summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-x.hgtags1
-rwxr-xr-xindra/llappearance/llavatarappearance.cpp66
-rwxr-xr-xindra/llappearance/llavatarappearance.h9
-rwxr-xr-xindra/llcharacter/llbvhloader.cpp130
-rwxr-xr-xindra/llcharacter/llbvhloader.h4
-rwxr-xr-xindra/llcharacter/lljoint.h11
-rwxr-xr-xindra/llcharacter/llkeyframemotion.cpp96
-rwxr-xr-xindra/llcharacter/llkeyframemotion.h1
-rwxr-xr-xindra/llcharacter/llmotion.cpp11
-rwxr-xr-xindra/llcharacter/llmotioncontroller.cpp17
-rwxr-xr-xindra/llcommon/CMakeLists.txt2
-rw-r--r--indra/llcommon/llcallbacklist.cpp230
-rw-r--r--[-rwxr-xr-x]indra/llcommon/llcallbacklist.h (renamed from indra/newview/llcallbacklist.h)21
-rwxr-xr-xindra/llcommon/llmemory.h7
-rw-r--r--indra/llcommon/llmutex.h4
-rwxr-xr-xindra/llcommon/llstl.h4
-rwxr-xr-xindra/llmath/llvolume.cpp43
-rwxr-xr-xindra/llmath/llvolume.h6
-rwxr-xr-xindra/llmath/m4math.cpp13
-rwxr-xr-xindra/llmath/m4math.h5
-rwxr-xr-xindra/llprimitive/CMakeLists.txt10
-rw-r--r--indra/llprimitive/lldaeloader.cpp2438
-rw-r--r--indra/llprimitive/lldaeloader.h108
-rwxr-xr-xindra/llprimitive/llmodel.cpp1314
-rwxr-xr-xindra/llprimitive/llmodel.h129
-rw-r--r--indra/llprimitive/llmodelloader.cpp623
-rw-r--r--indra/llprimitive/llmodelloader.h213
-rwxr-xr-xindra/llprimitive/lltextureentry.h4
-rwxr-xr-xindra/newview/CMakeLists.txt2
-rw-r--r--indra/newview/VIEWER_VERSION.txt2
-rwxr-xr-xindra/newview/app_settings/settings.xml55
-rwxr-xr-xindra/newview/app_settings/shaders/class1/avatar/objectSkinV.glsl16
-rwxr-xr-xindra/newview/character/avatar_lad.xml110
-rw-r--r--indra/newview/character/avatar_lad_orig.xml12505
-rw-r--r--indra/newview/character/avatar_lad_tentacles.xml12505
-rw-r--r--indra/newview/character/avatar_lad_wings_tail.xml12615
-rwxr-xr-xindra/newview/character/avatar_skeleton.xml28
-rw-r--r--indra/newview/character/avatar_skeleton_orig.xml81
-rw-r--r--indra/newview/character/avatar_skeleton_tentacles.xml281
-rw-r--r--indra/newview/character/avatar_skeleton_wings_tail.xml105
-rw-r--r--[-rwxr-xr-x]indra/newview/llcallbacklist.cpp0
-rwxr-xr-xindra/newview/llcommandhandler.cpp12
-rwxr-xr-xindra/newview/lldrawpoolavatar.cpp190
-rwxr-xr-xindra/newview/lldrawpoolavatar.h2
-rwxr-xr-xindra/newview/llfloaterbvhpreview.cpp3
-rwxr-xr-xindra/newview/llfloatermodelpreview.cpp3148
-rwxr-xr-xindra/newview/llfloatermodelpreview.h133
-rwxr-xr-xindra/newview/llmeshrepository.cpp375
-rwxr-xr-xindra/newview/llmeshrepository.h50
-rwxr-xr-xindra/newview/llpreviewanim.cpp8
-rwxr-xr-xindra/newview/llstartup.cpp2
-rwxr-xr-xindra/newview/llvoavatar.cpp17
-rwxr-xr-xindra/newview/llvovolume.cpp48
-rwxr-xr-xindra/newview/skins/default/xui/en/floater_model_preview.xml38
54 files changed, 43963 insertions, 3888 deletions
diff --git a/.hgtags b/.hgtags
index f05b8bd17a..0cc10b0100 100755
--- a/.hgtags
+++ b/.hgtags
@@ -507,3 +507,4 @@ d07f76c5b9860fb87924d00ca729f7d4532534d6 3.7.29-release
3f61ed662347dc7c6941b8266e72746a66d90e2a 3.8.1-release
3a62616f3dd8bd512fcdfd29ef033b2505b11213 3.8.2-release
60572f718879f786f6bc8b5c9373ebebf4693078 3.8.3-release
+27e3cf444c4cc645884960a61325a9ee0e9a2d0f 3.8.4-release
diff --git a/indra/llappearance/llavatarappearance.cpp b/indra/llappearance/llavatarappearance.cpp
index d1eb389013..f2cd2768d8 100755
--- a/indra/llappearance/llavatarappearance.cpp
+++ b/indra/llappearance/llavatarappearance.cpp
@@ -323,20 +323,33 @@ LLAvatarAppearance::~LLAvatarAppearance()
//static
void LLAvatarAppearance::initClass()
{
- std::string xmlFile;
+ initClass("","");
+}
- xmlFile = gDirUtilp->getExpandedFilename(LL_PATH_CHARACTER,AVATAR_DEFAULT_CHAR) + "_lad.xml";
- BOOL success = sXMLTree.parseFile( xmlFile, FALSE );
+//static
+void LLAvatarAppearance::initClass(const std::string& avatar_file_name_arg, const std::string& skeleton_file_name_arg)
+{
+ std::string avatar_file_name;
+
+ if (!avatar_file_name_arg.empty())
+ {
+ avatar_file_name = gDirUtilp->getExpandedFilename(LL_PATH_CHARACTER,avatar_file_name_arg);
+ }
+ else
+ {
+ avatar_file_name = gDirUtilp->getExpandedFilename(LL_PATH_CHARACTER,AVATAR_DEFAULT_CHAR + "_lad.xml");
+ }
+ BOOL success = sXMLTree.parseFile( avatar_file_name, FALSE );
if (!success)
{
- LL_ERRS() << "Problem reading avatar configuration file:" << xmlFile << LL_ENDL;
+ LL_ERRS() << "Problem reading avatar configuration file:" << avatar_file_name << LL_ENDL;
}
// now sanity check xml file
LLXmlTreeNode* root = sXMLTree.getRoot();
if (!root)
{
- LL_ERRS() << "No root node found in avatar configuration file: " << xmlFile << LL_ENDL;
+ LL_ERRS() << "No root node found in avatar configuration file: " << avatar_file_name << LL_ENDL;
return;
}
@@ -345,14 +358,14 @@ void LLAvatarAppearance::initClass()
//-------------------------------------------------------------------------
if( !root->hasName( "linden_avatar" ) )
{
- LL_ERRS() << "Invalid avatar file header: " << xmlFile << LL_ENDL;
+ LL_ERRS() << "Invalid avatar file header: " << avatar_file_name << LL_ENDL;
}
std::string version;
static LLStdStringHandle version_string = LLXmlTree::addAttributeString("version");
if( !root->getFastAttributeString( version_string, version ) || (version != "1.0") )
{
- LL_ERRS() << "Invalid avatar file version: " << version << " in file: " << xmlFile << LL_ENDL;
+ LL_ERRS() << "Invalid avatar file version: " << version << " in file: " << avatar_file_name << LL_ENDL;
}
S32 wearable_def_version = 1;
@@ -365,16 +378,19 @@ void LLAvatarAppearance::initClass()
LLXmlTreeNode* skeleton_node = root->getChildByName( "skeleton" );
if (!skeleton_node)
{
- LL_ERRS() << "No skeleton in avatar configuration file: " << xmlFile << LL_ENDL;
+ LL_ERRS() << "No skeleton in avatar configuration file: " << avatar_file_name << LL_ENDL;
return;
}
-
- std::string skeleton_file_name;
- static LLStdStringHandle file_name_string = LLXmlTree::addAttributeString("file_name");
- if (!skeleton_node->getFastAttributeString(file_name_string, skeleton_file_name))
- {
- LL_ERRS() << "No file name in skeleton node in avatar config file: " << xmlFile << LL_ENDL;
- }
+
+ std::string skeleton_file_name = skeleton_file_name_arg;
+ if (skeleton_file_name.empty())
+ {
+ static LLStdStringHandle file_name_string = LLXmlTree::addAttributeString("file_name");
+ if (!skeleton_node->getFastAttributeString(file_name_string, skeleton_file_name))
+ {
+ LL_ERRS() << "No file name in skeleton node in avatar config file: " << avatar_file_name << LL_ENDL;
+ }
+ }
std::string skeleton_path;
skeleton_path = gDirUtilp->getExpandedFilename(LL_PATH_CHARACTER,skeleton_file_name);
@@ -552,6 +568,12 @@ BOOL LLAvatarAppearance::setupBone(const LLAvatarBoneInfo* info, LLJoint* parent
{
LLJoint* joint = NULL;
+ LL_DEBUGS("BVH") << "bone info: name " << info->mName
+ << " isJoint " << info->mIsJoint
+ << " volume_num " << volume_num
+ << " joint_num " << joint_num
+ << LL_ENDL;
+
if (info->mIsJoint)
{
joint = getCharacterJoint(joint_num);
@@ -615,10 +637,7 @@ BOOL LLAvatarAppearance::allocateCharacterJoints( U32 num )
{
clearSkeleton();
- for(S32 joint_num = 0; joint_num < (S32)num; joint_num++)
- {
- mSkeleton.push_back(createAvatarJoint(joint_num));
- }
+ mSkeleton = avatar_joint_list_t(num,NULL);
return TRUE;
}
@@ -629,6 +648,7 @@ BOOL LLAvatarAppearance::allocateCharacterJoints( U32 num )
//-----------------------------------------------------------------------------
BOOL LLAvatarAppearance::buildSkeleton(const LLAvatarSkeletonInfo *info)
{
+ LL_DEBUGS("BVH") << "numBones " << info->mNumBones << " numCollisionVolumes " << info->mNumCollisionVolumes << LL_ENDL;
//-------------------------------------------------------------------------
// allocate joints
//-------------------------------------------------------------------------
@@ -655,8 +675,8 @@ BOOL LLAvatarAppearance::buildSkeleton(const LLAvatarSkeletonInfo *info)
LLAvatarSkeletonInfo::bone_info_list_t::const_iterator iter;
for (iter = info->mBoneInfoList.begin(); iter != info->mBoneInfoList.end(); ++iter)
{
- LLAvatarBoneInfo *info = *iter;
- if (!setupBone(info, NULL, current_volume_num, current_joint_num))
+ LLAvatarBoneInfo *bone_info = *iter;
+ if (!setupBone(bone_info, NULL, current_volume_num, current_joint_num))
{
LL_ERRS() << "Error parsing bone in skeleton file" << LL_ENDL;
return FALSE;
@@ -1240,6 +1260,10 @@ LLJoint *LLAvatarAppearance::getCharacterJoint( U32 num )
{
return NULL;
}
+ if (!mSkeleton[num])
+ {
+ mSkeleton[num] = createAvatarJoint(num);
+ }
return mSkeleton[num];
}
diff --git a/indra/llappearance/llavatarappearance.h b/indra/llappearance/llavatarappearance.h
index a0ef49b7cb..43a5274840 100755
--- a/indra/llappearance/llavatarappearance.h
+++ b/indra/llappearance/llavatarappearance.h
@@ -66,7 +66,8 @@ public:
LLAvatarAppearance(LLWearableData* wearable_data);
virtual ~LLAvatarAppearance();
- static void initClass(); // initializes static members
+ static void initClass(const std::string& avatar_file_name, const std::string& skeleton_file_name); // initializes static members
+ static void initClass();
static void cleanupClass(); // Cleanup data that's only init'd once per class.
virtual void initInstance(); // Called after construction to initialize the instance.
virtual BOOL loadSkeletonNode();
@@ -138,6 +139,9 @@ public:
void computeBodySize();
+public:
+ typedef std::vector<LLAvatarJoint*> avatar_joint_list_t;
+ const avatar_joint_list_t& getSkeleton() { return mSkeleton; }
protected:
static BOOL parseSkeletonFile(const std::string& filename);
@@ -147,10 +151,9 @@ protected:
BOOL setupBone(const LLAvatarBoneInfo* info, LLJoint* parent, S32 &current_volume_num, S32 &current_joint_num);
BOOL allocateCharacterJoints(U32 num);
BOOL buildSkeleton(const LLAvatarSkeletonInfo *info);
-protected:
+
void clearSkeleton();
BOOL mIsBuilt; // state of deferred character building
- typedef std::vector<LLAvatarJoint*> avatar_joint_list_t;
avatar_joint_list_t mSkeleton;
LLPosOverrideMap mPelvisFixups;
diff --git a/indra/llcharacter/llbvhloader.cpp b/indra/llcharacter/llbvhloader.cpp
index 0d558aeaa2..4dedeeab52 100755
--- a/indra/llcharacter/llbvhloader.cpp
+++ b/indra/llcharacter/llbvhloader.cpp
@@ -29,6 +29,7 @@
#include "llbvhloader.h"
#include <boost/tokenizer.hpp>
+#include <boost/lexical_cast.hpp>
#include "lldatapacker.h"
#include "lldir.h"
@@ -163,10 +164,10 @@ LLBVHLoader::LLBVHLoader(const char* buffer, ELoadStatus &loadStatus, S32 &error
errorLine = 0;
mStatus = loadTranslationTable("anim.ini");
loadStatus = mStatus;
- LL_INFOS()<<"Load Status 00 : "<< loadStatus << LL_ENDL;
+ LL_INFOS("BVH") << "Load Status 00 : " << loadStatus << LL_ENDL;
if (mStatus == E_ST_NO_XLT_FILE)
{
- //LL_WARNS() << "NOTE: No translation table found." << LL_ENDL;
+ LL_WARNS("BVH") << "NOTE: No translation table found." << LL_ENDL;
loadStatus = mStatus;
return;
}
@@ -174,7 +175,7 @@ LLBVHLoader::LLBVHLoader(const char* buffer, ELoadStatus &loadStatus, S32 &error
{
if (mStatus != E_ST_OK)
{
- //LL_WARNS() << "ERROR: [line: " << getLineNumber() << "] " << mStatus << LL_ENDL;
+ LL_WARNS("BVH") << "ERROR: [line: " << getLineNumber() << "] " << mStatus << LL_ENDL;
errorLine = getLineNumber();
loadStatus = mStatus;
return;
@@ -184,10 +185,14 @@ LLBVHLoader::LLBVHLoader(const char* buffer, ELoadStatus &loadStatus, S32 &error
char error_text[128]; /* Flawfinder: ignore */
S32 error_line;
mStatus = loadBVHFile(buffer, error_text, error_line);
+
+ LL_DEBUGS("BVH") << "============================================================" << LL_ENDL;
+ LL_DEBUGS("BVH") << "Raw data from file" << LL_ENDL;
+ dumpBVHInfo();
if (mStatus != E_ST_OK)
{
- //LL_WARNS() << "ERROR: [line: " << getLineNumber() << "] " << mStatus << LL_ENDL;
+ LL_WARNS("BVH") << "ERROR: [line: " << getLineNumber() << "] " << mStatus << LL_ENDL;
loadStatus = mStatus;
errorLine = getLineNumber();
return;
@@ -196,6 +201,10 @@ LLBVHLoader::LLBVHLoader(const char* buffer, ELoadStatus &loadStatus, S32 &error
applyTranslations();
optimize();
+ LL_DEBUGS("BVH") << "============================================================" << LL_ENDL;
+ LL_DEBUGS("BVH") << "After translations and optimize" << LL_ENDL;
+ dumpBVHInfo();
+
mInitialized = TRUE;
}
@@ -226,7 +235,7 @@ ELoadStatus LLBVHLoader::loadTranslationTable(const char *fileName)
if (!fp)
return E_ST_NO_XLT_FILE;
- LL_INFOS() << "NOTE: Loading translation table: " << fileName << LL_ENDL;
+ LL_INFOS("BVH") << "NOTE: Loading translation table: " << fileName << LL_ENDL;
//--------------------------------------------------------------------
// register file to be closed on function exit
@@ -666,6 +675,33 @@ ELoadStatus LLBVHLoader::loadTranslationTable(const char *fileName)
return E_ST_OK;
}
+void LLBVHLoader::dumpBVHInfo()
+{
+ for (U32 j=0; j<mJoints.size(); j++)
+ {
+ Joint *joint = mJoints[j];
+ LL_DEBUGS("BVH") << joint->mName << LL_ENDL;
+ for (S32 i=0; i<mNumFrames; i++)
+ {
+ Key &prevkey = joint->mKeys[llmax(i-1,0)];
+ Key &key = joint->mKeys[i];
+ if ((i==0) ||
+ (key.mPos[0] != prevkey.mPos[0]) ||
+ (key.mPos[1] != prevkey.mPos[1]) ||
+ (key.mPos[2] != prevkey.mPos[2]) ||
+ (key.mRot[0] != prevkey.mRot[0]) ||
+ (key.mRot[1] != prevkey.mRot[1]) ||
+ (key.mRot[2] != prevkey.mRot[2])
+ )
+ {
+ LL_DEBUGS("BVH") << "FRAME " << i
+ << " POS " << key.mPos[0] << "," << key.mPos[1] << "," << key.mPos[2]
+ << " ROT " << key.mRot[0] << "," << key.mRot[1] << "," << key.mRot[2] << LL_ENDL;
+ }
+ }
+ }
+
+}
//------------------------------------------------------------------------
// LLBVHLoader::loadBVHFile()
@@ -746,6 +782,7 @@ ELoadStatus LLBVHLoader::loadBVHFile(const char *buffer, char* error_text, S32 &
{
iter++; // {
iter++; // OFFSET
+ iter++; // }
S32 depth = 0;
for (S32 j = (S32)parent_joints.size() - 1; j >= 0; j--)
{
@@ -790,11 +827,14 @@ ELoadStatus LLBVHLoader::loadBVHFile(const char *buffer, char* error_text, S32 &
//----------------------------------------------------------------
mJoints.push_back( new Joint( jointName ) );
Joint *joint = mJoints.back();
+ LL_DEBUGS("BVH") << "Created joint " << jointName << LL_ENDL;
+ LL_DEBUGS("BVH") << "- index " << mJoints.size()-1 << LL_ENDL;
S32 depth = 1;
for (S32 j = (S32)parent_joints.size() - 1; j >= 0; j--)
{
Joint *pjoint = mJoints[parent_joints[j]];
+ LL_DEBUGS("BVH") << "- ancestor " << pjoint->mName << LL_ENDL;
if (depth > pjoint->mChildTreeMaxDepth)
{
pjoint->mChildTreeMaxDepth = depth;
@@ -863,6 +903,22 @@ ELoadStatus LLBVHLoader::loadBVHFile(const char *buffer, char* error_text, S32 &
return E_ST_NO_CHANNELS;
}
+ // FIXME BENTO do we want to open up motion of non-hip joints or
+ // not? Already effectively allowed via .anim upload.
+ int res = sscanf(line.c_str(), " CHANNELS %d", &joint->mNumChannels);
+ if ( res != 1 )
+ {
+ // Assume default if not otherwise specified.
+ if (mJoints.size()==1)
+ {
+ joint->mNumChannels = 6;
+ }
+ else
+ {
+ joint->mNumChannels = 3;
+ }
+ }
+
//----------------------------------------------------------------
// get rotation order
//----------------------------------------------------------------
@@ -961,57 +1017,41 @@ ELoadStatus LLBVHLoader::loadBVHFile(const char *buffer, char* error_text, S32 &
line = (*(iter++));
err_line++;
- // read and store values
- const char *p = line.c_str();
+ // Split line into a collection of floats.
+ std::deque<F32> floats;
+ boost::char_separator<char> whitespace_sep("\t ");
+ tokenizer float_tokens(line, whitespace_sep);
+ tokenizer::iterator float_token_iter = float_tokens.begin();
+ while (float_token_iter != float_tokens.end())
+ {
+ F32 val = boost::lexical_cast<float>(*float_token_iter);
+ floats.push_back(val);
+ float_token_iter++;
+ }
+ LL_DEBUGS("BVH") << "Got " << floats.size() << " floats " << LL_ENDL;
for (U32 j=0; j<mJoints.size(); j++)
{
Joint *joint = mJoints[j];
joint->mKeys.push_back( Key() );
Key &key = joint->mKeys.back();
- // get 3 pos values for root joint only
- if (j==0)
+ if (floats.size() < joint->mNumChannels)
{
- if ( sscanf(p, "%f %f %f", key.mPos, key.mPos+1, key.mPos+2) != 3 )
- {
- strncpy(error_text, line.c_str(), 127); /*Flawfinder: ignore*/
- return E_ST_NO_POS;
- }
+ strncpy(error_text, line.c_str(), 127); /*Flawfinder: ignore*/
+ return E_ST_NO_POS;
}
- // skip to next 3 values in the line
- p = find_next_whitespace(p);
- if (!p)
- {
- strncpy(error_text, line.c_str(), 127); /*Flawfinder: ignore*/
- return E_ST_NO_ROT;
- }
- p = find_next_whitespace(++p);
- if (!p)
+ // assume either numChannels == 6, in which case we have pos + rot,
+ // or numChannels == 3, in which case we have only rot.
+ if (joint->mNumChannels == 6)
{
- strncpy(error_text, line.c_str(), 127); /*Flawfinder: ignore*/
- return E_ST_NO_ROT;
+ key.mPos[0] = floats.front(); floats.pop_front();
+ key.mPos[1] = floats.front(); floats.pop_front();
+ key.mPos[2] = floats.front(); floats.pop_front();
}
- p = find_next_whitespace(++p);
- if (!p)
- {
- strncpy(error_text, line.c_str(), 127); /*Flawfinder: ignore*/
- return E_ST_NO_ROT;
- }
-
- // get 3 rot values for joint
- F32 rot[3];
- if ( sscanf(p, " %f %f %f", rot, rot+1, rot+2) != 3 )
- {
- strncpy(error_text, line.c_str(), 127); /*Flawfinder: ignore*/
- return E_ST_NO_ROT;
- }
-
- p++;
-
- key.mRot[ joint->mOrder[0]-'X' ] = rot[0];
- key.mRot[ joint->mOrder[1]-'X' ] = rot[1];
- key.mRot[ joint->mOrder[2]-'X' ] = rot[2];
+ key.mRot[ joint->mOrder[0]-'X' ] = floats.front(); floats.pop_front();
+ key.mRot[ joint->mOrder[1]-'X' ] = floats.front(); floats.pop_front();
+ key.mRot[ joint->mOrder[2]-'X' ] = floats.front(); floats.pop_front();
}
}
diff --git a/indra/llcharacter/llbvhloader.h b/indra/llcharacter/llbvhloader.h
index f816b76277..033d8714a9 100755
--- a/indra/llcharacter/llbvhloader.h
+++ b/indra/llcharacter/llbvhloader.h
@@ -102,6 +102,7 @@ struct Joint
mNumRotKeys = 0;
mChildTreeMaxDepth = 0;
mPriority = 0;
+ mNumChannels = 3;
}
// Include aligned members first
@@ -123,6 +124,7 @@ struct Joint
S32 mNumRotKeys;
S32 mChildTreeMaxDepth;
S32 mPriority;
+ S32 mNumChannels;
};
@@ -272,6 +274,8 @@ public:
// Returns status code.
ELoadStatus loadBVHFile(const char *buffer, char *error_text, S32 &error_line);
+ void dumpBVHInfo();
+
// Applies translations to BVH data loaded.
void applyTranslations();
diff --git a/indra/llcharacter/lljoint.h b/indra/llcharacter/lljoint.h
index 2abe1d6db1..b3bf588d79 100755
--- a/indra/llcharacter/lljoint.h
+++ b/indra/llcharacter/lljoint.h
@@ -40,9 +40,14 @@
#include "xform.h"
const S32 LL_CHARACTER_MAX_JOINTS_PER_MESH = 15;
-const U32 LL_CHARACTER_MAX_JOINTS = 32; // must be divisible by 4!
-const U32 LL_HAND_JOINT_NUM = 31;
-const U32 LL_FACE_JOINT_NUM = 30;
+// BENTO JOINT COUNT LIMIT
+const U32 LL_CHARACTER_MAX_JOINTS = 152; // must be divisible by 4!
+const U32 LL_MAX_JOINTS_PER_MESH_OBJECT = 152;
+
+// FIXME BENTO - these should be higher than the joint_num of any
+// other joint, to avoid conflicts in updateMotionsByType()
+const U32 LL_HAND_JOINT_NUM = (LL_CHARACTER_MAX_JOINTS-1);
+const U32 LL_FACE_JOINT_NUM = (LL_CHARACTER_MAX_JOINTS-2);
const S32 LL_CHARACTER_MAX_PRIORITY = 7;
const F32 LL_MAX_PELVIS_OFFSET = 5.f;
diff --git a/indra/llcharacter/llkeyframemotion.cpp b/indra/llcharacter/llkeyframemotion.cpp
index cd201a65b4..c227c3f8e9 100755
--- a/indra/llcharacter/llkeyframemotion.cpp
+++ b/indra/llcharacter/llkeyframemotion.cpp
@@ -1868,6 +1868,8 @@ BOOL LLKeyframeMotion::serialize(LLDataPacker& dp) const
{
BOOL success = TRUE;
+ LL_DEBUGS("BVH") << "serializing" << LL_ENDL;
+
success &= dp.packU16(KEYFRAME_MOTION_VERSION, "version");
success &= dp.packU16(KEYFRAME_MOTION_SUBVERSION, "sub_version");
success &= dp.packS32(mJointMotionList->mBasePriority, "base_priority");
@@ -1881,6 +1883,19 @@ BOOL LLKeyframeMotion::serialize(LLDataPacker& dp) const
success &= dp.packU32(mJointMotionList->mHandPose, "hand_pose");
success &= dp.packU32(mJointMotionList->getNumJointMotions(), "num_joints");
+ LL_DEBUGS("BVH") << "version " << KEYFRAME_MOTION_VERSION << LL_ENDL;
+ LL_DEBUGS("BVH") << "sub_version " << KEYFRAME_MOTION_SUBVERSION << LL_ENDL;
+ LL_DEBUGS("BVH") << "base_priority " << mJointMotionList->mBasePriority << LL_ENDL;
+ LL_DEBUGS("BVH") << "duration " << mJointMotionList->mDuration << LL_ENDL;
+ LL_DEBUGS("BVH") << "emote_name " << mJointMotionList->mEmoteName << LL_ENDL;
+ LL_DEBUGS("BVH") << "loop_in_point " << mJointMotionList->mLoopInPoint << LL_ENDL;
+ LL_DEBUGS("BVH") << "loop_out_point " << mJointMotionList->mLoopOutPoint << LL_ENDL;
+ LL_DEBUGS("BVH") << "loop " << mJointMotionList->mLoop << LL_ENDL;
+ LL_DEBUGS("BVH") << "ease_in_duration " << mJointMotionList->mEaseInDuration << LL_ENDL;
+ LL_DEBUGS("BVH") << "ease_out_duration " << mJointMotionList->mEaseOutDuration << LL_ENDL;
+ LL_DEBUGS("BVH") << "hand_pose " << mJointMotionList->mHandPose << LL_ENDL;
+ LL_DEBUGS("BVH") << "num_joints " << mJointMotionList->getNumJointMotions() << LL_ENDL;
+
for (U32 i = 0; i < mJointMotionList->getNumJointMotions(); i++)
{
JointMotion* joint_motionp = mJointMotionList->getJointMotion(i);
@@ -1888,6 +1903,7 @@ BOOL LLKeyframeMotion::serialize(LLDataPacker& dp) const
success &= dp.packS32(joint_motionp->mPriority, "joint_priority");
success &= dp.packS32(joint_motionp->mRotationCurve.mNumKeys, "num_rot_keys");
+ LL_DEBUGS("BVH") << "Joint " << joint_motionp->mJointName << LL_ENDL;
for (RotationCurve::key_map_t::iterator iter = joint_motionp->mRotationCurve.mKeys.begin();
iter != joint_motionp->mRotationCurve.mKeys.end(); ++iter)
{
@@ -1905,6 +1921,8 @@ BOOL LLKeyframeMotion::serialize(LLDataPacker& dp) const
success &= dp.packU16(x, "rot_angle_x");
success &= dp.packU16(y, "rot_angle_y");
success &= dp.packU16(z, "rot_angle_z");
+
+ LL_DEBUGS("BVH") << " rot: t " << rot_key.mTime << " angles " << rot_angles.mV[VX] <<","<< rot_angles.mV[VY] <<","<< rot_angles.mV[VZ] << LL_ENDL;
}
success &= dp.packS32(joint_motionp->mPositionCurve.mNumKeys, "num_pos_keys");
@@ -1923,37 +1941,54 @@ BOOL LLKeyframeMotion::serialize(LLDataPacker& dp) const
success &= dp.packU16(x, "pos_x");
success &= dp.packU16(y, "pos_y");
success &= dp.packU16(z, "pos_z");
+
+ LL_DEBUGS("BVH") << " pos: t " << pos_key.mTime << " pos " << pos_key.mPosition.mV[VX] <<","<< pos_key.mPosition.mV[VY] <<","<< pos_key.mPosition.mV[VZ] << LL_ENDL;
}
}
success &= dp.packS32(mJointMotionList->mConstraints.size(), "num_constraints");
+ LL_DEBUGS("BVH") << "num_constraints " << mJointMotionList->mConstraints.size() << LL_ENDL;
for (JointMotionList::constraint_list_t::const_iterator iter = mJointMotionList->mConstraints.begin();
iter != mJointMotionList->mConstraints.end(); ++iter)
{
JointConstraintSharedData* shared_constraintp = *iter;
success &= dp.packU8(shared_constraintp->mChainLength, "chain_length");
success &= dp.packU8(shared_constraintp->mConstraintType, "constraint_type");
- char volume_name[16]; /* Flawfinder: ignore */
- snprintf(volume_name, sizeof(volume_name), "%s", /* Flawfinder: ignore */
+ char source_volume[16]; /* Flawfinder: ignore */
+ snprintf(source_volume, sizeof(source_volume), "%s", /* Flawfinder: ignore */
mCharacter->findCollisionVolume(shared_constraintp->mSourceConstraintVolume)->getName().c_str());
- success &= dp.packBinaryDataFixed((U8*)volume_name, 16, "source_volume");
+
+ success &= dp.packBinaryDataFixed((U8*)source_volume, 16, "source_volume");
success &= dp.packVector3(shared_constraintp->mSourceConstraintOffset, "source_offset");
+ char target_volume[16]; /* Flawfinder: ignore */
if (shared_constraintp->mConstraintTargetType == CONSTRAINT_TARGET_TYPE_GROUND)
{
- snprintf(volume_name,sizeof(volume_name), "%s", "GROUND"); /* Flawfinder: ignore */
+ snprintf(target_volume,sizeof(target_volume), "%s", "GROUND"); /* Flawfinder: ignore */
}
else
{
- snprintf(volume_name, sizeof(volume_name),"%s", /* Flawfinder: ignore */
+ snprintf(target_volume, sizeof(target_volume),"%s", /* Flawfinder: ignore */
mCharacter->findCollisionVolume(shared_constraintp->mTargetConstraintVolume)->getName().c_str());
}
- success &= dp.packBinaryDataFixed((U8*)volume_name, 16, "target_volume");
+ success &= dp.packBinaryDataFixed((U8*)target_volume, 16, "target_volume");
success &= dp.packVector3(shared_constraintp->mTargetConstraintOffset, "target_offset");
success &= dp.packVector3(shared_constraintp->mTargetConstraintDir, "target_dir");
success &= dp.packF32(shared_constraintp->mEaseInStartTime, "ease_in_start");
success &= dp.packF32(shared_constraintp->mEaseInStopTime, "ease_in_stop");
success &= dp.packF32(shared_constraintp->mEaseOutStartTime, "ease_out_start");
success &= dp.packF32(shared_constraintp->mEaseOutStopTime, "ease_out_stop");
+
+ LL_DEBUGS("BVH") << " chain_length " << shared_constraintp->mChainLength << LL_ENDL;
+ LL_DEBUGS("BVH") << " constraint_type " << (S32)shared_constraintp->mConstraintType << LL_ENDL;
+ LL_DEBUGS("BVH") << " source_volume " << source_volume << LL_ENDL;
+ LL_DEBUGS("BVH") << " source_offset " << shared_constraintp->mSourceConstraintOffset << LL_ENDL;
+ LL_DEBUGS("BVH") << " target_volume " << target_volume << LL_ENDL;
+ LL_DEBUGS("BVH") << " target_offset " << shared_constraintp->mTargetConstraintOffset << LL_ENDL;
+ LL_DEBUGS("BVH") << " target_dir " << shared_constraintp->mTargetConstraintDir << LL_ENDL;
+ LL_DEBUGS("BVH") << " ease_in_start " << shared_constraintp->mEaseInStartTime << LL_ENDL;
+ LL_DEBUGS("BVH") << " ease_in_stop " << shared_constraintp->mEaseInStopTime << LL_ENDL;
+ LL_DEBUGS("BVH") << " ease_out_start " << shared_constraintp->mEaseOutStartTime << LL_ENDL;
+ LL_DEBUGS("BVH") << " ease_out_stop " << shared_constraintp->mEaseOutStopTime << LL_ENDL;
}
return success;
@@ -1972,6 +2007,52 @@ U32 LLKeyframeMotion::getFileSize()
}
//-----------------------------------------------------------------------------
+// FIXME BENTO TEMP
+// dumpToFile()
+//-----------------------------------------------------------------------------
+void LLKeyframeMotion::dumpToFile(const std::string& name)
+{
+ if (isLoaded())
+ {
+ std::string outfile_base;
+ if (!name.empty())
+ {
+ outfile_base = name;
+ }
+ else if (!getName().empty())
+ {
+ outfile_base = getName();
+ }
+ else
+ {
+ const LLUUID& id = getID();
+ outfile_base = id.asString();
+ }
+ std::string outfilename = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,outfile_base + ".anim");
+ if (LLFile::isfile(outfilename))
+ {
+ return;
+ }
+
+ S32 file_size = getFileSize();
+ U8* buffer = new U8[file_size];
+
+ LL_DEBUGS("BVH") << "Dumping " << outfilename << LL_ENDL;
+ LLDataPackerBinaryBuffer dp(buffer, file_size);
+ if (serialize(dp))
+ {
+ LLAPRFile outfile;
+ outfile.open(outfilename, LL_APR_WPB);
+ if (outfile.getFileHandle())
+ {
+ outfile.write(buffer, file_size);
+ }
+ }
+ delete [] buffer;
+ }
+}
+
+//-----------------------------------------------------------------------------
// getPelvisBBox()
//-----------------------------------------------------------------------------
const LLBBoxLocal &LLKeyframeMotion::getPelvisBBox()
@@ -2171,6 +2252,9 @@ void LLKeyframeMotion::onLoadComplete(LLVFS *vfs,
if (motionp->deserialize(dp))
{
motionp->mAssetStatus = ASSET_LOADED;
+ // FIXME BENTO TEMP
+ //motionp->dumpToFile("");
+
}
else
{
diff --git a/indra/llcharacter/llkeyframemotion.h b/indra/llcharacter/llkeyframemotion.h
index b1422b2b90..f1fa56d731 100755
--- a/indra/llcharacter/llkeyframemotion.h
+++ b/indra/llcharacter/llkeyframemotion.h
@@ -153,6 +153,7 @@ public:
BOOL serialize(LLDataPacker& dp) const;
BOOL deserialize(LLDataPacker& dp);
BOOL isLoaded() { return mJointMotionList != NULL; }
+ void dumpToFile(const std::string& name);
// setters for modifying a keyframe animation
diff --git a/indra/llcharacter/llmotion.cpp b/indra/llcharacter/llmotion.cpp
index 4803f855de..2d646b4ed2 100755
--- a/indra/llcharacter/llmotion.cpp
+++ b/indra/llcharacter/llmotion.cpp
@@ -111,9 +111,14 @@ void LLMotion::addJointState(const LLPointer<LLJointState>& jointState)
U32 usage = jointState->getUsage();
// for now, usage is everything
- mJointSignature[0][jointState->getJoint()->getJointNum()] = (usage & LLJointState::POS) ? (0xff >> (7 - priority)) : 0;
- mJointSignature[1][jointState->getJoint()->getJointNum()] = (usage & LLJointState::ROT) ? (0xff >> (7 - priority)) : 0;
- mJointSignature[2][jointState->getJoint()->getJointNum()] = (usage & LLJointState::SCALE) ? (0xff >> (7 - priority)) : 0;
+ S32 joint_num = jointState->getJoint()->getJointNum();
+ if ((joint_num >= (S32)LL_CHARACTER_MAX_JOINTS) || (joint_num < 0))
+ {
+ LL_WARNS() << "joint_num " << joint_num << " is outside of legal range [0-" << LL_CHARACTER_MAX_JOINTS << ")" << LL_ENDL;
+ }
+ mJointSignature[0][joint_num] = (usage & LLJointState::POS) ? (0xff >> (7 - priority)) : 0;
+ mJointSignature[1][joint_num] = (usage & LLJointState::ROT) ? (0xff >> (7 - priority)) : 0;
+ mJointSignature[2][joint_num] = (usage & LLJointState::SCALE) ? (0xff >> (7 - priority)) : 0;
}
void LLMotion::setDeactivateCallback( void (*cb)(void *), void* userdata )
diff --git a/indra/llcharacter/llmotioncontroller.cpp b/indra/llcharacter/llmotioncontroller.cpp
index e02b139608..a3532f9f9c 100755
--- a/indra/llcharacter/llmotioncontroller.cpp
+++ b/indra/llcharacter/llmotioncontroller.cpp
@@ -377,6 +377,14 @@ LLMotion* LLMotionController::createMotion( const LLUUID &id )
case LLMotion::STATUS_SUCCESS:
// add motion to our list
mLoadedMotions.insert(motion);
+ // BENTO TEMP
+ {
+ LLKeyframeMotion *km = dynamic_cast<LLKeyframeMotion*>(motion);
+ if (km)
+ {
+ //km->dumpToFile("");
+ }
+ }
break;
default:
LL_ERRS() << "Invalid initialization status" << LL_ENDL;
@@ -577,6 +585,7 @@ void LLMotionController::updateMotionsByType(LLMotion::LLMotionBlendType anim_ty
else
{
// NUM_JOINT_SIGNATURE_STRIDES should be multiple of 4
+ // FIXME BENTO - think it's just the number of joints that needs to be a multiple of 4, not the number of strides.
for (S32 i = 0; i < NUM_JOINT_SIGNATURE_STRIDES; i++)
{
U32 *current_signature = (U32*)&(mJointSignature[0][i * 4]);
@@ -780,6 +789,14 @@ void LLMotionController::updateLoadingMotions()
mLoadingMotions.erase(curiter);
// add motion to our loaded motion list
mLoadedMotions.insert(motionp);
+ // FIXME SO MUCH DUMP
+ {
+ LLKeyframeMotion *km = dynamic_cast<LLKeyframeMotion*>(motionp);
+ if (km)
+ {
+ km->dumpToFile("");
+ }
+ }
// this motion should be playing
if (!motionp->isStopped())
{
diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt
index 1459b9ada2..5863310162 100755
--- a/indra/llcommon/CMakeLists.txt
+++ b/indra/llcommon/CMakeLists.txt
@@ -37,6 +37,7 @@ set(llcommon_SOURCE_FILES
llbase32.cpp
llbase64.cpp
llbitpack.cpp
+ llcallbacklist.cpp
llcommon.cpp
llcommonutils.cpp
llcoros.cpp
@@ -129,6 +130,7 @@ set(llcommon_HEADER_FILES
llbase64.h
llbitpack.h
llboost.h
+ llcallbacklist.h
llcommon.h
llcommonutils.h
llcoros.h
diff --git a/indra/llcommon/llcallbacklist.cpp b/indra/llcommon/llcallbacklist.cpp
new file mode 100644
index 0000000000..541ff75ee4
--- /dev/null
+++ b/indra/llcommon/llcallbacklist.cpp
@@ -0,0 +1,230 @@
+/**
+ * @file llcallbacklist.cpp
+ * @brief A simple list of callback functions to call.
+ *
+ * $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$
+ */
+
+#include "llcallbacklist.h"
+#include "lleventtimer.h"
+#include "llerrorlegacy.h"
+
+// Globals
+//
+LLCallbackList gIdleCallbacks;
+
+//
+// Member functions
+//
+
+LLCallbackList::LLCallbackList()
+{
+ // nothing
+}
+
+LLCallbackList::~LLCallbackList()
+{
+}
+
+
+void LLCallbackList::addFunction( callback_t func, void *data)
+{
+ if (!func)
+ {
+ return;
+ }
+
+ // only add one callback per func/data pair
+ //
+ if (containsFunction(func))
+ {
+ return;
+ }
+
+ callback_pair_t t(func, data);
+ mCallbackList.push_back(t);
+}
+
+bool LLCallbackList::containsFunction( callback_t func, void *data)
+{
+ callback_pair_t t(func, data);
+ callback_list_t::iterator iter = find(func,data);
+ if (iter != mCallbackList.end())
+ {
+ return TRUE;
+ }
+ else
+ {
+ return FALSE;
+ }
+}
+
+
+bool LLCallbackList::deleteFunction( callback_t func, void *data)
+{
+ callback_list_t::iterator iter = find(func,data);
+ if (iter != mCallbackList.end())
+ {
+ mCallbackList.erase(iter);
+ return TRUE;
+ }
+ else
+ {
+ return FALSE;
+ }
+}
+
+inline
+LLCallbackList::callback_list_t::iterator
+LLCallbackList::find(callback_t func, void *data)
+{
+ callback_pair_t t(func, data);
+ return std::find(mCallbackList.begin(), mCallbackList.end(), t);
+}
+
+void LLCallbackList::deleteAllFunctions()
+{
+ mCallbackList.clear();
+}
+
+
+void LLCallbackList::callFunctions()
+{
+ for (callback_list_t::iterator iter = mCallbackList.begin(); iter != mCallbackList.end(); )
+ {
+ callback_list_t::iterator curiter = iter++;
+ curiter->first(curiter->second);
+ }
+}
+
+// Shim class to allow arbitrary boost::bind
+// expressions to be run as one-time idle callbacks.
+class OnIdleCallbackOneTime
+{
+public:
+ OnIdleCallbackOneTime(nullary_func_t callable):
+ mCallable(callable)
+ {
+ }
+ static void onIdle(void *data)
+ {
+ gIdleCallbacks.deleteFunction(onIdle, data);
+ OnIdleCallbackOneTime* self = reinterpret_cast<OnIdleCallbackOneTime*>(data);
+ self->call();
+ delete self;
+ }
+ void call()
+ {
+ mCallable();
+ }
+private:
+ nullary_func_t mCallable;
+};
+
+void doOnIdleOneTime(nullary_func_t callable)
+{
+ OnIdleCallbackOneTime* cb_functor = new OnIdleCallbackOneTime(callable);
+ gIdleCallbacks.addFunction(&OnIdleCallbackOneTime::onIdle,cb_functor);
+}
+
+// Shim class to allow generic boost functions to be run as
+// recurring idle callbacks. Callable should return true when done,
+// false to continue getting called.
+class OnIdleCallbackRepeating
+{
+public:
+ OnIdleCallbackRepeating(bool_func_t callable):
+ mCallable(callable)
+ {
+ }
+ // Will keep getting called until the callable returns true.
+ static void onIdle(void *data)
+ {
+ OnIdleCallbackRepeating* self = reinterpret_cast<OnIdleCallbackRepeating*>(data);
+ bool done = self->call();
+ if (done)
+ {
+ gIdleCallbacks.deleteFunction(onIdle, data);
+ delete self;
+ }
+ }
+ bool call()
+ {
+ return mCallable();
+ }
+private:
+ bool_func_t mCallable;
+};
+
+void doOnIdleRepeating(bool_func_t callable)
+{
+ OnIdleCallbackRepeating* cb_functor = new OnIdleCallbackRepeating(callable);
+ gIdleCallbacks.addFunction(&OnIdleCallbackRepeating::onIdle,cb_functor);
+}
+
+class NullaryFuncEventTimer: public LLEventTimer
+{
+public:
+ NullaryFuncEventTimer(nullary_func_t callable, F32 seconds):
+ LLEventTimer(seconds),
+ mCallable(callable)
+ {
+ }
+
+private:
+ BOOL tick()
+ {
+ mCallable();
+ return TRUE;
+ }
+
+ nullary_func_t mCallable;
+};
+
+// Call a given callable once after specified interval.
+void doAfterInterval(nullary_func_t callable, F32 seconds)
+{
+ new NullaryFuncEventTimer(callable, seconds);
+}
+
+class BoolFuncEventTimer: public LLEventTimer
+{
+public:
+ BoolFuncEventTimer(bool_func_t callable, F32 seconds):
+ LLEventTimer(seconds),
+ mCallable(callable)
+ {
+ }
+private:
+ BOOL tick()
+ {
+ return mCallable();
+ }
+
+ bool_func_t mCallable;
+};
+
+// Call a given callable every specified number of seconds, until it returns true.
+void doPeriodically(bool_func_t callable, F32 seconds)
+{
+ new BoolFuncEventTimer(callable, seconds);
+}
diff --git a/indra/newview/llcallbacklist.h b/indra/llcommon/llcallbacklist.h
index 0516c9cdb4..89716cd74c 100755..100644
--- a/indra/newview/llcallbacklist.h
+++ b/indra/llcommon/llcallbacklist.h
@@ -28,27 +28,34 @@
#define LL_LLCALLBACKLIST_H
#include "llstl.h"
+#include <boost/function.hpp>
+#include <list>
class LLCallbackList
{
public:
typedef void (*callback_t)(void*);
+
+ typedef std::pair< callback_t,void* > callback_pair_t;
+ // NOTE: It is confirmed that we DEPEND on the order provided by using a list :(
+ //
+ typedef std::list< callback_pair_t > callback_list_t;
LLCallbackList();
~LLCallbackList();
- void addFunction( callback_t func, void *data = NULL ); // register a callback, which will be called as func(data)
- BOOL containsFunction( callback_t func, void *data = NULL ); // true if list already contains the function/data pair
- BOOL deleteFunction( callback_t func, void *data = NULL ); // removes the first instance of this function/data pair from the list, false if not found
- void callFunctions(); // calls all functions
+ void addFunction( callback_t func, void *data = NULL ); // register a callback, which will be called as func(data)
+ bool containsFunction( callback_t func, void *data = NULL ); // true if list already contains the function/data pair
+ bool deleteFunction( callback_t func, void *data = NULL ); // removes the first instance of this function/data pair from the list, false if not found
+ void callFunctions(); // calls all functions
void deleteAllFunctions();
static void test();
protected:
- // Use a list so that the callbacks are ordered in case that matters
- typedef std::pair<callback_t,void*> callback_pair_t;
- typedef std::list<callback_pair_t > callback_list_t;
+
+ inline callback_list_t::iterator find(callback_t func, void *data);
+
callback_list_t mCallbackList;
};
diff --git a/indra/llcommon/llmemory.h b/indra/llcommon/llmemory.h
index c4c9cc0566..d3a9bbc4ae 100755
--- a/indra/llcommon/llmemory.h
+++ b/indra/llcommon/llmemory.h
@@ -28,6 +28,7 @@
#include "linden_common.h"
#include "llunits.h"
+#include "stdtypes.h"
#if !LL_WINDOWS
#include <stdint.h>
#endif
@@ -59,7 +60,7 @@ class LLMutex ;
LL_COMMON_API void ll_assert_aligned_func(uintptr_t ptr,U32 alignment);
#ifdef SHOW_ASSERT
-#define ll_assert_aligned(ptr,alignment) ll_assert_aligned_func(reinterpret_cast<uintptr_t>(ptr),((U32)alignment))
+#define ll_assert_aligned(ptr,alignment) ll_assert_aligned_func(uintptr_t(ptr),((U32)alignment))
#else
#define ll_assert_aligned(ptr,alignment)
#endif
@@ -69,13 +70,13 @@ LL_COMMON_API void ll_assert_aligned_func(uintptr_t ptr,U32 alignment);
template <typename T> T* LL_NEXT_ALIGNED_ADDRESS(T* address)
{
return reinterpret_cast<T*>(
- (reinterpret_cast<uintptr_t>(address) + 0xF) & ~0xF);
+ (uintptr_t(address) + 0xF) & ~0xF);
}
template <typename T> T* LL_NEXT_ALIGNED_ADDRESS_64(T* address)
{
return reinterpret_cast<T*>(
- (reinterpret_cast<uintptr_t>(address) + 0x3F) & ~0x3F);
+ (uintptr_t(address) + 0x3F) & ~0x3F);
}
#if LL_LINUX || LL_DARWIN
diff --git a/indra/llcommon/llmutex.h b/indra/llcommon/llmutex.h
index 3659a319a2..ea535cee86 100644
--- a/indra/llcommon/llmutex.h
+++ b/indra/llcommon/llmutex.h
@@ -33,6 +33,10 @@
#define MUTEX_DEBUG (LL_DEBUG || LL_RELEASE_WITH_DEBUG_INFO)
+#if MUTEX_DEBUG
+#include <map>
+#endif
+
struct apr_thread_mutex_t;
struct apr_pool_t;
struct apr_thread_cond_t;
diff --git a/indra/llcommon/llstl.h b/indra/llcommon/llstl.h
index 02f10fa2ba..0435cb8a08 100755
--- a/indra/llcommon/llstl.h
+++ b/indra/llcommon/llstl.h
@@ -27,6 +27,7 @@
#ifndef LL_LLSTL_H
#define LL_LLSTL_H
+#include "stdtypes.h"
#include <functional>
#include <algorithm>
#include <map>
@@ -272,6 +273,7 @@ inline T get_if_there(const std::map<K,T>& inmap, const K& key, T default_value)
}
};
+// Useful for replacing the removeObj() functionality of LLDynamicArray
// Example:
// for (std::vector<T>::iterator iter = mList.begin(); iter != mList.end(); )
// {
@@ -530,7 +532,7 @@ bool before(const std::type_info* lhs, const std::type_info* rhs)
return strcmp(lhs->name(), rhs->name()) < 0;
#else // not Linux, or gcc 4.4+
// Just use before(), as we normally would
- return lhs->before(*rhs);
+ return lhs->before(*rhs) ? true : false;
#endif
}
diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp
index c2198b91a7..ae714c5bce 100755
--- a/indra/llmath/llvolume.cpp
+++ b/indra/llmath/llvolume.cpp
@@ -2536,6 +2536,8 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size)
U32 cur_influence = 0;
LLVector4 wght(0,0,0,0);
+ U32 joints[4] = {0,0,0,0};
+ LLVector4 joints_with_weights(0,0,0,0);
while (joint != END_INFLUENCES && idx < weights.size())
{
@@ -2543,7 +2545,9 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size)
influence |= ((U16) weights[idx++] << 8);
F32 w = llclamp((F32) influence / 65535.f, 0.f, 0.99999f);
- wght.mV[cur_influence++] = (F32) joint + w;
+ wght.mV[cur_influence] = w;
+ joints[cur_influence] = joint;
+ cur_influence++;
if (cur_influence >= 4)
{
@@ -2554,8 +2558,16 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size)
joint = weights[idx++];
}
}
-
- face.mWeights[cur_vertex].loadua(wght.mV);
+ F32 wsum = wght.mV[VX] + wght.mV[VY] + wght.mV[VZ] + wght.mV[VW];
+ if (wsum <= 0.f)
+ {
+ wght = LLVector4(0.99999f,0.f,0.f,0.f);
+ }
+ for (U32 k=0; k<4; k++)
+ {
+ joints_with_weights[k] = (F32) joints[k] + wght[k];
+ }
+ face.mWeights[cur_vertex].loadua(joints_with_weights.mV);
cur_vertex++;
}
@@ -6072,7 +6084,7 @@ void LLVolumeFace::pushVertex(const LLVector4a& pos, const LLVector4a& norm, con
if (new_verts > mNumAllocatedVertices)
{
- //double buffer size on expansion
+ // double buffer size on expansion
new_verts *= 2;
S32 new_tc_size = ((new_verts*8)+0xF) & ~0xF;
@@ -6088,18 +6100,21 @@ void LLVolumeFace::pushVertex(const LLVector4a& pos, const LLVector4a& norm, con
mNormals = mPositions+new_verts;
mTexCoords = (LLVector2*) (mNormals+new_verts);
- //positions
- LLVector4a::memcpyNonAliased16((F32*) mPositions, (F32*) old_buf, old_vsize);
-
- //normals
- LLVector4a::memcpyNonAliased16((F32*) mNormals, (F32*) (old_buf+mNumVertices), old_vsize);
+ if (old_buf != NULL)
+ {
+ // copy old positions into new buffer
+ LLVector4a::memcpyNonAliased16((F32*)mPositions, (F32*)old_buf, old_vsize);
- //tex coords
- LLVector4a::memcpyNonAliased16((F32*) mTexCoords, (F32*) (old_buf+mNumVertices*2), old_tc_size);
+ // normals
+ LLVector4a::memcpyNonAliased16((F32*)mNormals, (F32*)(old_buf + mNumVertices), old_vsize);
- //just clear tangents
- ll_aligned_free_16(mTangents);
- mTangents = NULL;
+ // tex coords
+ LLVector4a::memcpyNonAliased16((F32*)mTexCoords, (F32*)(old_buf + mNumVertices * 2), old_tc_size);
+ }
+
+ // just clear tangents
+ ll_aligned_free_16(mTangents);
+ mTangents = NULL;
ll_aligned_free<64>(old_buf);
mNumAllocatedVertices = new_verts;
diff --git a/indra/llmath/llvolume.h b/indra/llmath/llvolume.h
index c8476f6897..625f7cff02 100755
--- a/indra/llmath/llvolume.h
+++ b/indra/llmath/llvolume.h
@@ -968,6 +968,7 @@ protected:
~LLVolume(); // use unref
public:
+ typedef std::vector<LLVolumeFace> face_list_t;
struct FaceParams
{
@@ -1041,6 +1042,10 @@ public:
// conversion if *(LLVolume*) to LLVolume&
const LLVolumeFace &getVolumeFace(const S32 f) const {return mVolumeFaces[f];} // DO NOT DELETE VOLUME WHILE USING THIS REFERENCE, OR HOLD A POINTER TO THIS VOLUMEFACE
+ LLVolumeFace &getVolumeFace(const S32 f) {return mVolumeFaces[f];} // DO NOT DELETE VOLUME WHILE USING THIS REFERENCE, OR HOLD A POINTER TO THIS VOLUMEFACE
+
+ face_list_t& getVolumeFaces() { return mVolumeFaces; }
+
U32 mFaceMask; // bit array of which faces exist in this volume
LLVector3 mLODScaleBias; // vector for biasing LOD based on scale
@@ -1080,7 +1085,6 @@ public:
BOOL mGenerateSingleFace;
- typedef std::vector<LLVolumeFace> face_list_t;
face_list_t mVolumeFaces;
public:
diff --git a/indra/llmath/m4math.cpp b/indra/llmath/m4math.cpp
index 6a1b4143cf..d89c482804 100755
--- a/indra/llmath/m4math.cpp
+++ b/indra/llmath/m4math.cpp
@@ -274,6 +274,19 @@ const LLMatrix4& LLMatrix4::invert(void)
return *this;
}
+// Convenience func for simplifying comparison-heavy code by
+// intentionally stomping values in [-FLT_EPS,FLT_EPS] to 0.0f
+//
+void LLMatrix4::condition(void)
+{
+ U32 i;
+ U32 j;
+ for (i = 0; i < 3;i++)
+ for (j = 0; j < 3;j++)
+ mMatrix[i][j] = ((mMatrix[i][j] > -FLT_EPSILON)
+ && (mMatrix[i][j] < FLT_EPSILON)) ? 0.0f : mMatrix[i][j];
+}
+
LLVector4 LLMatrix4::getFwdRow4() const
{
return LLVector4(mMatrix[VX][VX], mMatrix[VX][VY], mMatrix[VX][VZ], mMatrix[VX][VW]);
diff --git a/indra/llmath/m4math.h b/indra/llmath/m4math.h
index a7dce10397..a77c5bc76d 100755
--- a/indra/llmath/m4math.h
+++ b/indra/llmath/m4math.h
@@ -180,6 +180,11 @@ public:
const LLMatrix4& setTranslation(const LLVector4 &translation);
const LLMatrix4& setTranslation(const LLVector3 &translation);
+ // Convenience func for simplifying comparison-heavy code by
+ // intentionally stomping values [-FLT_EPS,FLT_EPS] to 0.0
+ //
+ void condition(void);
+
///////////////////////////
//
// Get properties of a matrix
diff --git a/indra/llprimitive/CMakeLists.txt b/indra/llprimitive/CMakeLists.txt
index d1475cf734..75ce624a58 100755
--- a/indra/llprimitive/CMakeLists.txt
+++ b/indra/llprimitive/CMakeLists.txt
@@ -8,6 +8,7 @@ include(LLMath)
include(LLMessage)
include(LLXML)
include(LLPhysicsExtensions)
+include(LLCharacter)
include_directories(
${LLCOMMON_INCLUDE_DIRS}
@@ -16,6 +17,7 @@ include_directories(
${LLXML_INCLUDE_DIRS}
${LIBS_PREBUILT_DIR}/include/collada
${LIBS_PREBUILT_DIR}/include/collada/1.4
+ ${LLCHARACTER_INCLUDE_DIRS}
)
include_directories(SYSTEM
${LLCOMMON_SYSTEM_INCLUDE_DIRS}
@@ -24,11 +26,13 @@ include_directories(SYSTEM
)
set(llprimitive_SOURCE_FILES
+ lldaeloader.cpp
llmaterialid.cpp
llmaterial.cpp
llmaterialtable.cpp
llmediaentry.cpp
llmodel.cpp
+ llmodelloader.cpp
llprimitive.cpp
llprimtexturelist.cpp
lltextureanim.cpp
@@ -40,16 +44,17 @@ set(llprimitive_SOURCE_FILES
set(llprimitive_HEADER_FILES
CMakeLists.txt
-
+ lldaeloader.h
legacy_object_types.h
- lllslconstants.h
llmaterial.h
llmaterialid.h
llmaterialtable.h
llmediaentry.h
llmodel.h
+ llmodelloader.h
llprimitive.h
llprimtexturelist.h
+ lllslconstants.h
lltextureanim.h
lltextureentry.h
lltreeparams.h
@@ -72,6 +77,7 @@ target_link_libraries(llprimitive
${LLMESSAGE_LIBRARIES}
${LLXML_LIBRARIES}
${LLPHYSICSEXTENSIONS_LIBRARIES}
+ ${LLCHARACTER_LIBRARIES}
)
diff --git a/indra/llprimitive/lldaeloader.cpp b/indra/llprimitive/lldaeloader.cpp
new file mode 100644
index 0000000000..6ff9613c80
--- /dev/null
+++ b/indra/llprimitive/lldaeloader.cpp
@@ -0,0 +1,2438 @@
+/**
+ * @file lldaeloader.cpp
+ * @brief LLDAELoader class implementation
+ *
+ * $LicenseInfo:firstyear=2013&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2013, 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$
+ */
+
+#if LL_MSVC
+#pragma warning (disable : 4263)
+#pragma warning (disable : 4264)
+#endif
+#include "dae.h"
+#include "dom/domAsset.h"
+#include "dom/domBind_material.h"
+#include "dom/domCOLLADA.h"
+#include "dom/domConstants.h"
+#include "dom/domController.h"
+#include "dom/domEffect.h"
+#include "dom/domGeometry.h"
+#include "dom/domInstance_geometry.h"
+#include "dom/domInstance_material.h"
+#include "dom/domInstance_node.h"
+#include "dom/domInstance_effect.h"
+#include "dom/domMaterial.h"
+#include "dom/domMatrix.h"
+#include "dom/domNode.h"
+#include "dom/domProfile_COMMON.h"
+#include "dom/domRotate.h"
+#include "dom/domScale.h"
+#include "dom/domTranslate.h"
+#include "dom/domVisual_scene.h"
+#if LL_MSVC
+#pragma warning (default : 4263)
+#pragma warning (default : 4264)
+#endif
+
+#include <boost/lexical_cast.hpp>
+
+#include "lldaeloader.h"
+#include "llsdserialize.h"
+#include "lljoint.h"
+
+#include "glh/glh_linear.h"
+#include "llmatrix4a.h"
+
+std::string colladaVersion[VERSIONTYPE_COUNT+1] =
+{
+ "1.4.0",
+ "1.4.1",
+ "Unsupported"
+};
+
+static const std::string lod_suffix[LLModel::NUM_LODS] =
+{
+ "_LOD0",
+ "_LOD1",
+ "_LOD2",
+ "",
+ "_PHYS",
+};
+
+const U32 LIMIT_MATERIALS_OUTPUT = 12;
+
+bool get_dom_sources(const domInputLocalOffset_Array& inputs, S32& pos_offset, S32& tc_offset, S32& norm_offset, S32 &idx_stride,
+ domSource* &pos_source, domSource* &tc_source, domSource* &norm_source)
+{
+ idx_stride = 0;
+
+ for (U32 j = 0; j < inputs.getCount(); ++j)
+ {
+ idx_stride = llmax((S32) inputs[j]->getOffset(), idx_stride);
+
+ if (strcmp(COMMON_PROFILE_INPUT_VERTEX, inputs[j]->getSemantic()) == 0)
+ { //found vertex array
+ const domURIFragmentType& uri = inputs[j]->getSource();
+ daeElementRef elem = uri.getElement();
+ domVertices* vertices = (domVertices*) elem.cast();
+ if ( !vertices )
+ {
+ return false;
+ }
+
+ domInputLocal_Array& v_inp = vertices->getInput_array();
+
+
+ for (U32 k = 0; k < v_inp.getCount(); ++k)
+ {
+ if (strcmp(COMMON_PROFILE_INPUT_POSITION, v_inp[k]->getSemantic()) == 0)
+ {
+ pos_offset = inputs[j]->getOffset();
+
+ const domURIFragmentType& uri = v_inp[k]->getSource();
+ daeElementRef elem = uri.getElement();
+ pos_source = (domSource*) elem.cast();
+ }
+
+ if (strcmp(COMMON_PROFILE_INPUT_NORMAL, v_inp[k]->getSemantic()) == 0)
+ {
+ norm_offset = inputs[j]->getOffset();
+
+ const domURIFragmentType& uri = v_inp[k]->getSource();
+ daeElementRef elem = uri.getElement();
+ norm_source = (domSource*) elem.cast();
+ }
+ }
+ }
+
+ if (strcmp(COMMON_PROFILE_INPUT_NORMAL, inputs[j]->getSemantic()) == 0)
+ {
+ //found normal array for this triangle list
+ norm_offset = inputs[j]->getOffset();
+ const domURIFragmentType& uri = inputs[j]->getSource();
+ daeElementRef elem = uri.getElement();
+ norm_source = (domSource*) elem.cast();
+ }
+ else if (strcmp(COMMON_PROFILE_INPUT_TEXCOORD, inputs[j]->getSemantic()) == 0)
+ { //found texCoords
+ tc_offset = inputs[j]->getOffset();
+ const domURIFragmentType& uri = inputs[j]->getSource();
+ daeElementRef elem = uri.getElement();
+ tc_source = (domSource*) elem.cast();
+ }
+ }
+
+ idx_stride += 1;
+
+ return true;
+}
+
+LLModel::EModelStatus load_face_from_dom_triangles(std::vector<LLVolumeFace>& face_list, std::vector<std::string>& materials, domTrianglesRef& tri)
+{
+ LLVolumeFace face;
+ std::vector<LLVolumeFace::VertexData> verts;
+ std::vector<U16> indices;
+
+ const domInputLocalOffset_Array& inputs = tri->getInput_array();
+
+ S32 pos_offset = -1;
+ S32 tc_offset = -1;
+ S32 norm_offset = -1;
+
+ domSource* pos_source = NULL;
+ domSource* tc_source = NULL;
+ domSource* norm_source = NULL;
+
+ S32 idx_stride = 0;
+
+ if ( !get_dom_sources(inputs, pos_offset, tc_offset, norm_offset, idx_stride, pos_source, tc_source, norm_source))
+ {
+ return LLModel::BAD_ELEMENT;
+ }
+
+ if (!pos_source || !pos_source->getFloat_array())
+ {
+ LL_WARNS() << "Unable to process mesh without position data; invalid model; invalid model." << LL_ENDL;
+ return LLModel::BAD_ELEMENT;
+ }
+
+ domPRef p = tri->getP();
+ domListOfUInts& idx = p->getValue();
+
+ domListOfFloats dummy ;
+ domListOfFloats& v = pos_source ? pos_source->getFloat_array()->getValue() : dummy ;
+ domListOfFloats& tc = tc_source ? tc_source->getFloat_array()->getValue() : dummy ;
+ domListOfFloats& n = norm_source ? norm_source->getFloat_array()->getValue() : dummy ;
+
+ if (pos_source)
+ {
+ if(v.getCount() == 0)
+ {
+ return LLModel::BAD_ELEMENT;
+ }
+
+ face.mExtents[0].set(v[0], v[1], v[2]);
+ face.mExtents[1].set(v[0], v[1], v[2]);
+ }
+
+ LLVolumeFace::VertexMapData::PointMap point_map;
+
+ for (U32 i = 0; i < idx.getCount(); i += idx_stride)
+ {
+ LLVolumeFace::VertexData cv;
+ if (pos_source)
+ {
+ cv.setPosition(LLVector4a(v[idx[i+pos_offset]*3+0],
+ v[idx[i+pos_offset]*3+1],
+ v[idx[i+pos_offset]*3+2]));
+ }
+
+ if (tc_source)
+ {
+ cv.mTexCoord.setVec(tc[idx[i+tc_offset]*2+0],
+ tc[idx[i+tc_offset]*2+1]);
+ }
+
+ if (norm_source)
+ {
+ cv.setNormal(LLVector4a(n[idx[i+norm_offset]*3+0],
+ n[idx[i+norm_offset]*3+1],
+ n[idx[i+norm_offset]*3+2]));
+ }
+
+ BOOL found = FALSE;
+
+ LLVolumeFace::VertexMapData::PointMap::iterator point_iter;
+ point_iter = point_map.find(LLVector3(cv.getPosition().getF32ptr()));
+
+ if (point_iter != point_map.end())
+ {
+ for (U32 j = 0; j < point_iter->second.size(); ++j)
+ {
+ // We have a matching loc
+ //
+ if ((point_iter->second)[j] == cv)
+ {
+ U16 shared_index = (point_iter->second)[j].mIndex;
+
+ // Don't share verts within the same tri, degenerate
+ //
+ if ((indices.size() % 3) && (indices[indices.size()-1] != shared_index))
+ {
+ found = true;
+ indices.push_back(shared_index);
+ }
+ break;
+ }
+ }
+ }
+
+ if (!found)
+ {
+ update_min_max(face.mExtents[0], face.mExtents[1], cv.getPosition());
+ verts.push_back(cv);
+ if (verts.size() >= 65535)
+ {
+ //llerrs << "Attempted to write model exceeding 16-bit index buffer limitation." << LL_ENDL;
+ return LLModel::VERTEX_NUMBER_OVERFLOW ;
+ }
+ U16 index = (U16) (verts.size()-1);
+ indices.push_back(index);
+
+ LLVolumeFace::VertexMapData d;
+ d.setPosition(cv.getPosition());
+ d.mTexCoord = cv.mTexCoord;
+ d.setNormal(cv.getNormal());
+ d.mIndex = index;
+ if (point_iter != point_map.end())
+ {
+ point_iter->second.push_back(d);
+ }
+ else
+ {
+ point_map[LLVector3(d.getPosition().getF32ptr())].push_back(d);
+ }
+ }
+
+ if (indices.size()%3 == 0 && verts.size() >= 65532)
+ {
+ std::string material;
+
+ if (tri->getMaterial())
+ {
+ material = std::string(tri->getMaterial());
+ }
+
+ materials.push_back(material);
+ face_list.push_back(face);
+ face_list.rbegin()->fillFromLegacyData(verts, indices);
+ LLVolumeFace& new_face = *face_list.rbegin();
+ if (!norm_source)
+ {
+ //ll_aligned_free_16(new_face.mNormals);
+ new_face.mNormals = NULL;
+ }
+
+ if (!tc_source)
+ {
+ //ll_aligned_free_16(new_face.mTexCoords);
+ new_face.mTexCoords = NULL;
+ }
+
+ face = LLVolumeFace();
+ point_map.clear();
+ }
+ }
+
+ if (!verts.empty())
+ {
+ std::string material;
+
+ if (tri->getMaterial())
+ {
+ material = std::string(tri->getMaterial());
+ }
+
+ materials.push_back(material);
+ face_list.push_back(face);
+
+ face_list.rbegin()->fillFromLegacyData(verts, indices);
+ LLVolumeFace& new_face = *face_list.rbegin();
+ if (!norm_source)
+ {
+ //ll_aligned_free_16(new_face.mNormals);
+ new_face.mNormals = NULL;
+ }
+
+ if (!tc_source)
+ {
+ //ll_aligned_free_16(new_face.mTexCoords);
+ new_face.mTexCoords = NULL;
+ }
+ }
+
+ return LLModel::NO_ERRORS ;
+}
+
+LLModel::EModelStatus load_face_from_dom_polylist(std::vector<LLVolumeFace>& face_list, std::vector<std::string>& materials, domPolylistRef& poly)
+{
+ domPRef p = poly->getP();
+ domListOfUInts& idx = p->getValue();
+
+ if (idx.getCount() == 0)
+ {
+ return LLModel::NO_ERRORS ;
+ }
+
+ const domInputLocalOffset_Array& inputs = poly->getInput_array();
+
+
+ domListOfUInts& vcount = poly->getVcount()->getValue();
+
+ S32 pos_offset = -1;
+ S32 tc_offset = -1;
+ S32 norm_offset = -1;
+
+ domSource* pos_source = NULL;
+ domSource* tc_source = NULL;
+ domSource* norm_source = NULL;
+
+ S32 idx_stride = 0;
+
+ if (!get_dom_sources(inputs, pos_offset, tc_offset, norm_offset, idx_stride, pos_source, tc_source, norm_source))
+ {
+ return LLModel::BAD_ELEMENT;
+ }
+
+ LLVolumeFace face;
+
+ std::vector<U16> indices;
+ std::vector<LLVolumeFace::VertexData> verts;
+
+ domListOfFloats v;
+ domListOfFloats tc;
+ domListOfFloats n;
+
+ if (pos_source)
+ {
+ v = pos_source->getFloat_array()->getValue();
+ face.mExtents[0].set(v[0], v[1], v[2]);
+ face.mExtents[1].set(v[0], v[1], v[2]);
+ }
+
+ if (tc_source)
+ {
+ tc = tc_source->getFloat_array()->getValue();
+ }
+
+ if (norm_source)
+ {
+ n = norm_source->getFloat_array()->getValue();
+ }
+
+ LLVolumeFace::VertexMapData::PointMap point_map;
+
+ U32 cur_idx = 0;
+ for (U32 i = 0; i < vcount.getCount(); ++i)
+ { //for each polygon
+ U32 first_index = 0;
+ U32 last_index = 0;
+ for (U32 j = 0; j < vcount[i]; ++j)
+ { //for each vertex
+
+ LLVolumeFace::VertexData cv;
+
+ if (pos_source)
+ {
+ cv.getPosition().set(v[idx[cur_idx+pos_offset]*3+0],
+ v[idx[cur_idx+pos_offset]*3+1],
+ v[idx[cur_idx+pos_offset]*3+2]);
+ if (!cv.getPosition().isFinite3())
+ {
+ LL_WARNS() << "Found NaN while loading position data from DAE-Model, invalid model." << LL_ENDL;
+ return LLModel::BAD_ELEMENT;
+ }
+ }
+
+ if (tc_source)
+ {
+ cv.mTexCoord.setVec(tc[idx[cur_idx+tc_offset]*2+0],
+ tc[idx[cur_idx+tc_offset]*2+1]);
+ }
+
+ if (norm_source)
+ {
+ cv.getNormal().set(n[idx[cur_idx+norm_offset]*3+0],
+ n[idx[cur_idx+norm_offset]*3+1],
+ n[idx[cur_idx+norm_offset]*3+2]);
+
+ if (!cv.getNormal().isFinite3())
+ {
+ LL_WARNS() << "Found NaN while loading normals from DAE-Model, invalid model." << LL_ENDL;
+ return LLModel::BAD_ELEMENT;
+ }
+ }
+
+ cur_idx += idx_stride;
+
+ BOOL found = FALSE;
+
+ LLVolumeFace::VertexMapData::PointMap::iterator point_iter;
+ LLVector3 pos3(cv.getPosition().getF32ptr());
+ point_iter = point_map.find(pos3);
+
+ if (point_iter != point_map.end())
+ {
+ for (U32 k = 0; k < point_iter->second.size(); ++k)
+ {
+ if ((point_iter->second)[k] == cv)
+ {
+ found = TRUE;
+ U32 index = (point_iter->second)[k].mIndex;
+ if (j == 0)
+ {
+ first_index = index;
+ }
+ else if (j == 1)
+ {
+ last_index = index;
+ }
+ else
+ {
+ // if these are the same, we have a very, very skinny triangle (coincident verts on one or more edges)
+ //
+ llassert((first_index != last_index) && (last_index != index) && (first_index != index));
+ indices.push_back(first_index);
+ indices.push_back(last_index);
+ indices.push_back(index);
+ last_index = index;
+ }
+
+ break;
+ }
+ }
+ }
+
+ if (!found)
+ {
+ update_min_max(face.mExtents[0], face.mExtents[1], cv.getPosition());
+ verts.push_back(cv);
+ if (verts.size() >= 65535)
+ {
+ //llerrs << "Attempted to write model exceeding 16-bit index buffer limitation." << LL_ENDL;
+ return LLModel::VERTEX_NUMBER_OVERFLOW ;
+ }
+ U16 index = (U16) (verts.size()-1);
+
+ if (j == 0)
+ {
+ first_index = index;
+ }
+ else if (j == 1)
+ {
+ last_index = index;
+ }
+ else
+ {
+ // detect very skinny degenerate triangles with collapsed edges
+ //
+ llassert((first_index != last_index) && (last_index != index) && (first_index != index));
+ indices.push_back(first_index);
+ indices.push_back(last_index);
+ indices.push_back(index);
+ last_index = index;
+ }
+
+ LLVolumeFace::VertexMapData d;
+ d.setPosition(cv.getPosition());
+ d.mTexCoord = cv.mTexCoord;
+ d.setNormal(cv.getNormal());
+ d.mIndex = index;
+ if (point_iter != point_map.end())
+ {
+ point_iter->second.push_back(d);
+ }
+ else
+ {
+ point_map[pos3].push_back(d);
+ }
+ }
+
+ if (indices.size()%3 == 0 && indices.size() >= 65532)
+ {
+ std::string material;
+
+ if (poly->getMaterial())
+ {
+ material = std::string(poly->getMaterial());
+ }
+
+ materials.push_back(material);
+ face_list.push_back(face);
+ face_list.rbegin()->fillFromLegacyData(verts, indices);
+ LLVolumeFace& new_face = *face_list.rbegin();
+ if (!norm_source)
+ {
+ //ll_aligned_free_16(new_face.mNormals);
+ new_face.mNormals = NULL;
+ }
+
+ if (!tc_source)
+ {
+ //ll_aligned_free_16(new_face.mTexCoords);
+ new_face.mTexCoords = NULL;
+ }
+
+ face = LLVolumeFace();
+ verts.clear();
+ indices.clear();
+ point_map.clear();
+ }
+ }
+ }
+
+ if (!verts.empty())
+ {
+ std::string material;
+
+ if (poly->getMaterial())
+ {
+ material = std::string(poly->getMaterial());
+ }
+
+ materials.push_back(material);
+ face_list.push_back(face);
+ face_list.rbegin()->fillFromLegacyData(verts, indices);
+
+ LLVolumeFace& new_face = *face_list.rbegin();
+ if (!norm_source)
+ {
+ //ll_aligned_free_16(new_face.mNormals);
+ new_face.mNormals = NULL;
+ }
+
+ if (!tc_source)
+ {
+ //ll_aligned_free_16(new_face.mTexCoords);
+ new_face.mTexCoords = NULL;
+ }
+ }
+
+ return LLModel::NO_ERRORS ;
+}
+
+LLModel::EModelStatus load_face_from_dom_polygons(std::vector<LLVolumeFace>& face_list, std::vector<std::string>& materials, domPolygonsRef& poly)
+{
+ LLVolumeFace face;
+ std::vector<U16> indices;
+ std::vector<LLVolumeFace::VertexData> verts;
+
+ const domInputLocalOffset_Array& inputs = poly->getInput_array();
+
+ S32 v_offset = -1;
+ S32 n_offset = -1;
+ S32 t_offset = -1;
+
+ domListOfFloats* v = NULL;
+ domListOfFloats* n = NULL;
+ domListOfFloats* t = NULL;
+
+ U32 stride = 0;
+ for (U32 i = 0; i < inputs.getCount(); ++i)
+ {
+ stride = llmax((U32) inputs[i]->getOffset()+1, stride);
+
+ if (strcmp(COMMON_PROFILE_INPUT_VERTEX, inputs[i]->getSemantic()) == 0)
+ { //found vertex array
+ v_offset = inputs[i]->getOffset();
+
+ const domURIFragmentType& uri = inputs[i]->getSource();
+ daeElementRef elem = uri.getElement();
+ domVertices* vertices = (domVertices*) elem.cast();
+ if (!vertices)
+ {
+ return LLModel::BAD_ELEMENT;
+ }
+ domInputLocal_Array& v_inp = vertices->getInput_array();
+
+ for (U32 k = 0; k < v_inp.getCount(); ++k)
+ {
+ if (strcmp(COMMON_PROFILE_INPUT_POSITION, v_inp[k]->getSemantic()) == 0)
+ {
+ const domURIFragmentType& uri = v_inp[k]->getSource();
+ daeElementRef elem = uri.getElement();
+ domSource* src = (domSource*) elem.cast();
+ if (!src)
+ {
+ return LLModel::BAD_ELEMENT;
+ }
+ v = &(src->getFloat_array()->getValue());
+ }
+ }
+ }
+ else if (strcmp(COMMON_PROFILE_INPUT_NORMAL, inputs[i]->getSemantic()) == 0)
+ {
+ n_offset = inputs[i]->getOffset();
+ //found normal array for this triangle list
+ const domURIFragmentType& uri = inputs[i]->getSource();
+ daeElementRef elem = uri.getElement();
+ domSource* src = (domSource*) elem.cast();
+ if (!src)
+ {
+ return LLModel::BAD_ELEMENT;
+ }
+ n = &(src->getFloat_array()->getValue());
+ }
+ else if (strcmp(COMMON_PROFILE_INPUT_TEXCOORD, inputs[i]->getSemantic()) == 0 && inputs[i]->getSet() == 0)
+ { //found texCoords
+ t_offset = inputs[i]->getOffset();
+ const domURIFragmentType& uri = inputs[i]->getSource();
+ daeElementRef elem = uri.getElement();
+ domSource* src = (domSource*) elem.cast();
+ if (!src)
+ {
+ return LLModel::BAD_ELEMENT;
+ }
+ t = &(src->getFloat_array()->getValue());
+ }
+ }
+
+ domP_Array& ps = poly->getP_array();
+
+ //make a triangle list in <verts>
+ for (U32 i = 0; i < ps.getCount(); ++i)
+ { //for each polygon
+ domListOfUInts& idx = ps[i]->getValue();
+ for (U32 j = 0; j < idx.getCount()/stride; ++j)
+ { //for each vertex
+ if (j > 2)
+ {
+ U32 size = verts.size();
+ LLVolumeFace::VertexData v0 = verts[size-3];
+ LLVolumeFace::VertexData v1 = verts[size-1];
+
+ verts.push_back(v0);
+ verts.push_back(v1);
+ }
+
+ LLVolumeFace::VertexData vert;
+
+
+ if (v)
+ {
+ U32 v_idx = idx[j*stride+v_offset]*3;
+ v_idx = llclamp(v_idx, (U32) 0, (U32) v->getCount());
+ vert.getPosition().set(v->get(v_idx),
+ v->get(v_idx+1),
+ v->get(v_idx+2));
+ }
+
+ //bounds check n and t lookups because some FBX to DAE converters
+ //use negative indices and empty arrays to indicate data does not exist
+ //for a particular channel
+ if (n && n->getCount() > 0)
+ {
+ U32 n_idx = idx[j*stride+n_offset]*3;
+ n_idx = llclamp(n_idx, (U32) 0, (U32) n->getCount());
+ vert.getNormal().set(n->get(n_idx),
+ n->get(n_idx+1),
+ n->get(n_idx+2));
+ }
+ else
+ {
+ vert.getNormal().clear();
+ }
+
+
+ if (t && t->getCount() > 0)
+ {
+ U32 t_idx = idx[j*stride+t_offset]*2;
+ t_idx = llclamp(t_idx, (U32) 0, (U32) t->getCount());
+ vert.mTexCoord.setVec(t->get(t_idx),
+ t->get(t_idx+1));
+ }
+ else
+ {
+ vert.mTexCoord.clear();
+ }
+
+
+ verts.push_back(vert);
+ }
+ }
+
+ if (verts.empty())
+ {
+ return LLModel::NO_ERRORS;
+ }
+
+ face.mExtents[0] = verts[0].getPosition();
+ face.mExtents[1] = verts[0].getPosition();
+
+ //create a map of unique vertices to indices
+ std::map<LLVolumeFace::VertexData, U32> vert_idx;
+
+ U32 cur_idx = 0;
+ for (U32 i = 0; i < verts.size(); ++i)
+ {
+ std::map<LLVolumeFace::VertexData, U32>::iterator iter = vert_idx.find(verts[i]);
+ if (iter == vert_idx.end())
+ {
+ vert_idx[verts[i]] = cur_idx++;
+ }
+ }
+
+ //build vertex array from map
+ std::vector<LLVolumeFace::VertexData> new_verts;
+ new_verts.resize(vert_idx.size());
+
+ for (std::map<LLVolumeFace::VertexData, U32>::iterator iter = vert_idx.begin(); iter != vert_idx.end(); ++iter)
+ {
+ new_verts[iter->second] = iter->first;
+ update_min_max(face.mExtents[0], face.mExtents[1], iter->first.getPosition());
+ }
+
+ //build index array from map
+ indices.resize(verts.size());
+
+ for (U32 i = 0; i < verts.size(); ++i)
+ {
+ indices[i] = vert_idx[verts[i]];
+ llassert(!i || (indices[i-1] != indices[i]));
+ }
+
+ // DEBUG just build an expanded triangle list
+ /*for (U32 i = 0; i < verts.size(); ++i)
+ {
+ indices.push_back((U16) i);
+ update_min_max(face.mExtents[0], face.mExtents[1], verts[i].getPosition());
+ }*/
+
+ if (!new_verts.empty())
+ {
+ std::string material;
+
+ if (poly->getMaterial())
+ {
+ material = std::string(poly->getMaterial());
+ }
+
+ materials.push_back(material);
+ face_list.push_back(face);
+ face_list.rbegin()->fillFromLegacyData(new_verts, indices);
+
+ LLVolumeFace& new_face = *face_list.rbegin();
+ if (!n)
+ {
+ //ll_aligned_free_16(new_face.mNormals);
+ new_face.mNormals = NULL;
+ }
+
+ if (!t)
+ {
+ //ll_aligned_free_16(new_face.mTexCoords);
+ new_face.mTexCoords = NULL;
+ }
+ }
+
+ return LLModel::NO_ERRORS ;
+}
+
+//-----------------------------------------------------------------------------
+// LLDAELoader
+//-----------------------------------------------------------------------------
+LLDAELoader::LLDAELoader(
+ std::string filename,
+ S32 lod,
+ load_callback_t load_cb,
+ joint_lookup_func_t joint_lookup_func,
+ texture_load_func_t texture_load_func,
+ state_callback_t state_cb,
+ void* opaque_userdata,
+ JointTransformMap& jointTransformMap,
+ JointNameSet& jointsFromNodes,
+ JointNameSet& legalJointNames,
+ U32 modelLimit)
+: LLModelLoader(
+ filename,
+ lod,
+ load_cb,
+ joint_lookup_func,
+ texture_load_func,
+ state_cb,
+ opaque_userdata,
+ jointTransformMap,
+ jointsFromNodes,
+ legalJointNames),
+mGeneratedModelLimit(modelLimit)
+{
+}
+
+LLDAELoader::~LLDAELoader()
+{
+}
+
+struct ModelSort
+{
+ bool operator()(const LLPointer< LLModel >& lhs, const LLPointer< LLModel >& rhs)
+ {
+ if (lhs->mSubmodelID < rhs->mSubmodelID)
+ {
+ return true;
+ }
+ return LLStringUtil::compareInsensitive(lhs->mLabel, rhs->mLabel) < 0;
+ }
+};
+
+bool LLDAELoader::OpenFile(const std::string& filename)
+{
+ //no suitable slm exists, load from the .dae file
+ DAE dae;
+ domCOLLADA* dom = dae.open(filename);
+
+ if (!dom)
+ {
+ LL_INFOS() <<" Error with dae - traditionally indicates a corrupt file."<<LL_ENDL;
+ setLoadState( ERROR_PARSING );
+ return false;
+ }
+ //Dom version
+ daeString domVersion = dae.getDomVersion();
+ std::string sldom(domVersion);
+ LL_INFOS()<<"Collada Importer Version: "<<sldom<<LL_ENDL;
+ //Dae version
+ domVersionType docVersion = dom->getVersion();
+ //0=1.4
+ //1=1.4.1
+ //2=Currently unsupported, however may work
+ if (docVersion > 1 )
+ {
+ docVersion = VERSIONTYPE_COUNT;
+ }
+ LL_INFOS()<<"Dae version "<<colladaVersion[docVersion]<<LL_ENDL;
+
+
+ daeDatabase* db = dae.getDatabase();
+
+ daeInt count = db->getElementCount(NULL, COLLADA_TYPE_MESH);
+
+ daeDocument* doc = dae.getDoc(mFilename);
+ if (!doc)
+ {
+ LL_WARNS() << "can't find internal doc" << LL_ENDL;
+ return false;
+ }
+
+ daeElement* root = doc->getDomRoot();
+ if (!root)
+ {
+ LL_WARNS() << "document has no root" << LL_ENDL;
+ return false;
+ }
+
+ //Verify some basic properties of the dae
+ //1. Basic validity check on controller
+ U32 controllerCount = (int) db->getElementCount( NULL, "controller" );
+ bool result = false;
+ for ( int i=0; i<controllerCount; ++i )
+ {
+ domController* pController = NULL;
+ db->getElement( (daeElement**) &pController, i , NULL, "controller" );
+ result = verifyController( pController );
+ if (!result)
+ {
+ LL_INFOS() << "Could not verify controller" << LL_ENDL;
+ setLoadState( ERROR_PARSING );
+ return true;
+ }
+ }
+
+
+ //get unit scale
+ mTransform.setIdentity();
+
+ domAsset::domUnit* unit = daeSafeCast<domAsset::domUnit>(root->getDescendant(daeElement::matchType(domAsset::domUnit::ID())));
+
+ if (unit)
+ {
+ F32 meter = unit->getMeter();
+ mTransform.mMatrix[0][0] = meter;
+ mTransform.mMatrix[1][1] = meter;
+ mTransform.mMatrix[2][2] = meter;
+ }
+
+ //get up axis rotation
+ LLMatrix4 rotation;
+
+ domUpAxisType up = UPAXISTYPE_Y_UP; // default is Y_UP
+ domAsset::domUp_axis* up_axis =
+ daeSafeCast<domAsset::domUp_axis>(root->getDescendant(daeElement::matchType(domAsset::domUp_axis::ID())));
+
+ if (up_axis)
+ {
+ up = up_axis->getValue();
+ }
+
+ if (up == UPAXISTYPE_X_UP)
+ {
+ rotation.initRotation(0.0f, 90.0f * DEG_TO_RAD, 0.0f);
+ }
+ else if (up == UPAXISTYPE_Y_UP)
+ {
+ rotation.initRotation(90.0f * DEG_TO_RAD, 0.0f, 0.0f);
+ }
+
+ rotation *= mTransform;
+ mTransform = rotation;
+
+ mTransform.condition();
+
+ U32 submodel_limit = count > 0 ? mGeneratedModelLimit/count : 0;
+ for (daeInt idx = 0; idx < count; ++idx)
+ { //build map of domEntities to LLModel
+ domMesh* mesh = NULL;
+ db->getElement((daeElement**) &mesh, idx, NULL, COLLADA_TYPE_MESH);
+
+ if (mesh)
+ {
+
+ std::vector<LLModel*> models;
+
+ loadModelsFromDomMesh(mesh, models, submodel_limit);
+
+ std::vector<LLModel*>::iterator i;
+ i = models.begin();
+ while (i != models.end())
+ {
+ LLModel* mdl = *i;
+ if(mdl->getStatus() != LLModel::NO_ERRORS)
+ {
+ setLoadState(ERROR_MODEL + mdl->getStatus()) ;
+ return false; //abort
+ }
+
+ if (mdl && validate_model(mdl))
+ {
+ mModelList.push_back(mdl);
+ mModelsMap[mesh].push_back(mdl);
+ }
+ i++;
+ }
+ }
+ }
+
+ std::sort(mModelList.begin(), mModelList.end(), ModelSort());
+
+ model_list::iterator model_iter = mModelList.begin();
+ while (model_iter != mModelList.end())
+ {
+ LLModel* mdl = *model_iter;
+ U32 material_count = mdl->mMaterialList.size();
+ LL_INFOS() << "Importing " << mdl->mLabel << " model with " << material_count << " material references" << LL_ENDL;
+ std::vector<std::string>::iterator mat_iter = mdl->mMaterialList.begin();
+ std::vector<std::string>::iterator end_iter = material_count > LIMIT_MATERIALS_OUTPUT
+ ? mat_iter + LIMIT_MATERIALS_OUTPUT
+ : mdl->mMaterialList.end();
+ while (mat_iter != end_iter)
+ {
+ LL_INFOS() << mdl->mLabel << " references " << (*mat_iter) << LL_ENDL;
+ mat_iter++;
+ }
+ model_iter++;
+ }
+
+ count = db->getElementCount(NULL, COLLADA_TYPE_SKIN);
+ for (daeInt idx = 0; idx < count; ++idx)
+ { //add skinned meshes as instances
+ domSkin* skin = NULL;
+ db->getElement((daeElement**) &skin, idx, NULL, COLLADA_TYPE_SKIN);
+
+ if (skin)
+ {
+ domGeometry* geom = daeSafeCast<domGeometry>(skin->getSource().getElement());
+
+ if (geom)
+ {
+ domMesh* mesh = geom->getMesh();
+ if (mesh)
+ {
+ std::vector< LLPointer< LLModel > >::iterator i = mModelsMap[mesh].begin();
+ while (i != mModelsMap[mesh].end())
+ {
+ LLPointer<LLModel> mdl = *i;
+ LLDAELoader::processDomModel(mdl, &dae, root, mesh, skin);
+ i++;
+ }
+ }
+ }
+ }
+ }
+
+ LL_INFOS()<< "Collada skins processed: " << count <<LL_ENDL;
+
+ daeElement* scene = root->getDescendant("visual_scene");
+
+ if (!scene)
+ {
+ LL_WARNS() << "document has no visual_scene" << LL_ENDL;
+ setLoadState( ERROR_PARSING );
+ return true;
+ }
+
+ setLoadState( DONE );
+
+ bool badElement = false;
+
+ processElement( scene, badElement, &dae );
+
+ if ( badElement )
+ {
+ LL_INFOS()<<"Scene could not be parsed"<<LL_ENDL;
+ setLoadState( ERROR_PARSING );
+ }
+
+ return true;
+}
+
+void LLDAELoader::processDomModel(LLModel* model, DAE* dae, daeElement* root, domMesh* mesh, domSkin* skin)
+{
+ llassert(model && dae && mesh && skin);
+
+ if (model)
+ {
+ LLVector3 mesh_scale_vector;
+ LLVector3 mesh_translation_vector;
+ model->getNormalizedScaleTranslation(mesh_scale_vector, mesh_translation_vector);
+
+ LLMatrix4 normalized_transformation;
+ normalized_transformation.setTranslation(mesh_translation_vector);
+
+ LLMatrix4 mesh_scale;
+ mesh_scale.initScale(mesh_scale_vector);
+ mesh_scale *= normalized_transformation;
+ normalized_transformation = mesh_scale;
+
+ glh::matrix4f inv_mat((F32*) normalized_transformation.mMatrix);
+ inv_mat = inv_mat.inverse();
+ LLMatrix4 inverse_normalized_transformation(inv_mat.m);
+
+ domSkin::domBind_shape_matrix* bind_mat = skin->getBind_shape_matrix();
+
+ if (bind_mat)
+ { //get bind shape matrix
+ domFloat4x4& dom_value = bind_mat->getValue();
+
+ LLMeshSkinInfo& skin_info = model->mSkinInfo;
+
+ for (int i = 0; i < 4; i++)
+ {
+ for(int j = 0; j < 4; j++)
+ {
+ skin_info.mBindShapeMatrix.mMatrix[i][j] = dom_value[i + j*4];
+ }
+ }
+
+ LLMatrix4 trans = normalized_transformation;
+ trans *= skin_info.mBindShapeMatrix;
+ skin_info.mBindShapeMatrix = trans;
+ }
+
+
+ //Some collada setup for accessing the skeleton
+ daeElement* pElement = 0;
+ dae->getDatabase()->getElement( &pElement, 0, 0, "skeleton" );
+
+ //Try to get at the skeletal instance controller
+ domInstance_controller::domSkeleton* pSkeleton = daeSafeCast<domInstance_controller::domSkeleton>( pElement );
+ bool missingSkeletonOrScene = false;
+
+ //If no skeleton, do a breadth-first search to get at specific joints
+ bool rootNode = false;
+
+ //Need to test for a skeleton that does not have a root node
+ //This occurs when your instance controller does not have an associated scene
+ if ( pSkeleton )
+ {
+ daeElement* pSkeletonRootNode = pSkeleton->getValue().getElement();
+ if ( pSkeletonRootNode )
+ {
+ rootNode = true;
+ }
+
+ }
+ if ( !pSkeleton || !rootNode )
+ {
+ daeElement* pScene = root->getDescendant("visual_scene");
+ if ( !pScene )
+ {
+ LL_WARNS()<<"No visual scene - unable to parse bone offsets "<<LL_ENDL;
+ missingSkeletonOrScene = true;
+ }
+ else
+ {
+ //Get the children at this level
+ daeTArray< daeSmartRef<daeElement> > children = pScene->getChildren();
+ S32 childCount = children.getCount();
+
+ //Process any children that are joints
+ //Not all children are joints, some code be ambient lights, cameras, geometry etc..
+ for (S32 i = 0; i < childCount; ++i)
+ {
+ domNode* pNode = daeSafeCast<domNode>(children[i]);
+ if ( isNodeAJoint( pNode ) )
+ {
+ processJointNode( pNode, mJointList );
+ }
+ }
+ }
+ }
+ else
+ //Has Skeleton
+ {
+ //Get the root node of the skeleton
+ daeElement* pSkeletonRootNode = pSkeleton->getValue().getElement();
+ if ( pSkeletonRootNode )
+ {
+ //Once we have the root node - start acccessing it's joint components
+ const int jointCnt = mJointMap.size();
+ JointMap :: const_iterator jointIt = mJointMap.begin();
+
+ //Loop over all the possible joints within the .dae - using the allowed joint list in the ctor.
+ for ( int i=0; i<jointCnt; ++i, ++jointIt )
+ {
+ //Build a joint for the resolver to work with
+ char str[64]={0};
+ sprintf(str,"./%s",(*jointIt).first.c_str() );
+ //LL_WARNS()<<"Joint "<< str <<LL_ENDL;
+
+ //Setup the resolver
+ daeSIDResolver resolver( pSkeletonRootNode, str );
+
+ //Look for the joint
+ domNode* pJoint = daeSafeCast<domNode>( resolver.getElement() );
+ if ( pJoint )
+ {
+ //Pull out the translate id and store it in the jointTranslations map
+ daeSIDResolver jointResolverA( pJoint, "./translate" );
+ domTranslate* pTranslateA = daeSafeCast<domTranslate>( jointResolverA.getElement() );
+ daeSIDResolver jointResolverB( pJoint, "./location" );
+ domTranslate* pTranslateB = daeSafeCast<domTranslate>( jointResolverB.getElement() );
+
+ LLMatrix4 workingTransform;
+
+ //Translation via SID
+ if ( pTranslateA )
+ {
+ extractTranslation( pTranslateA, workingTransform );
+ }
+ else
+ if ( pTranslateB )
+ {
+ extractTranslation( pTranslateB, workingTransform );
+ }
+ else
+ {
+ //Translation via child from element
+ daeElement* pTranslateElement = getChildFromElement( pJoint, "translate" );
+ if ( pTranslateElement && pTranslateElement->typeID() != domTranslate::ID() )
+ {
+ LL_WARNS()<< "The found element is not a translate node" <<LL_ENDL;
+ missingSkeletonOrScene = true;
+ }
+ else
+ if ( pTranslateElement )
+ {
+ extractTranslationViaElement( pTranslateElement, workingTransform );
+ }
+ else
+ {
+ extractTranslationViaSID( pJoint, workingTransform );
+ }
+
+ }
+
+ //Store the joint transform w/respect to it's name.
+ mJointList[(*jointIt).second.c_str()] = workingTransform;
+ }
+ }
+
+ //If anything failed in regards to extracting the skeleton, joints or translation id,
+ //mention it
+ if ( missingSkeletonOrScene )
+ {
+ LL_WARNS()<< "Partial jointmap found in asset - did you mean to just have a partial map?" << LL_ENDL;
+ }
+ }//got skeleton?
+ }
+
+
+ domSkin::domJoints* joints = skin->getJoints();
+
+ domInputLocal_Array& joint_input = joints->getInput_array();
+
+ for (size_t i = 0; i < joint_input.getCount(); ++i)
+ {
+ domInputLocal* input = joint_input.get(i);
+ xsNMTOKEN semantic = input->getSemantic();
+
+ if (strcmp(semantic, COMMON_PROFILE_INPUT_JOINT) == 0)
+ { //found joint source, fill model->mJointMap and model->mSkinInfo.mJointNames
+ daeElement* elem = input->getSource().getElement();
+
+ domSource* source = daeSafeCast<domSource>(elem);
+ if (source)
+ {
+
+
+ domName_array* names_source = source->getName_array();
+
+ if (names_source)
+ {
+ domListOfNames &names = names_source->getValue();
+
+ for (size_t j = 0; j < names.getCount(); ++j)
+ {
+ std::string name(names.get(j));
+ if (mJointMap.find(name) != mJointMap.end())
+ {
+ name = mJointMap[name];
+ }
+ model->mSkinInfo.mJointNames.push_back(name);
+ model->mSkinInfo.mJointMap[name] = j;
+ }
+ }
+ else
+ {
+ domIDREF_array* names_source = source->getIDREF_array();
+ if (names_source)
+ {
+ xsIDREFS& names = names_source->getValue();
+
+ for (size_t j = 0; j < names.getCount(); ++j)
+ {
+ std::string name(names.get(j).getID());
+ if (mJointMap.find(name) != mJointMap.end())
+ {
+ name = mJointMap[name];
+ }
+ model->mSkinInfo.mJointNames.push_back(name);
+ model->mSkinInfo.mJointMap[name] = j;
+ }
+ }
+ }
+ }
+ }
+ else if (strcmp(semantic, COMMON_PROFILE_INPUT_INV_BIND_MATRIX) == 0)
+ { //found inv_bind_matrix array, fill model->mInvBindMatrix
+ domSource* source = daeSafeCast<domSource>(input->getSource().getElement());
+ if (source)
+ {
+ domFloat_array* t = source->getFloat_array();
+ if (t)
+ {
+ domListOfFloats& transform = t->getValue();
+ S32 count = transform.getCount()/16;
+
+ for (S32 k = 0; k < count; ++k)
+ {
+ LLMatrix4 mat;
+
+ for (int i = 0; i < 4; i++)
+ {
+ for(int j = 0; j < 4; j++)
+ {
+ mat.mMatrix[i][j] = transform[k*16 + i + j*4];
+ }
+ }
+
+ model->mSkinInfo.mInvBindMatrix.push_back(mat);
+ }
+ }
+ }
+ }
+ }
+
+ //Now that we've parsed the joint array, let's determine if we have a full rig
+ //(which means we have all the joint sthat are required for an avatar versus
+ //a skinned asset attached to a node in a file that contains an entire skeleton,
+ //but does not use the skeleton).
+ buildJointToNodeMappingFromScene( root );
+ critiqueRigForUploadApplicability( model->mSkinInfo.mJointNames );
+
+ if ( !missingSkeletonOrScene )
+ {
+ //Set the joint translations on the avatar - if it's a full mapping
+ //The joints are reset in the dtor
+ if ( getRigWithSceneParity() )
+ {
+ JointMap :: const_iterator masterJointIt = mJointMap.begin();
+ JointMap :: const_iterator masterJointItEnd = mJointMap.end();
+ for (;masterJointIt!=masterJointItEnd;++masterJointIt )
+ {
+ std::string lookingForJoint = (*masterJointIt).first.c_str();
+
+ if ( mJointList.find( lookingForJoint ) != mJointList.end() )
+ {
+ //LL_INFOS()<<"joint "<<lookingForJoint.c_str()<<LL_ENDL;
+ LLMatrix4 jointTransform = mJointList[lookingForJoint];
+ LLJoint* pJoint = mJointLookupFunc(lookingForJoint,mOpaqueData);
+ if ( pJoint )
+ {
+ LLUUID fake_mesh_id;
+ fake_mesh_id.generate();
+ pJoint->addAttachmentPosOverride( jointTransform.getTranslation(), fake_mesh_id, "");
+ }
+ else
+ {
+ //Most likely an error in the asset.
+ LL_WARNS()<<"Tried to apply joint position from .dae, but it did not exist in the avatar rig." << LL_ENDL;
+ }
+ }
+ }
+ }
+ } //missingSkeletonOrScene
+
+ //We need to construct the alternate bind matrix (which contains the new joint positions)
+ //in the same order as they were stored in the joint buffer. The joints associated
+ //with the skeleton are not stored in the same order as they are in the exported joint buffer.
+ //This remaps the skeletal joints to be in the same order as the joints stored in the model.
+ std::vector<std::string> :: const_iterator jointIt = model->mSkinInfo.mJointNames.begin();
+ const int jointCnt = model->mSkinInfo.mJointNames.size();
+ for ( int i=0; i<jointCnt; ++i, ++jointIt )
+ {
+ std::string lookingForJoint = (*jointIt).c_str();
+ //Look for the joint xform that we extracted from the skeleton, using the jointIt as the key
+ //and store it in the alternate bind matrix
+ if ( mJointList.find( lookingForJoint ) != mJointList.end() )
+ {
+ LLMatrix4 jointTransform = mJointList[lookingForJoint];
+ LLMatrix4 newInverse = model->mSkinInfo.mInvBindMatrix[i];
+ newInverse.setTranslation( mJointList[lookingForJoint].getTranslation() );
+ model->mSkinInfo.mAlternateBindMatrix.push_back( newInverse );
+ }
+ else
+ {
+ LL_WARNS()<<"Possibly misnamed/missing joint [" <<lookingForJoint.c_str()<<" ] "<<LL_ENDL;
+ }
+ }
+
+ //grab raw position array
+
+ domVertices* verts = mesh->getVertices();
+ if (verts)
+ {
+ domInputLocal_Array& inputs = verts->getInput_array();
+ for (size_t i = 0; i < inputs.getCount() && model->mPosition.empty(); ++i)
+ {
+ if (strcmp(inputs[i]->getSemantic(), COMMON_PROFILE_INPUT_POSITION) == 0)
+ {
+ domSource* pos_source = daeSafeCast<domSource>(inputs[i]->getSource().getElement());
+ if (pos_source)
+ {
+ domFloat_array* pos_array = pos_source->getFloat_array();
+ if (pos_array)
+ {
+ domListOfFloats& pos = pos_array->getValue();
+
+ for (size_t j = 0; j < pos.getCount(); j += 3)
+ {
+ if (pos.getCount() <= j+2)
+ {
+ LL_ERRS() << "Invalid position array size." << LL_ENDL;
+ }
+
+ LLVector3 v(pos[j], pos[j+1], pos[j+2]);
+
+ //transform from COLLADA space to volume space
+ v = v * inverse_normalized_transformation;
+
+ model->mPosition.push_back(v);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ //grab skin weights array
+ domSkin::domVertex_weights* weights = skin->getVertex_weights();
+ if (weights)
+ {
+ domInputLocalOffset_Array& inputs = weights->getInput_array();
+ domFloat_array* vertex_weights = NULL;
+ for (size_t i = 0; i < inputs.getCount(); ++i)
+ {
+ if (strcmp(inputs[i]->getSemantic(), COMMON_PROFILE_INPUT_WEIGHT) == 0)
+ {
+ domSource* weight_source = daeSafeCast<domSource>(inputs[i]->getSource().getElement());
+ if (weight_source)
+ {
+ vertex_weights = weight_source->getFloat_array();
+ }
+ }
+ }
+
+ if (vertex_weights)
+ {
+ domListOfFloats& w = vertex_weights->getValue();
+ domListOfUInts& vcount = weights->getVcount()->getValue();
+ domListOfInts& v = weights->getV()->getValue();
+
+ U32 c_idx = 0;
+ for (size_t vc_idx = 0; vc_idx < vcount.getCount(); ++vc_idx)
+ { //for each vertex
+ daeUInt count = vcount[vc_idx];
+
+ //create list of weights that influence this vertex
+ LLModel::weight_list weight_list;
+
+ for (daeUInt i = 0; i < count; ++i)
+ { //for each weight
+ daeInt joint_idx = v[c_idx++];
+ daeInt weight_idx = v[c_idx++];
+
+ if (joint_idx == -1)
+ {
+ //ignore bindings to bind_shape_matrix
+ continue;
+ }
+
+ F32 weight_value = w[weight_idx];
+
+ weight_list.push_back(LLModel::JointWeight(joint_idx, weight_value));
+ }
+
+ //sort by joint weight
+ std::sort(weight_list.begin(), weight_list.end(), LLModel::CompareWeightGreater());
+
+ std::vector<LLModel::JointWeight> wght;
+
+ F32 total = 0.f;
+
+ for (U32 i = 0; i < llmin((U32) 4, (U32) weight_list.size()); ++i)
+ { //take up to 4 most significant weights
+ if (weight_list[i].mWeight > 0.f)
+ {
+ wght.push_back( weight_list[i] );
+ total += weight_list[i].mWeight;
+ }
+ }
+
+ F32 scale = 1.f/total;
+ if (scale != 1.f)
+ { //normalize weights
+ for (U32 i = 0; i < wght.size(); ++i)
+ {
+ wght[i].mWeight *= scale;
+ }
+ }
+
+ model->mSkinWeights[model->mPosition[vc_idx]] = wght;
+ }
+ }
+
+ }
+
+ //add instance to scene for this model
+
+ LLMatrix4 transformation;
+ transformation.initScale(mesh_scale_vector);
+ transformation.setTranslation(mesh_translation_vector);
+ transformation *= mTransform;
+
+ std::map<std::string, LLImportMaterial> materials;
+ for (U32 i = 0; i < model->mMaterialList.size(); ++i)
+ {
+ materials[model->mMaterialList[i]] = LLImportMaterial();
+ }
+ mScene[transformation].push_back(LLModelInstance(model, model->mLabel, transformation, materials));
+ stretch_extents(model, transformation, mExtents[0], mExtents[1], mFirstTransform);
+ }
+}
+
+//-----------------------------------------------------------------------------
+// buildJointToNodeMappingFromScene()
+//-----------------------------------------------------------------------------
+void LLDAELoader::buildJointToNodeMappingFromScene( daeElement* pRoot )
+{
+ daeElement* pScene = pRoot->getDescendant("visual_scene");
+ if ( pScene )
+ {
+ daeTArray< daeSmartRef<daeElement> > children = pScene->getChildren();
+ S32 childCount = children.getCount();
+ for (S32 i = 0; i < childCount; ++i)
+ {
+ domNode* pNode = daeSafeCast<domNode>(children[i]);
+ processJointToNodeMapping( pNode );
+ }
+ }
+}
+//-----------------------------------------------------------------------------
+// processJointToNodeMapping()
+//-----------------------------------------------------------------------------
+void LLDAELoader::processJointToNodeMapping( domNode* pNode )
+{
+ if ( isNodeAJoint( pNode ) )
+ {
+ //1.Store the parent
+ std::string nodeName = pNode->getName();
+ if ( !nodeName.empty() )
+ {
+ mJointsFromNode.push_front( pNode->getName() );
+ }
+ //2. Handle the kiddo's
+ processChildJoints( pNode );
+ }
+ else
+ {
+ //Determine if the're any children wrt to this failed node.
+ //This occurs when an armature is exported and ends up being what essentially amounts to
+ //as the root for the visual_scene
+ if ( pNode )
+ {
+ processChildJoints( pNode );
+ }
+ else
+ {
+ LL_INFOS()<<"Node is NULL"<<LL_ENDL;
+ }
+
+ }
+}
+//-----------------------------------------------------------------------------
+// processChildJoint()
+//-----------------------------------------------------------------------------
+void LLDAELoader::processChildJoints( domNode* pParentNode )
+{
+ daeTArray< daeSmartRef<daeElement> > childOfChild = pParentNode->getChildren();
+ S32 childOfChildCount = childOfChild.getCount();
+ for (S32 i = 0; i < childOfChildCount; ++i)
+ {
+ domNode* pChildNode = daeSafeCast<domNode>( childOfChild[i] );
+ if ( pChildNode )
+ {
+ processJointToNodeMapping( pChildNode );
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------
+// isNodeAJoint()
+//-----------------------------------------------------------------------------
+bool LLDAELoader::isNodeAJoint( domNode* pNode )
+{
+ if ( !pNode )
+ {
+ LL_INFOS()<<"Created node is NULL"<<LL_ENDL;
+ return false;
+ }
+
+ return LLModelLoader::isNodeAJoint(pNode->getName());
+}
+//-----------------------------------------------------------------------------
+// verifyCount
+//-----------------------------------------------------------------------------
+bool LLDAELoader::verifyCount( int expected, int result )
+{
+ if ( expected != result )
+ {
+ LL_INFOS()<< "Error: (expected/got)"<<expected<<"/"<<result<<"verts"<<LL_ENDL;
+ return false;
+ }
+ return true;
+}
+//-----------------------------------------------------------------------------
+// verifyController
+//-----------------------------------------------------------------------------
+bool LLDAELoader::verifyController( domController* pController )
+{
+
+ bool result = true;
+
+ domSkin* pSkin = pController->getSkin();
+
+ if ( pSkin )
+ {
+ xsAnyURI & uri = pSkin->getSource();
+ domElement* pElement = uri.getElement();
+
+ if ( !pElement )
+ {
+ LL_INFOS()<<"Can't resolve skin source"<<LL_ENDL;
+ return false;
+ }
+
+ daeString type_str = pElement->getTypeName();
+ if ( stricmp(type_str, "geometry") == 0 )
+ {
+ //Skin is reference directly by geometry and get the vertex count from skin
+ domSkin::domVertex_weights* pVertexWeights = pSkin->getVertex_weights();
+ U32 vertexWeightsCount = pVertexWeights->getCount();
+ domGeometry* pGeometry = (domGeometry*) (domElement*) uri.getElement();
+ domMesh* pMesh = pGeometry->getMesh();
+
+ if ( pMesh )
+ {
+ //Get vertex count from geometry
+ domVertices* pVertices = pMesh->getVertices();
+ if ( !pVertices )
+ {
+ LL_INFOS()<<"No vertices!"<<LL_ENDL;
+ return false;
+ }
+
+ if ( pVertices )
+ {
+ xsAnyURI src = pVertices->getInput_array()[0]->getSource();
+ domSource* pSource = (domSource*) (domElement*) src.getElement();
+ U32 verticesCount = pSource->getTechnique_common()->getAccessor()->getCount();
+ result = verifyCount( verticesCount, vertexWeightsCount );
+ if ( !result )
+ {
+ return result;
+ }
+ }
+ }
+
+ U32 vcountCount = (U32) pVertexWeights->getVcount()->getValue().getCount();
+ result = verifyCount( vcountCount, vertexWeightsCount );
+ if ( !result )
+ {
+ return result;
+ }
+
+ domInputLocalOffset_Array& inputs = pVertexWeights->getInput_array();
+ U32 sum = 0;
+ for (size_t i=0; i<vcountCount; i++)
+ {
+ sum += pVertexWeights->getVcount()->getValue()[i];
+ }
+ result = verifyCount( sum * inputs.getCount(), (domInt) pVertexWeights->getV()->getValue().getCount() );
+ }
+ }
+
+ return result;
+}
+
+//-----------------------------------------------------------------------------
+// extractTranslation()
+//-----------------------------------------------------------------------------
+void LLDAELoader::extractTranslation( domTranslate* pTranslate, LLMatrix4& transform )
+{
+ domFloat3 jointTrans = pTranslate->getValue();
+ LLVector3 singleJointTranslation( jointTrans[0], jointTrans[1], jointTrans[2] );
+ transform.setTranslation( singleJointTranslation );
+}
+//-----------------------------------------------------------------------------
+// extractTranslationViaElement()
+//-----------------------------------------------------------------------------
+void LLDAELoader::extractTranslationViaElement( daeElement* pTranslateElement, LLMatrix4& transform )
+{
+ if ( pTranslateElement )
+ {
+ domTranslate* pTranslateChild = dynamic_cast<domTranslate*>( pTranslateElement );
+ domFloat3 translateChild = pTranslateChild->getValue();
+ LLVector3 singleJointTranslation( translateChild[0], translateChild[1], translateChild[2] );
+ transform.setTranslation( singleJointTranslation );
+ }
+}
+//-----------------------------------------------------------------------------
+// extractTranslationViaSID()
+//-----------------------------------------------------------------------------
+void LLDAELoader::extractTranslationViaSID( daeElement* pElement, LLMatrix4& transform )
+{
+ if ( pElement )
+ {
+ daeSIDResolver resolver( pElement, "./transform" );
+ domMatrix* pMatrix = daeSafeCast<domMatrix>( resolver.getElement() );
+ //We are only extracting out the translational component atm
+ LLMatrix4 workingTransform;
+ if ( pMatrix )
+ {
+ domFloat4x4 domArray = pMatrix->getValue();
+ for ( int i = 0; i < 4; i++ )
+ {
+ for( int j = 0; j < 4; j++ )
+ {
+ workingTransform.mMatrix[i][j] = domArray[i + j*4];
+ }
+ }
+ LLVector3 trans = workingTransform.getTranslation();
+ transform.setTranslation( trans );
+ }
+ }
+ else
+ {
+ LL_WARNS()<<"Element is nonexistent - empty/unsupported node."<<LL_ENDL;
+ }
+}
+//-----------------------------------------------------------------------------
+// processJointNode()
+//-----------------------------------------------------------------------------
+void LLDAELoader::processJointNode( domNode* pNode, JointTransformMap& jointTransforms )
+{
+ if (pNode->getName() == NULL)
+ {
+ LL_WARNS() << "nameless node, can't process" << LL_ENDL;
+ return;
+ }
+
+ //LL_WARNS()<<"ProcessJointNode# Node:" <<pNode->getName()<<LL_ENDL;
+
+ //1. handle the incoming node - extract out translation via SID or element
+
+ LLMatrix4 workingTransform;
+
+ //Pull out the translate id and store it in the jointTranslations map
+ daeSIDResolver jointResolverA( pNode, "./translate" );
+ domTranslate* pTranslateA = daeSafeCast<domTranslate>( jointResolverA.getElement() );
+ daeSIDResolver jointResolverB( pNode, "./location" );
+ domTranslate* pTranslateB = daeSafeCast<domTranslate>( jointResolverB.getElement() );
+
+ //Translation via SID was successful
+ if ( pTranslateA )
+ {
+ extractTranslation( pTranslateA, workingTransform );
+ }
+ else
+ if ( pTranslateB )
+ {
+ extractTranslation( pTranslateB, workingTransform );
+ }
+ else
+ {
+ //Translation via child from element
+ daeElement* pTranslateElement = getChildFromElement( pNode, "translate" );
+ if ( !pTranslateElement || pTranslateElement->typeID() != domTranslate::ID() )
+ {
+ //LL_WARNS()<< "The found element is not a translate node" <<LL_ENDL;
+ daeSIDResolver jointResolver( pNode, "./matrix" );
+ domMatrix* pMatrix = daeSafeCast<domMatrix>( jointResolver.getElement() );
+ if ( pMatrix )
+ {
+ //LL_INFOS()<<"A matrix SID was however found!"<<LL_ENDL;
+ domFloat4x4 domArray = pMatrix->getValue();
+ for ( int i = 0; i < 4; i++ )
+ {
+ for( int j = 0; j < 4; j++ )
+ {
+ workingTransform.mMatrix[i][j] = domArray[i + j*4];
+ }
+ }
+ }
+ else
+ {
+ LL_WARNS()<< "The found element is not translate or matrix node - most likely a corrupt export!" <<LL_ENDL;
+ }
+ }
+ else
+ {
+ extractTranslationViaElement( pTranslateElement, workingTransform );
+ }
+ }
+
+ //Store the working transform relative to the nodes name.
+ jointTransforms[ pNode->getName() ] = workingTransform;
+
+ //2. handle the nodes children
+
+ //Gather and handle the incoming nodes children
+ daeTArray< daeSmartRef<daeElement> > childOfChild = pNode->getChildren();
+ S32 childOfChildCount = childOfChild.getCount();
+
+ for (S32 i = 0; i < childOfChildCount; ++i)
+ {
+ domNode* pChildNode = daeSafeCast<domNode>( childOfChild[i] );
+ if ( pChildNode )
+ {
+ processJointNode( pChildNode, jointTransforms );
+ }
+ }
+}
+//-----------------------------------------------------------------------------
+// getChildFromElement()
+//-----------------------------------------------------------------------------
+daeElement* LLDAELoader::getChildFromElement( daeElement* pElement, std::string const & name )
+{
+ daeElement* pChildOfElement = pElement->getChild( name.c_str() );
+ if ( pChildOfElement )
+ {
+ return pChildOfElement;
+ }
+ LL_WARNS()<< "Could not find a child [" << name << "] for the element: \"" << pElement->getAttribute("id") << "\"" << LL_ENDL;
+ return NULL;
+}
+
+void LLDAELoader::processElement( daeElement* element, bool& badElement, DAE* dae )
+{
+ LLMatrix4 saved_transform;
+ bool pushed_mat = false;
+
+ domNode* node = daeSafeCast<domNode>(element);
+ if (node)
+ {
+ pushed_mat = true;
+ saved_transform = mTransform;
+ }
+
+ domTranslate* translate = daeSafeCast<domTranslate>(element);
+ if (translate)
+ {
+ domFloat3 dom_value = translate->getValue();
+
+ LLMatrix4 translation;
+ translation.setTranslation(LLVector3(dom_value[0], dom_value[1], dom_value[2]));
+
+ translation *= mTransform;
+ mTransform = translation;
+ mTransform.condition();
+ }
+
+ domRotate* rotate = daeSafeCast<domRotate>(element);
+ if (rotate)
+ {
+ domFloat4 dom_value = rotate->getValue();
+
+ LLMatrix4 rotation;
+ rotation.initRotTrans(dom_value[3] * DEG_TO_RAD, LLVector3(dom_value[0], dom_value[1], dom_value[2]), LLVector3(0, 0, 0));
+
+ rotation *= mTransform;
+ mTransform = rotation;
+ mTransform.condition();
+ }
+
+ domScale* scale = daeSafeCast<domScale>(element);
+ if (scale)
+ {
+ domFloat3 dom_value = scale->getValue();
+
+
+ LLVector3 scale_vector = LLVector3(dom_value[0], dom_value[1], dom_value[2]);
+ scale_vector.abs(); // Set all values positive, since we don't currently support mirrored meshes
+ LLMatrix4 scaling;
+ scaling.initScale(scale_vector);
+
+ scaling *= mTransform;
+ mTransform = scaling;
+ mTransform.condition();
+ }
+
+ domMatrix* matrix = daeSafeCast<domMatrix>(element);
+ if (matrix)
+ {
+ domFloat4x4 dom_value = matrix->getValue();
+
+ LLMatrix4 matrix_transform;
+
+ for (int i = 0; i < 4; i++)
+ {
+ for(int j = 0; j < 4; j++)
+ {
+ matrix_transform.mMatrix[i][j] = dom_value[i + j*4];
+ }
+ }
+
+ matrix_transform *= mTransform;
+ mTransform = matrix_transform;
+ mTransform.condition();
+ }
+
+ domInstance_geometry* instance_geo = daeSafeCast<domInstance_geometry>(element);
+ if (instance_geo)
+ {
+ domGeometry* geo = daeSafeCast<domGeometry>(instance_geo->getUrl().getElement());
+ if (geo)
+ {
+ domMesh* mesh = daeSafeCast<domMesh>(geo->getDescendant(daeElement::matchType(domMesh::ID())));
+ if (mesh)
+ {
+
+ std::vector< LLPointer< LLModel > >::iterator i = mModelsMap[mesh].begin();
+ while (i != mModelsMap[mesh].end())
+ {
+ LLModel* model = *i;
+
+ LLMatrix4 transformation = mTransform;
+
+ if (mTransform.determinant() < 0)
+ { //negative scales are not supported
+ LL_INFOS() << "Negative scale detected, unsupported transform. domInstance_geometry: " << getElementLabel(instance_geo) << LL_ENDL;
+ badElement = true;
+ }
+
+ LLModelLoader::material_map materials = getMaterials(model, instance_geo, dae);
+
+ // adjust the transformation to compensate for mesh normalization
+ LLVector3 mesh_scale_vector;
+ LLVector3 mesh_translation_vector;
+ model->getNormalizedScaleTranslation(mesh_scale_vector, mesh_translation_vector);
+
+ LLMatrix4 mesh_translation;
+ mesh_translation.setTranslation(mesh_translation_vector);
+ mesh_translation *= transformation;
+ transformation = mesh_translation;
+
+ LLMatrix4 mesh_scale;
+ mesh_scale.initScale(mesh_scale_vector);
+ mesh_scale *= transformation;
+ transformation = mesh_scale;
+
+ if (transformation.determinant() < 0)
+ { //negative scales are not supported
+ LL_INFOS() << "Negative scale detected, unsupported post-normalization transform. domInstance_geometry: " << getElementLabel(instance_geo) << LL_ENDL;
+ badElement = true;
+ }
+
+ std::string label;
+
+ if (model->mLabel.empty())
+ {
+ label = getLodlessLabel(instance_geo);
+
+ llassert(!label.empty());
+
+ if (model->mSubmodelID)
+ {
+ label += (char)((int)'a' + model->mSubmodelID);
+ }
+
+ model->mLabel = label + lod_suffix[mLod];
+ }
+ else
+ {
+ // Don't change model's name if possible, it will play havoc with scenes that already use said model.
+ size_t ext_pos = getSuffixPosition(model->mLabel);
+ if (ext_pos != -1)
+ {
+ label = model->mLabel.substr(0, ext_pos);
+ }
+ else
+ {
+ label = model->mLabel;
+ }
+ }
+
+ mScene[transformation].push_back(LLModelInstance(model, label, transformation, materials));
+ stretch_extents(model, transformation, mExtents[0], mExtents[1], mFirstTransform);
+ i++;
+ }
+ }
+ }
+ else
+ {
+ LL_INFOS()<<"Unable to resolve geometry URL."<<LL_ENDL;
+ badElement = true;
+ }
+
+ }
+
+ domInstance_node* instance_node = daeSafeCast<domInstance_node>(element);
+ if (instance_node)
+ {
+ daeElement* instance = instance_node->getUrl().getElement();
+ if (instance)
+ {
+ processElement(instance,badElement, dae);
+ }
+ }
+
+ //process children
+ daeTArray< daeSmartRef<daeElement> > children = element->getChildren();
+ int childCount = children.getCount();
+ for (S32 i = 0; i < childCount; i++)
+ {
+ processElement(children[i],badElement, dae);
+ }
+
+ if (pushed_mat)
+ { //this element was a node, restore transform before processiing siblings
+ mTransform = saved_transform;
+ }
+}
+
+std::map<std::string, LLImportMaterial> LLDAELoader::getMaterials(LLModel* model, domInstance_geometry* instance_geo, DAE* dae)
+{
+ std::map<std::string, LLImportMaterial> materials;
+ for (int i = 0; i < model->mMaterialList.size(); i++)
+ {
+ LLImportMaterial import_material;
+
+ domInstance_material* instance_mat = NULL;
+
+ domBind_material::domTechnique_common* technique =
+ daeSafeCast<domBind_material::domTechnique_common>(instance_geo->getDescendant(daeElement::matchType(domBind_material::domTechnique_common::ID())));
+
+ if (technique)
+ {
+ daeTArray< daeSmartRef<domInstance_material> > inst_materials = technique->getChildrenByType<domInstance_material>();
+ for (int j = 0; j < inst_materials.getCount(); j++)
+ {
+ std::string symbol(inst_materials[j]->getSymbol());
+
+ if (symbol == model->mMaterialList[i]) // found the binding
+ {
+ instance_mat = inst_materials[j];
+ break;
+ }
+ }
+ }
+
+ if (instance_mat)
+ {
+ domMaterial* material = daeSafeCast<domMaterial>(instance_mat->getTarget().getElement());
+ if (material)
+ {
+ domInstance_effect* instance_effect =
+ daeSafeCast<domInstance_effect>(material->getDescendant(daeElement::matchType(domInstance_effect::ID())));
+ if (instance_effect)
+ {
+ domEffect* effect = daeSafeCast<domEffect>(instance_effect->getUrl().getElement());
+ if (effect)
+ {
+ domProfile_COMMON* profile =
+ daeSafeCast<domProfile_COMMON>(effect->getDescendant(daeElement::matchType(domProfile_COMMON::ID())));
+ if (profile)
+ {
+ import_material = profileToMaterial(profile, dae);
+ }
+ }
+ }
+ }
+ }
+
+ import_material.mBinding = model->mMaterialList[i];
+ materials[model->mMaterialList[i]] = import_material;
+ }
+
+ return materials;
+}
+
+LLImportMaterial LLDAELoader::profileToMaterial(domProfile_COMMON* material, DAE* dae)
+{
+ LLImportMaterial mat;
+ mat.mFullbright = FALSE;
+
+ daeElement* diffuse = material->getDescendant("diffuse");
+ if (diffuse)
+ {
+ domCommon_color_or_texture_type_complexType::domTexture* texture =
+ daeSafeCast<domCommon_color_or_texture_type_complexType::domTexture>(diffuse->getDescendant("texture"));
+ if (texture)
+ {
+ domCommon_newparam_type_Array newparams = material->getNewparam_array();
+ if (newparams.getCount())
+ {
+
+ for (S32 i = 0; i < newparams.getCount(); i++)
+ {
+ domFx_surface_common* surface = newparams[i]->getSurface();
+ if (surface)
+ {
+ domFx_surface_init_common* init = surface->getFx_surface_init_common();
+ if (init)
+ {
+ domFx_surface_init_from_common_Array init_from = init->getInit_from_array();
+
+ if (init_from.getCount() > i)
+ {
+ domImage* image = daeSafeCast<domImage>(init_from[i]->getValue().getElement());
+ if (image)
+ {
+ // we only support init_from now - embedded data will come later
+ domImage::domInit_from* init = image->getInit_from();
+ if (init)
+ {
+ mat.mDiffuseMapFilename = cdom::uriToNativePath(init->getValue().str());
+ mat.mDiffuseMapLabel = getElementLabel(material);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ else if (texture->getTexture())
+ {
+ domImage* image = NULL;
+ dae->getDatabase()->getElement((daeElement**) &image, 0, texture->getTexture(), COLLADA_TYPE_IMAGE);
+ if (image)
+ {
+ // we only support init_from now - embedded data will come later
+ domImage::domInit_from* init = image->getInit_from();
+ if (init)
+ {
+ std::string image_path_value = cdom::uriToNativePath(init->getValue().str());
+
+#if LL_WINDOWS
+ // Work-around DOM tendency to resort to UNC names which are only confusing for downstream...
+ //
+ std::string::iterator i = image_path_value.begin();
+ while (*i == '\\')
+ i++;
+ mat.mDiffuseMapFilename.assign(i, image_path_value.end());
+#else
+ mat.mDiffuseMapFilename = image_path_value;
+#endif
+ mat.mDiffuseMapLabel = getElementLabel(material);
+ }
+ }
+ }
+ }
+
+ domCommon_color_or_texture_type_complexType::domColor* color =
+ daeSafeCast<domCommon_color_or_texture_type_complexType::domColor>(diffuse->getDescendant("color"));
+ if (color)
+ {
+ domFx_color_common domfx_color = color->getValue();
+ LLColor4 value = LLColor4(domfx_color[0], domfx_color[1], domfx_color[2], domfx_color[3]);
+ mat.mDiffuseColor = value;
+ }
+ }
+
+ daeElement* emission = material->getDescendant("emission");
+ if (emission)
+ {
+ LLColor4 emission_color = getDaeColor(emission);
+ if (((emission_color[0] + emission_color[1] + emission_color[2]) / 3.0) > 0.25)
+ {
+ mat.mFullbright = TRUE;
+ }
+ }
+
+ return mat;
+}
+
+// try to get a decent label for this element
+std::string LLDAELoader::getElementLabel(daeElement *element)
+{
+ // if we have a name attribute, use it
+ std::string name = element->getAttribute("name");
+ if (name.length())
+ {
+ return name;
+ }
+
+ // if we have an ID attribute, use it
+ if (element->getID())
+ {
+ return std::string(element->getID());
+ }
+
+ // if we have a parent, use it
+ daeElement* parent = element->getParent();
+ std::string index_string;
+ if (parent)
+ {
+ // retrieve index to distinguish items inside same parent
+ size_t ind = 0;
+ parent->getChildren().find(element, ind);
+ index_string = "_" + boost::lexical_cast<std::string>(ind);
+
+ // if parent has a name or ID, use it
+ std::string name = parent->getAttribute("name");
+ if (!name.length())
+ {
+ name = std::string(parent->getID());
+ }
+
+ if (name.length())
+ {
+ // make sure that index won't mix up with pre-named lod extensions
+ size_t ext_pos = getSuffixPosition(name);
+
+ if (ext_pos == -1)
+ {
+ return name + index_string;
+ }
+ else
+ {
+ return name.insert(ext_pos, index_string);
+ }
+ }
+ }
+
+ // try to use our type
+ daeString element_name = element->getElementName();
+ if (element_name)
+ {
+ return std::string(element_name) + index_string;
+ }
+
+ // if all else fails, use "object"
+ return std::string("object") + index_string;
+}
+
+// static
+size_t LLDAELoader::getSuffixPosition(std::string label)
+{
+ if ((label.find("_LOD") != -1) || (label.find("_PHYS") != -1))
+ {
+ return label.rfind('_');
+ }
+ return -1;
+}
+
+// static
+std::string LLDAELoader::getLodlessLabel(daeElement *element)
+{
+ std::string label = getElementLabel(element);
+ size_t ext_pos = getSuffixPosition(label);
+ if (ext_pos != -1)
+ {
+ return label.substr(0, ext_pos);
+ }
+ return label;
+}
+
+LLColor4 LLDAELoader::getDaeColor(daeElement* element)
+{
+ LLColor4 value;
+ domCommon_color_or_texture_type_complexType::domColor* color =
+ daeSafeCast<domCommon_color_or_texture_type_complexType::domColor>(element->getDescendant("color"));
+ if (color)
+ {
+ domFx_color_common domfx_color = color->getValue();
+ value = LLColor4(domfx_color[0], domfx_color[1], domfx_color[2], domfx_color[3]);
+ }
+
+ return value;
+}
+
+bool LLDAELoader::addVolumeFacesFromDomMesh(LLModel* pModel,domMesh* mesh)
+{
+ LLModel::EModelStatus status = LLModel::NO_ERRORS;
+ domTriangles_Array& tris = mesh->getTriangles_array();
+
+ for (U32 i = 0; i < tris.getCount(); ++i)
+ {
+ domTrianglesRef& tri = tris.get(i);
+
+ status = load_face_from_dom_triangles(pModel->getVolumeFaces(), pModel->getMaterialList(), tri);
+ pModel->mStatus = status;
+ if(status != LLModel::NO_ERRORS)
+ {
+ pModel->ClearFacesAndMaterials();
+ return false;
+ }
+ }
+
+ domPolylist_Array& polys = mesh->getPolylist_array();
+ for (U32 i = 0; i < polys.getCount(); ++i)
+ {
+ domPolylistRef& poly = polys.get(i);
+ status = load_face_from_dom_polylist(pModel->getVolumeFaces(), pModel->getMaterialList(), poly);
+
+ if(status != LLModel::NO_ERRORS)
+ {
+ pModel->ClearFacesAndMaterials();
+ return false;
+ }
+ }
+
+ domPolygons_Array& polygons = mesh->getPolygons_array();
+
+ for (U32 i = 0; i < polygons.getCount(); ++i)
+ {
+ domPolygonsRef& poly = polygons.get(i);
+ status = load_face_from_dom_polygons(pModel->getVolumeFaces(), pModel->getMaterialList(), poly);
+
+ if(status != LLModel::NO_ERRORS)
+ {
+ pModel->ClearFacesAndMaterials();
+ return false;
+ }
+ }
+
+ return (status == LLModel::NO_ERRORS);
+}
+
+//static
+LLModel* LLDAELoader::loadModelFromDomMesh(domMesh *mesh)
+{
+ LLVolumeParams volume_params;
+ volume_params.setType(LL_PCODE_PROFILE_SQUARE, LL_PCODE_PATH_LINE);
+ LLModel* ret = new LLModel(volume_params, 0.f);
+ createVolumeFacesFromDomMesh(ret, mesh);
+ if (ret->mLabel.empty())
+ {
+ ret->mLabel = getElementLabel(mesh);
+ }
+ return ret;
+}
+
+//static diff version supports creating multiple models when material counts spill
+// over the 8 face server-side limit
+//
+bool LLDAELoader::loadModelsFromDomMesh(domMesh* mesh, std::vector<LLModel*>& models_out, U32 submodel_limit)
+{
+
+ LLVolumeParams volume_params;
+ volume_params.setType(LL_PCODE_PROFILE_SQUARE, LL_PCODE_PATH_LINE);
+
+ models_out.clear();
+
+ LLModel* ret = new LLModel(volume_params, 0.f);
+
+ std::string model_name = getLodlessLabel(mesh);
+ ret->mLabel = model_name + lod_suffix[mLod];
+
+ llassert(!ret->mLabel.empty());
+
+ // Like a monkey, ready to be shot into space
+ //
+ ret->ClearFacesAndMaterials();
+
+ // Get the whole set of volume faces
+ //
+ addVolumeFacesFromDomMesh(ret, mesh);
+
+ U32 volume_faces = ret->getNumVolumeFaces();
+
+ // Side-steps all manner of issues when splitting models
+ // and matching lower LOD materials to base models
+ //
+ ret->sortVolumeFacesByMaterialName();
+
+ bool normalized = false;
+
+ int submodelID = 0;
+
+ // remove all faces that definitely won't fit into one model and submodel limit
+ U32 face_limit = (submodel_limit + 1) * LL_SCULPT_MESH_MAX_FACES;
+ if (face_limit < volume_faces)
+ {
+ ret->setNumVolumeFaces(face_limit);
+ }
+
+ LLVolume::face_list_t remainder;
+ do
+ {
+ // Insure we do this once with the whole gang and not per-model
+ //
+ if (!normalized && !mNoNormalize)
+ {
+ normalized = true;
+ ret->normalizeVolumeFaces();
+ }
+
+ ret->trimVolumeFacesToSize(LL_SCULPT_MESH_MAX_FACES, &remainder);
+
+ if (!mNoOptimize)
+ {
+ ret->optimizeVolumeFaces();
+ }
+
+ volume_faces = remainder.size();
+
+ models_out.push_back(ret);
+
+ // If we have left-over volume faces, create another model
+ // to absorb them...
+ //
+ if (volume_faces)
+ {
+ LLModel* next = new LLModel(volume_params, 0.f);
+ next->mSubmodelID = ++submodelID;
+ next->mLabel = model_name + (char)((int)'a' + next->mSubmodelID) + lod_suffix[mLod];
+ next->getVolumeFaces() = remainder;
+ next->mNormalizedScale = ret->mNormalizedScale;
+ next->mNormalizedTranslation = ret->mNormalizedTranslation;
+ if ( ret->mMaterialList.size() > LL_SCULPT_MESH_MAX_FACES)
+ {
+ next->mMaterialList.assign(ret->mMaterialList.begin() + LL_SCULPT_MESH_MAX_FACES, ret->mMaterialList.end());
+ }
+ ret = next;
+ }
+
+ remainder.clear();
+
+ } while (volume_faces);
+
+ return true;
+}
+
+bool LLDAELoader::createVolumeFacesFromDomMesh(LLModel* pModel, domMesh* mesh)
+{
+ if (mesh)
+ {
+ pModel->ClearFacesAndMaterials();
+
+ addVolumeFacesFromDomMesh(pModel, mesh);
+
+ if (pModel->getNumVolumeFaces() > 0)
+ {
+ pModel->normalizeVolumeFaces();
+ pModel->optimizeVolumeFaces();
+
+ if (pModel->getNumVolumeFaces() > 0)
+ {
+ return true;
+ }
+ }
+ }
+ else
+ {
+ LL_WARNS() << "no mesh found" << LL_ENDL;
+ }
+
+ return false;
+}
diff --git a/indra/llprimitive/lldaeloader.h b/indra/llprimitive/lldaeloader.h
new file mode 100644
index 0000000000..896451320c
--- /dev/null
+++ b/indra/llprimitive/lldaeloader.h
@@ -0,0 +1,108 @@
+/**
+ * @file lldaeloader.h
+ * @brief LLDAELoader class definition
+ *
+ * $LicenseInfo:firstyear=2013&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2013, 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_LLDAELOADER_H
+#define LL_LLDAELOADER_H
+
+#include "llmodelloader.h"
+
+class DAE;
+class daeElement;
+class domProfile_COMMON;
+class domInstance_geometry;
+class domNode;
+class domTranslate;
+class domController;
+class domSkin;
+class domMesh;
+
+class LLDAELoader : public LLModelLoader
+{
+public:
+ typedef std::map<std::string, LLImportMaterial> material_map;
+ typedef std::map<daeElement*, std::vector<LLPointer<LLModel> > > dae_model_map;
+ dae_model_map mModelsMap;
+
+ LLDAELoader(
+ std::string filename,
+ S32 lod,
+ LLModelLoader::load_callback_t load_cb,
+ LLModelLoader::joint_lookup_func_t joint_lookup_func,
+ LLModelLoader::texture_load_func_t texture_load_func,
+ LLModelLoader::state_callback_t state_cb,
+ void* opaque_userdata,
+ JointTransformMap& jointTransformMap,
+ JointNameSet& jointsFromNodes,
+ JointNameSet& legalJointNames,
+ U32 modelLimit);
+ virtual ~LLDAELoader() ;
+
+ virtual bool OpenFile(const std::string& filename);
+
+protected:
+
+ void processElement(daeElement* element, bool& badElement, DAE* dae);
+ void processDomModel(LLModel* model, DAE* dae, daeElement* pRoot, domMesh* mesh, domSkin* skin);
+
+ material_map getMaterials(LLModel* model, domInstance_geometry* instance_geo, DAE* dae);
+ LLImportMaterial profileToMaterial(domProfile_COMMON* material, DAE* dae);
+ LLColor4 getDaeColor(daeElement* element);
+
+ daeElement* getChildFromElement( daeElement* pElement, std::string const & name );
+
+ bool isNodeAJoint( domNode* pNode );
+ void processJointNode( domNode* pNode, std::map<std::string,LLMatrix4>& jointTransforms );
+ void extractTranslation( domTranslate* pTranslate, LLMatrix4& transform );
+ void extractTranslationViaElement( daeElement* pTranslateElement, LLMatrix4& transform );
+ void extractTranslationViaSID( daeElement* pElement, LLMatrix4& transform );
+ void buildJointToNodeMappingFromScene( daeElement* pRoot );
+ void processJointToNodeMapping( domNode* pNode );
+ void processChildJoints( domNode* pParentNode );
+
+ bool verifyCount( int expected, int result );
+
+ //Verify that a controller matches vertex counts
+ bool verifyController( domController* pController );
+
+ static bool addVolumeFacesFromDomMesh(LLModel* model, domMesh* mesh);
+ static bool createVolumeFacesFromDomMesh(LLModel* model, domMesh *mesh);
+
+ static LLModel* loadModelFromDomMesh(domMesh* mesh);
+
+ // Loads a mesh breaking it into one or more models as necessary
+ // to get around volume face limitations while retaining >8 materials
+ //
+ bool loadModelsFromDomMesh(domMesh* mesh, std::vector<LLModel*>& models_out, U32 submodel_limit);
+
+ static std::string getElementLabel(daeElement *element);
+ static size_t getSuffixPosition(std::string label);
+ static std::string getLodlessLabel(daeElement *element);
+
+private:
+ U32 mGeneratedModelLimit; // Attempt to limit amount of generated submodels
+
+};
+#endif // LL_LLDAELLOADER_H
diff --git a/indra/llprimitive/llmodel.cpp b/indra/llprimitive/llmodel.cpp
index ed903146ef..72b5ca77dd 100755
--- a/indra/llprimitive/llmodel.cpp
+++ b/indra/llprimitive/llmodel.cpp
@@ -31,18 +31,6 @@
#include "llconvexdecomposition.h"
#include "llsdserialize.h"
#include "llvector4a.h"
-#if LL_MSVC
-#pragma warning (disable : 4263)
-#pragma warning (disable : 4264)
-#endif
-#include "dae.h"
-#include "dae/daeErrorHandler.h"
-#include "dom/domConstants.h"
-#include "dom/domMesh.h"
-#if LL_MSVC
-#pragma warning (default : 4263)
-#pragma warning (default : 4264)
-#endif
#ifdef LL_USESYSTEMLIBS
# include <zlib.h>
@@ -50,8 +38,6 @@
# include "zlib/zlib.h"
#endif
-
-
std::string model_names[] =
{
"lowest_lod",
@@ -65,7 +51,7 @@ const int MODEL_NAMES_LENGTH = sizeof(model_names) / sizeof(std::string);
LLModel::LLModel(LLVolumeParams& params, F32 detail)
: LLVolume(params, detail), mNormalizedScale(1,1,1), mNormalizedTranslation(0,0,0)
- , mPelvisOffset( 0.0f ), mStatus(NO_ERRORS)
+ , mPelvisOffset( 0.0f ), mStatus(NO_ERRORS), mSubmodelID(0)
{
mDecompID = -1;
mLocalID = -1;
@@ -79,939 +65,112 @@ LLModel::~LLModel()
}
}
-
-bool get_dom_sources(const domInputLocalOffset_Array& inputs, S32& pos_offset, S32& tc_offset, S32& norm_offset, S32 &idx_stride,
- domSource* &pos_source, domSource* &tc_source, domSource* &norm_source)
+//static
+std::string LLModel::getStatusString(U32 status)
{
- idx_stride = 0;
+ const static std::string status_strings[(S32)INVALID_STATUS] = {"status_no_error", "status_vertex_number_overflow","bad_element"};
- for (U32 j = 0; j < inputs.getCount(); ++j)
+ if(status < INVALID_STATUS)
{
- idx_stride = llmax((S32) inputs[j]->getOffset(), idx_stride);
-
- if (strcmp(COMMON_PROFILE_INPUT_VERTEX, inputs[j]->getSemantic()) == 0)
- { //found vertex array
- const domURIFragmentType& uri = inputs[j]->getSource();
- daeElementRef elem = uri.getElement();
- domVertices* vertices = (domVertices*) elem.cast();
- if ( !vertices )
- {
- return false;
- }
-
- domInputLocal_Array& v_inp = vertices->getInput_array();
-
-
- for (U32 k = 0; k < v_inp.getCount(); ++k)
- {
- if (strcmp(COMMON_PROFILE_INPUT_POSITION, v_inp[k]->getSemantic()) == 0)
- {
- pos_offset = inputs[j]->getOffset();
-
- const domURIFragmentType& uri = v_inp[k]->getSource();
- daeElementRef elem = uri.getElement();
- pos_source = (domSource*) elem.cast();
- }
-
- if (strcmp(COMMON_PROFILE_INPUT_NORMAL, v_inp[k]->getSemantic()) == 0)
- {
- norm_offset = inputs[j]->getOffset();
-
- const domURIFragmentType& uri = v_inp[k]->getSource();
- daeElementRef elem = uri.getElement();
- norm_source = (domSource*) elem.cast();
- }
- }
- }
-
- if (strcmp(COMMON_PROFILE_INPUT_NORMAL, inputs[j]->getSemantic()) == 0)
+ if(status_strings[status] == std::string())
{
- //found normal array for this triangle list
- norm_offset = inputs[j]->getOffset();
- const domURIFragmentType& uri = inputs[j]->getSource();
- daeElementRef elem = uri.getElement();
- norm_source = (domSource*) elem.cast();
+ //LL_ERRS() << "No valid status string for this status: " << (U32)status << LL_ENDL();
}
- else if (strcmp(COMMON_PROFILE_INPUT_TEXCOORD, inputs[j]->getSemantic()) == 0)
- { //found texCoords
- tc_offset = inputs[j]->getOffset();
- const domURIFragmentType& uri = inputs[j]->getSource();
- daeElementRef elem = uri.getElement();
- tc_source = (domSource*) elem.cast();
- }
- }
-
- idx_stride += 1;
-
- return true;
-}
-
-LLModel::EModelStatus load_face_from_dom_triangles(std::vector<LLVolumeFace>& face_list, std::vector<std::string>& materials, domTrianglesRef& tri)
-{
- LLVolumeFace face;
- std::vector<LLVolumeFace::VertexData> verts;
- std::vector<U16> indices;
-
- const domInputLocalOffset_Array& inputs = tri->getInput_array();
-
- S32 pos_offset = -1;
- S32 tc_offset = -1;
- S32 norm_offset = -1;
-
- domSource* pos_source = NULL;
- domSource* tc_source = NULL;
- domSource* norm_source = NULL;
-
- S32 idx_stride = 0;
-
- if ( !get_dom_sources(inputs, pos_offset, tc_offset, norm_offset, idx_stride, pos_source, tc_source, norm_source) || !pos_source )
- {
- LL_WARNS() << "Could not find dom sources for basic geo data; invalid model." << LL_ENDL;
- return LLModel::BAD_ELEMENT;
+ return status_strings[status] ;
}
- if (!pos_source)
- {
- LL_WARNS() << "Unable to process mesh without position data; invalid model; invalid model." << LL_ENDL;
- return LLModel::BAD_ELEMENT;
- }
-
- domPRef p = tri->getP();
- domListOfUInts& idx = p->getValue();
-
- domListOfFloats dummy ;
- domListOfFloats& v = (pos_source && pos_source->getFloat_array()) ? pos_source->getFloat_array()->getValue() : dummy ;
- domListOfFloats& tc = (tc_source && tc_source->getFloat_array()) ? tc_source->getFloat_array()->getValue() : dummy ;
- domListOfFloats& n = (norm_source && norm_source->getFloat_array()) ? norm_source->getFloat_array()->getValue() : dummy ;
+ //LL_ERRS() << "Invalid model status: " << (U32)status << LL_ENDL();
- LLVolumeFace::VertexMapData::PointMap point_map;
-
- U32 index_count = idx.getCount();
- U32 vertex_count = (pos_source && pos_source->getFloat_array()) ? v.getCount() : 0;
- U32 tc_count = (tc_source && tc_source->getFloat_array()) ? tc.getCount() : 0;
- U32 norm_count = (norm_source && norm_source->getFloat_array()) ? n.getCount(): 0;
+ return std::string() ;
+}
- if (vertex_count == 0)
- {
- LL_WARNS() << "Unable to process mesh with empty position array; invalid model." << LL_ENDL;
- return LLModel::BAD_ELEMENT;
- }
- face.mExtents[0].set(v[0], v[1], v[2]);
- face.mExtents[1].set(v[0], v[1], v[2]);
+void LLModel::offsetMesh( const LLVector3& pivotPoint )
+{
+ LLVector4a pivot( pivotPoint[VX], pivotPoint[VY], pivotPoint[VZ] );
- for (U32 i = 0; i < index_count; i += idx_stride)
- {
- LLVolumeFace::VertexData cv;
- if (pos_source)
- {
- // guard against model data specifiying out of range indices or verts
- //
- if (((i + pos_offset) > index_count)
- || ((idx[i+pos_offset]*3+2) > vertex_count))
- {
- LL_WARNS() << "Out of range index data; invalid model." << LL_ENDL;
- return LLModel::BAD_ELEMENT;
- }
-
- cv.setPosition(LLVector4a(v[idx[i+pos_offset]*3+0],
- v[idx[i+pos_offset]*3+1],
- v[idx[i+pos_offset]*3+2]));
-
- if (!cv.getPosition().isFinite3())
- {
- LL_WARNS() << "Nan positional data, invalid model." << LL_ENDL;
- return LLModel::BAD_ELEMENT;
- }
- }
-
- if (tc_source)
- {
- // guard against model data specifiying out of range indices or tcs
- //
-
- if (((i + tc_offset) > index_count)
- || ((idx[i+tc_offset]*2+1) > tc_count))
- {
- LL_WARNS() << "Out of range TC indices." << LL_ENDL;
- return LLModel::BAD_ELEMENT;
- }
-
- cv.mTexCoord.setVec(tc[idx[i+tc_offset]*2+0],
- tc[idx[i+tc_offset]*2+1]);
-
- if (!cv.mTexCoord.isFinite())
- {
- LL_WARNS() << "Found NaN while loading tex coords from DAE-Model, invalid model." << LL_ENDL;
- return LLModel::BAD_ELEMENT;
- }
- }
-
- if (norm_source)
- {
- // guard against model data specifiying out of range indices or norms
- //
- if (((i + norm_offset) > index_count)
- || ((idx[i+norm_offset]*3+2) > norm_count))
- {
- LL_WARNS() << "Found out of range norm indices, invalid model." << LL_ENDL;
- return LLModel::BAD_ELEMENT;
- }
-
- cv.setNormal(LLVector4a(n[idx[i+norm_offset]*3+0],
- n[idx[i+norm_offset]*3+1],
- n[idx[i+norm_offset]*3+2]));
-
- if (!cv.getNormal().isFinite3())
- {
- LL_WARNS() << "Found NaN while loading normals from DAE-Model, invalid model." << LL_ENDL;
- return LLModel::BAD_ELEMENT;
- }
- }
-
- BOOL found = FALSE;
-
- LLVolumeFace::VertexMapData::PointMap::iterator point_iter;
- point_iter = point_map.find(LLVector3(cv.getPosition().getF32ptr()));
-
- if (point_iter != point_map.end())
- {
- for (U32 j = 0; j < point_iter->second.size(); ++j)
- {
- if ((point_iter->second)[j] == cv)
- {
- found = TRUE;
- indices.push_back((point_iter->second)[j].mIndex);
- break;
- }
- }
- }
-
- if (!found)
- {
- update_min_max(face.mExtents[0], face.mExtents[1], cv.getPosition());
- verts.push_back(cv);
- if (verts.size() >= 65535)
- {
- //LL_ERRS() << "Attempted to write model exceeding 16-bit index buffer limitation." << LL_ENDL;
- return LLModel::VERTEX_NUMBER_OVERFLOW ;
- }
- U16 index = (U16) (verts.size()-1);
- indices.push_back(index);
-
- LLVolumeFace::VertexMapData d;
- d.setPosition(cv.getPosition());
- d.mTexCoord = cv.mTexCoord;
- d.setNormal(cv.getNormal());
- d.mIndex = index;
- if (point_iter != point_map.end())
- {
- point_iter->second.push_back(d);
- }
- else
- {
- point_map[LLVector3(d.getPosition().getF32ptr())].push_back(d);
- }
- }
-
- if (indices.size()%3 == 0 && verts.size() >= 65532)
- {
- std::string material;
-
- if (tri->getMaterial())
- {
- material = std::string(tri->getMaterial());
- }
-
- materials.push_back(material);
- face_list.push_back(face);
- face_list.rbegin()->fillFromLegacyData(verts, indices);
- LLVolumeFace& new_face = *face_list.rbegin();
- if (!norm_source)
- {
- //ll_aligned_free_16(new_face.mNormals);
- new_face.mNormals = NULL;
- }
-
- if (!tc_source)
- {
- //ll_aligned_free_16(new_face.mTexCoords);
- new_face.mTexCoords = NULL;
- }
-
- face = LLVolumeFace();
- point_map.clear();
- }
- }
-
- if (!verts.empty())
+ for (std::vector<LLVolumeFace>::iterator faceIt = mVolumeFaces.begin(); faceIt != mVolumeFaces.end(); )
{
- std::string material;
-
- if (tri->getMaterial())
- {
- material = std::string(tri->getMaterial());
- }
+ std::vector<LLVolumeFace>:: iterator currentFaceIt = faceIt++;
+ LLVolumeFace& face = *currentFaceIt;
+ LLVector4a *pos = (LLVector4a*) face.mPositions;
- materials.push_back(material);
- face_list.push_back(face);
-
- face_list.rbegin()->fillFromLegacyData(verts, indices);
- LLVolumeFace& new_face = *face_list.rbegin();
- if (!norm_source)
- {
- //ll_aligned_free_16(new_face.mNormals);
- new_face.mNormals = NULL;
- }
-
- if (!tc_source)
+ for (U32 i=0; i<face.mNumVertices; ++i )
{
- //ll_aligned_free_16(new_face.mTexCoords);
- new_face.mTexCoords = NULL;
+ pos[i].add( pivot );
}
}
-
- return LLModel::NO_ERRORS ;
}
-LLModel::EModelStatus load_face_from_dom_polylist(std::vector<LLVolumeFace>& face_list, std::vector<std::string>& materials, domPolylistRef& poly)
+void LLModel::optimizeVolumeFaces()
{
- domPRef p = poly->getP();
- domListOfUInts& idx = p->getValue();
-
- if (idx.getCount() == 0)
- {
- return LLModel::NO_ERRORS ;
- }
-
- const domInputLocalOffset_Array& inputs = poly->getInput_array();
-
-
- domListOfUInts& vcount = poly->getVcount()->getValue();
-
- S32 pos_offset = -1;
- S32 tc_offset = -1;
- S32 norm_offset = -1;
-
- domSource* pos_source = NULL;
- domSource* tc_source = NULL;
- domSource* norm_source = NULL;
-
- S32 idx_stride = 0;
-
- if (!get_dom_sources(inputs, pos_offset, tc_offset, norm_offset, idx_stride, pos_source, tc_source, norm_source))
- {
- LL_WARNS() << "Could not get DOM sources for basic geo data, invalid model." << LL_ENDL;
- return LLModel::BAD_ELEMENT;
- }
-
- LLVolumeFace face;
-
- std::vector<U16> indices;
- std::vector<LLVolumeFace::VertexData> verts;
-
- domListOfFloats v;
- domListOfFloats tc;
- domListOfFloats n;
-
- if (pos_source)
- {
- v = pos_source->getFloat_array()->getValue();
- face.mExtents[0].set(v[0], v[1], v[2]);
- face.mExtents[1].set(v[0], v[1], v[2]);
- }
-
- if (tc_source)
- {
- tc = tc_source->getFloat_array()->getValue();
- }
-
- if (norm_source)
- {
- n = norm_source->getFloat_array()->getValue();
- }
-
- LLVolumeFace::VertexMapData::PointMap point_map;
-
- U32 index_count = idx.getCount();
- U32 vertex_count = pos_source ? v.getCount() : 0;
- U32 tc_count = tc_source ? tc.getCount() : 0;
- U32 norm_count = norm_source ? n.getCount() : 0;
-
- U32 cur_idx = 0;
- for (U32 i = 0; i < vcount.getCount(); ++i)
- { //for each polygon
- U32 first_index = 0;
- U32 last_index = 0;
- for (U32 j = 0; j < vcount[i]; ++j)
- { //for each vertex
-
- LLVolumeFace::VertexData cv;
-
- if (pos_source)
- {
- // guard against model data specifiying out of range indices or verts
- //
- if (((cur_idx + pos_offset) > index_count)
- || ((idx[cur_idx+pos_offset]*3+2) > vertex_count))
- {
- LL_WARNS() << "Out of range position indices, invalid model." << LL_ENDL;
- return LLModel::BAD_ELEMENT;
- }
-
- cv.getPosition().set(v[idx[cur_idx+pos_offset]*3+0],
- v[idx[cur_idx+pos_offset]*3+1],
- v[idx[cur_idx+pos_offset]*3+2]);
-
- if (!cv.getPosition().isFinite3())
- {
- LL_WARNS() << "Found NaN while loading positions from DAE-Model, invalid model." << LL_ENDL;
- return LLModel::BAD_ELEMENT;
- }
-
- }
-
- if (tc_source)
- {
- // guard against model data specifiying out of range indices or tcs
- //
- if (((cur_idx + tc_offset) > index_count)
- || ((idx[cur_idx+tc_offset]*2+1) > tc_count))
- {
- LL_WARNS() << "Out of range TC indices, invalid model." << LL_ENDL;
- return LLModel::BAD_ELEMENT;
- }
-
- cv.mTexCoord.setVec(tc[idx[cur_idx+tc_offset]*2+0],
- tc[idx[cur_idx+tc_offset]*2+1]);
-
- if (!cv.mTexCoord.isFinite())
- {
- LL_WARNS() << "Found NaN while loading tex coords from DAE-Model, invalid model." << LL_ENDL;
- return LLModel::BAD_ELEMENT;
- }
- }
-
- if (norm_source)
- {
- // guard against model data specifiying out of range indices or norms
- //
- if (((cur_idx + norm_offset) > index_count)
- || ((idx[cur_idx+norm_offset]*3+2) > norm_count))
- {
- LL_WARNS() << "Out of range norm indices, invalid model." << LL_ENDL;
- return LLModel::BAD_ELEMENT;
- }
-
- cv.getNormal().set(n[idx[cur_idx+norm_offset]*3+0],
- n[idx[cur_idx+norm_offset]*3+1],
- n[idx[cur_idx+norm_offset]*3+2]);
-
- if (!cv.getNormal().isFinite3())
- {
- LL_WARNS() << "Found NaN while loading normals from DAE-Model, invalid model." << LL_ENDL;
- return LLModel::BAD_ELEMENT;
- }
- }
-
- cur_idx += idx_stride;
-
- BOOL found = FALSE;
-
- LLVolumeFace::VertexMapData::PointMap::iterator point_iter;
- LLVector3 pos3(cv.getPosition().getF32ptr());
- point_iter = point_map.find(pos3);
-
- if (point_iter != point_map.end())
- {
- for (U32 k = 0; k < point_iter->second.size(); ++k)
- {
- if ((point_iter->second)[k] == cv)
- {
- found = TRUE;
- U32 index = (point_iter->second)[k].mIndex;
- if (j == 0)
- {
- first_index = index;
- }
- else if (j == 1)
- {
- last_index = index;
- }
- else
- {
- indices.push_back(first_index);
- indices.push_back(last_index);
- indices.push_back(index);
- last_index = index;
- }
-
- break;
- }
- }
- }
-
- if (!found)
- {
- update_min_max(face.mExtents[0], face.mExtents[1], cv.getPosition());
- verts.push_back(cv);
- if (verts.size() >= 65535)
- {
- //LL_ERRS() << "Attempted to write model exceeding 16-bit index buffer limitation." << LL_ENDL;
- return LLModel::VERTEX_NUMBER_OVERFLOW ;
- }
- U16 index = (U16) (verts.size()-1);
-
- if (j == 0)
- {
- first_index = index;
- }
- else if (j == 1)
- {
- last_index = index;
- }
- else
- {
- indices.push_back(first_index);
- indices.push_back(last_index);
- indices.push_back(index);
- last_index = index;
- }
-
- LLVolumeFace::VertexMapData d;
- d.setPosition(cv.getPosition());
- d.mTexCoord = cv.mTexCoord;
- d.setNormal(cv.getNormal());
- d.mIndex = index;
- if (point_iter != point_map.end())
- {
- point_iter->second.push_back(d);
- }
- else
- {
- point_map[pos3].push_back(d);
- }
- }
-
- if (indices.size()%3 == 0 && indices.size() >= 65532)
- {
- std::string material;
-
- if (poly->getMaterial())
- {
- material = std::string(poly->getMaterial());
- }
-
- materials.push_back(material);
- face_list.push_back(face);
- face_list.rbegin()->fillFromLegacyData(verts, indices);
- LLVolumeFace& new_face = *face_list.rbegin();
- if (!norm_source)
- {
- //ll_aligned_free_16(new_face.mNormals);
- new_face.mNormals = NULL;
- }
-
- if (!tc_source)
- {
- //ll_aligned_free_16(new_face.mTexCoords);
- new_face.mTexCoords = NULL;
- }
-
- face = LLVolumeFace();
- verts.clear();
- indices.clear();
- point_map.clear();
- }
- }
- }
-
- if (!verts.empty())
+ for (U32 i = 0; i < getNumVolumeFaces(); ++i)
{
- std::string material;
-
- if (poly->getMaterial())
- {
- material = std::string(poly->getMaterial());
- }
-
- materials.push_back(material);
- face_list.push_back(face);
- face_list.rbegin()->fillFromLegacyData(verts, indices);
-
- LLVolumeFace& new_face = *face_list.rbegin();
- if (!norm_source)
- {
- //ll_aligned_free_16(new_face.mNormals);
- new_face.mNormals = NULL;
- }
-
- if (!tc_source)
- {
- //ll_aligned_free_16(new_face.mTexCoords);
- new_face.mTexCoords = NULL;
- }
+ mVolumeFaces[i].optimize();
}
-
- return LLModel::NO_ERRORS ;
}
-LLModel::EModelStatus load_face_from_dom_polygons(std::vector<LLVolumeFace>& face_list, std::vector<std::string>& materials, domPolygonsRef& poly)
+struct MaterialBinding
{
- LLVolumeFace face;
- std::vector<U16> indices;
- std::vector<LLVolumeFace::VertexData> verts;
-
- const domInputLocalOffset_Array& inputs = poly->getInput_array();
-
- S32 v_offset = -1;
- S32 n_offset = -1;
- S32 t_offset = -1;
-
- domListOfFloats* v = NULL;
- domListOfFloats* n = NULL;
- domListOfFloats* t = NULL;
-
- U32 stride = 0;
- for (U32 i = 0; i < inputs.getCount(); ++i)
- {
- stride = llmax((U32) inputs[i]->getOffset()+1, stride);
-
- if (strcmp(COMMON_PROFILE_INPUT_VERTEX, inputs[i]->getSemantic()) == 0)
- { //found vertex array
- v_offset = inputs[i]->getOffset();
-
- const domURIFragmentType& uri = inputs[i]->getSource();
- daeElementRef elem = uri.getElement();
- domVertices* vertices = (domVertices*) elem.cast();
- if (!vertices)
- {
- LL_WARNS() << "Could not find vertex source, invalid model." << LL_ENDL;
- return LLModel::BAD_ELEMENT;
- }
- domInputLocal_Array& v_inp = vertices->getInput_array();
-
- for (U32 k = 0; k < v_inp.getCount(); ++k)
- {
- if (strcmp(COMMON_PROFILE_INPUT_POSITION, v_inp[k]->getSemantic()) == 0)
- {
- const domURIFragmentType& uri = v_inp[k]->getSource();
- daeElementRef elem = uri.getElement();
- domSource* src = (domSource*) elem.cast();
- if (!src)
- {
- LL_WARNS() << "Could not find DOM source, invalid model." << LL_ENDL;
- return LLModel::BAD_ELEMENT;
- }
- v = &(src->getFloat_array()->getValue());
- }
- }
- }
- else if (strcmp(COMMON_PROFILE_INPUT_NORMAL, inputs[i]->getSemantic()) == 0)
- {
- n_offset = inputs[i]->getOffset();
- //found normal array for this triangle list
- const domURIFragmentType& uri = inputs[i]->getSource();
- daeElementRef elem = uri.getElement();
- domSource* src = (domSource*) elem.cast();
- if (!src)
- {
- LL_WARNS() << "Could not find DOM source, invalid model." << LL_ENDL;
- return LLModel::BAD_ELEMENT;
- }
- n = &(src->getFloat_array()->getValue());
- }
- else if (strcmp(COMMON_PROFILE_INPUT_TEXCOORD, inputs[i]->getSemantic()) == 0 && inputs[i]->getSet() == 0)
- { //found texCoords
- t_offset = inputs[i]->getOffset();
- const domURIFragmentType& uri = inputs[i]->getSource();
- daeElementRef elem = uri.getElement();
- domSource* src = (domSource*) elem.cast();
- if (!src)
- {
- LL_WARNS() << "Could not find DOM source, invalid model." << LL_ENDL;
- return LLModel::BAD_ELEMENT;
- }
- t = &(src->getFloat_array()->getValue());
- }
- }
-
- domP_Array& ps = poly->getP_array();
-
- //make a triangle list in <verts>
- for (U32 i = 0; i < ps.getCount(); ++i)
- { //for each polygon
- domListOfUInts& idx = ps[i]->getValue();
- for (U32 j = 0; j < idx.getCount()/stride; ++j)
- { //for each vertex
- if (j > 2)
- {
- U32 size = verts.size();
- LLVolumeFace::VertexData v0 = verts[size-3];
- LLVolumeFace::VertexData v1 = verts[size-1];
-
- verts.push_back(v0);
- verts.push_back(v1);
- }
-
- LLVolumeFace::VertexData vert;
-
-
- if (v)
- {
- U32 v_idx = idx[j*stride+v_offset]*3;
- v_idx = llclamp(v_idx, (U32) 0, (U32) v->getCount());
- vert.getPosition().set(v->get(v_idx),
- v->get(v_idx+1),
- v->get(v_idx+2));
-
- if (!vert.getPosition().isFinite3())
- {
- LL_WARNS() << "Found NaN while loading position data from DAE-Model, invalid model." << LL_ENDL;
- return LLModel::BAD_ELEMENT;
- }
- }
-
- //bounds check n and t lookups because some FBX to DAE converters
- //use negative indices and empty arrays to indicate data does not exist
- //for a particular channel
- if (n && n->getCount() > 0)
- {
- U32 n_idx = idx[j*stride+n_offset]*3;
- n_idx = llclamp(n_idx, (U32) 0, (U32) n->getCount());
- vert.getNormal().set(n->get(n_idx),
- n->get(n_idx+1),
- n->get(n_idx+2));
-
- if (!vert.getNormal().isFinite3())
- {
- LL_WARNS() << "Found NaN while loading normals from DAE-Model, invalid model." << LL_ENDL;
- return LLModel::BAD_ELEMENT;
- }
- }
- else
- {
- vert.getNormal().clear();
- }
-
-
- if (t && t->getCount() > 0)
- {
- U32 t_idx = idx[j*stride+t_offset]*2;
- t_idx = llclamp(t_idx, (U32) 0, (U32) t->getCount());
- vert.mTexCoord.setVec(t->get(t_idx),
- t->get(t_idx+1));
-
- if (!vert.mTexCoord.isFinite())
- {
- LL_WARNS() << "Found NaN while loading tex coords from DAE-Model, invalid model." << LL_ENDL;
- return LLModel::BAD_ELEMENT;
- }
- }
- else
- {
- vert.mTexCoord.clear();
- }
-
-
- verts.push_back(vert);
- }
- }
-
- if (verts.empty())
- {
- return LLModel::NO_ERRORS;
- }
-
- face.mExtents[0] = verts[0].getPosition();
- face.mExtents[1] = verts[0].getPosition();
-
- //create a map of unique vertices to indices
- std::map<LLVolumeFace::VertexData, U32> vert_idx;
-
- U32 cur_idx = 0;
- for (U32 i = 0; i < verts.size(); ++i)
- {
- std::map<LLVolumeFace::VertexData, U32>::iterator iter = vert_idx.find(verts[i]);
- if (iter == vert_idx.end())
- {
- vert_idx[verts[i]] = cur_idx++;
- }
- }
-
- //build vertex array from map
- std::vector<LLVolumeFace::VertexData> new_verts;
- new_verts.resize(vert_idx.size());
-
- for (std::map<LLVolumeFace::VertexData, U32>::iterator iter = vert_idx.begin(); iter != vert_idx.end(); ++iter)
- {
- new_verts[iter->second] = iter->first;
- update_min_max(face.mExtents[0], face.mExtents[1], iter->first.getPosition());
- }
-
- //build index array from map
- indices.resize(verts.size());
-
- for (U32 i = 0; i < verts.size(); ++i)
- {
- indices[i] = vert_idx[verts[i]];
- }
-
- // DEBUG just build an expanded triangle list
- /*for (U32 i = 0; i < verts.size(); ++i)
- {
- indices.push_back((U16) i);
- update_min_max(face.mExtents[0], face.mExtents[1], verts[i].getPosition());
- }*/
-
- if (!new_verts.empty())
- {
- std::string material;
-
- if (poly->getMaterial())
- {
- material = std::string(poly->getMaterial());
- }
-
- materials.push_back(material);
- face_list.push_back(face);
- face_list.rbegin()->fillFromLegacyData(new_verts, indices);
-
- LLVolumeFace& new_face = *face_list.rbegin();
- if (!n)
- {
- //ll_aligned_free_16(new_face.mNormals);
- new_face.mNormals = NULL;
- }
-
- if (!t)
- {
- //ll_aligned_free_16(new_face.mTexCoords);
- new_face.mTexCoords = NULL;
- }
- }
-
- return LLModel::NO_ERRORS ;
-}
+ int index;
+ std::string matName;
+};
-//static
-std::string LLModel::getStatusString(U32 status)
+struct MaterialSort
{
- const static std::string status_strings[(S32)INVALID_STATUS] = {"status_no_error", "status_vertex_number_overflow","bad_element"};
-
- if(status < INVALID_STATUS)
+ bool operator()(const MaterialBinding& lhs, const MaterialBinding& rhs)
{
- if(status_strings[status] == std::string())
- {
- LL_ERRS() << "No valid status string for this status: " << (U32)status << LL_ENDL ;
- }
- return status_strings[status] ;
+ return LLStringUtil::compareInsensitive(lhs.matName, rhs.matName) < 0;
}
+};
- LL_ERRS() << "Invalid model status: " << (U32)status << LL_ENDL ;
-
- return std::string() ;
-}
-
-void LLModel::addVolumeFacesFromDomMesh(domMesh* mesh)
+void LLModel::sortVolumeFacesByMaterialName()
{
- domTriangles_Array& tris = mesh->getTriangles_array();
-
- for (U32 i = 0; i < tris.getCount(); ++i)
- {
- domTrianglesRef& tri = tris.get(i);
+ std::vector<MaterialBinding> bindings;
+ bindings.resize(mVolumeFaces.size());
- mStatus = load_face_from_dom_triangles(mVolumeFaces, mMaterialList, tri);
-
- if(mStatus != NO_ERRORS)
+ for (int i = 0; i < bindings.size(); i++)
+ {
+ bindings[i].index = i;
+ if(i < mMaterialList.size())
{
- mVolumeFaces.clear() ;
- mMaterialList.clear() ;
- return ; //abort
+ bindings[i].matName = mMaterialList[i];
}
}
+ std::sort(bindings.begin(), bindings.end(), MaterialSort());
+ std::vector< LLVolumeFace > new_faces;
- domPolylist_Array& polys = mesh->getPolylist_array();
- for (U32 i = 0; i < polys.getCount(); ++i)
+ // remap the faces to be in the same order the mats now are...
+ //
+ new_faces.resize(bindings.size());
+ for (int i = 0; i < bindings.size(); i++)
{
- domPolylistRef& poly = polys.get(i);
- mStatus = load_face_from_dom_polylist(mVolumeFaces, mMaterialList, poly);
-
- if(mStatus != NO_ERRORS)
+ new_faces[i] = mVolumeFaces[bindings[i].index];
+ if(i < mMaterialList.size())
{
- mVolumeFaces.clear() ;
- mMaterialList.clear() ;
- return ; //abort
+ mMaterialList[i] = bindings[i].matName;
}
}
-
- domPolygons_Array& polygons = mesh->getPolygons_array();
-
- for (U32 i = 0; i < polygons.getCount(); ++i)
- {
- domPolygonsRef& poly = polygons.get(i);
- mStatus = load_face_from_dom_polygons(mVolumeFaces, mMaterialList, poly);
- if(mStatus != NO_ERRORS)
- {
- mVolumeFaces.clear() ;
- mMaterialList.clear() ;
- return ; //abort
- }
- }
-
+ mVolumeFaces = new_faces;
}
-BOOL LLModel::createVolumeFacesFromDomMesh(domMesh* mesh)
+void LLModel::trimVolumeFacesToSize(U32 new_count, LLVolume::face_list_t* remainder)
{
- if (mesh)
- {
- mVolumeFaces.clear();
- mMaterialList.clear();
-
- addVolumeFacesFromDomMesh(mesh);
-
- if (getNumVolumeFaces() > 0)
- {
- normalizeVolumeFaces();
- optimizeVolumeFaces();
-
- if (getNumVolumeFaces() > 0)
- {
- return TRUE;
- }
- }
- }
- else
- {
- LL_WARNS() << "no mesh found" << LL_ENDL;
- }
-
- return FALSE;
-}
+ llassert(new_count <= LL_SCULPT_MESH_MAX_FACES);
-void LLModel::offsetMesh( const LLVector3& pivotPoint )
-{
- LLVector4a pivot( pivotPoint[VX], pivotPoint[VY], pivotPoint[VZ] );
-
- for (std::vector<LLVolumeFace>::iterator faceIt = mVolumeFaces.begin(); faceIt != mVolumeFaces.end(); )
+ if (new_count && (getNumVolumeFaces() > new_count))
{
- std::vector<LLVolumeFace>:: iterator currentFaceIt = faceIt++;
- LLVolumeFace& face = *currentFaceIt;
- LLVector4a *pos = (LLVector4a*) face.mPositions;
-
- for (U32 i=0; i<face.mNumVertices; ++i )
+ // Copy out remaining volume faces for alternative handling, if provided
+ //
+ if (remainder)
{
- pos[i].add( pivot );
- }
- }
-}
+ (*remainder).assign(mVolumeFaces.begin() + new_count, mVolumeFaces.end());
+ }
-void LLModel::optimizeVolumeFaces()
-{
- for (U32 i = 0; i < getNumVolumeFaces(); ++i)
- {
- mVolumeFaces[i].optimize();
+ // Trim down to the final set of volume faces (now stuffed to the gills!)
+ //
+ mVolumeFaces.resize(new_count);
}
}
@@ -1025,11 +184,6 @@ void LLModel::optimizeVolumeFaces()
// within the unit cube.
void LLModel::normalizeVolumeFaces()
{
-
- // ensure we don't have too many faces
- if (mVolumeFaces.size() > LL_SCULPT_MESH_MAX_FACES)
- mVolumeFaces.resize(LL_SCULPT_MESH_MAX_FACES);
-
if (!mVolumeFaces.empty())
{
LLVector4a min, max;
@@ -1496,68 +650,10 @@ void LLModel::generateNormals(F32 angle_cutoff)
}
}
-//static
-std::string LLModel::getElementLabel(daeElement *element)
-{ // try to get a decent label for this element
- // if we have a name attribute, use it
- std::string name = element->getAttribute("name");
- if (name.length())
- {
- return name;
- }
-
- // if we have an ID attribute, use it
- if (element->getID())
- {
- return std::string(element->getID());
- }
-
- // if we have a parent, use it
- daeElement* parent = element->getParent();
- if (parent)
- {
- // if parent has a name, use it
- std::string name = parent->getAttribute("name");
- if (name.length())
- {
- return name;
- }
-
- // if parent has an ID, use it
- if (parent->getID())
- {
- return std::string(parent->getID());
- }
- }
-
- // try to use our type
- daeString element_name = element->getElementName();
- if (element_name)
- {
- return std::string(element_name);
- }
-
- // if all else fails, use "object"
- return std::string("object");
-}
-
-//static
-LLModel* LLModel::loadModelFromDomMesh(domMesh *mesh)
-{
- LLVolumeParams volume_params;
- volume_params.setType(LL_PCODE_PROFILE_SQUARE, LL_PCODE_PATH_LINE);
- LLModel* ret = new LLModel(volume_params, 0.f);
- ret->createVolumeFacesFromDomMesh(mesh);
- ret->mLabel = getElementLabel(mesh);
- return ret;
-}
std::string LLModel::getName() const
{
- if (!mRequestedLabel.empty())
- return mRequestedLabel;
- else
- return mLabel;
+ return mRequestedLabel.empty() ? mLabel : mRequestedLabel;
}
//static
@@ -1572,7 +668,8 @@ LLSD LLModel::writeModel(
BOOL upload_skin,
BOOL upload_joints,
BOOL nowrite,
- BOOL as_slm)
+ BOOL as_slm,
+ int submodel_id)
{
LLSD mdl;
@@ -1601,6 +698,14 @@ LLSD LLModel::writeModel(
model[LLModel::LOD_PHYSICS] = NULL;
}
}
+ else if (submodel_id)
+ {
+ const LLModel::Decomposition fake_decomp;
+ mdl["secondary"] = true;
+ mdl["submodel_id"] = submodel_id;
+ mdl["physics_convex"] = fake_decomp.asLLSD();
+ model[LLModel::LOD_PHYSICS] = NULL;
+ }
if (as_slm)
{ //save material list names
@@ -1612,7 +717,7 @@ LLSD LLModel::writeModel(
for (U32 idx = 0; idx < MODEL_NAMES_LENGTH; ++idx)
{
- if (model[idx] && model[idx]->getNumVolumeFaces() > 0)
+ if (model[idx] && (model[idx]->getNumVolumeFaces() > 0) && model[idx]->getVolumeFace(0).mPositions != NULL)
{
LLVector3 min_pos = LLVector3(model[idx]->getVolumeFace(0).mPositions[0].getF32ptr());
LLVector3 max_pos = min_pos;
@@ -1762,6 +867,7 @@ LLSD LLModel::writeModel(
S32 count = 0;
for (weight_list::iterator iter = weights.begin(); iter != weights.end(); ++iter)
{
+ // BENTO JOINT COUNT LIMIT 255?
if (iter->mJointIdx < 255 && iter->mJointIdx >= 0)
{
U8 idx = (U8) iter->mJointIdx;
@@ -1845,6 +951,11 @@ LLSD LLModel::writeModelToStream(std::ostream& ostr, LLSD& mdl, BOOL nowrite, BO
}
}
+ if (mdl.has("submodel_id"))
+ { //write out submodel id
+ header["submodel_id"] = (LLSD::Integer)mdl["submodel_id"];
+ }
+
std::string out[MODEL_NAMES_LENGTH];
for (S32 i = 0; i < MODEL_NAMES_LENGTH; i++)
@@ -2028,7 +1139,9 @@ bool LLModel::loadModel(std::istream& is)
}
}
- static const std::string nm[] =
+ mSubmodelID = header.has("submodel_id") ? header["submodel_id"].asInteger() : false;
+
+ static const std::string lod_name[] =
{
"lowest_lod",
"low_lod",
@@ -2041,8 +1154,8 @@ bool LLModel::loadModel(std::istream& is)
S32 lod = llclamp((S32) mDetail, 0, MODEL_LODS);
- if (header[nm[lod]]["offset"].asInteger() == -1 ||
- header[nm[lod]]["size"].asInteger() == 0 )
+ if (header[lod_name[lod]]["offset"].asInteger() == -1 ||
+ header[lod_name[lod]]["size"].asInteger() == 0 )
{ //cannot load requested LOD
LL_WARNS() << "LoD data is invalid!" << LL_ENDL;
return false;
@@ -2051,23 +1164,23 @@ bool LLModel::loadModel(std::istream& is)
bool has_skin = header["skin"]["offset"].asInteger() >=0 &&
header["skin"]["size"].asInteger() > 0;
- if (lod == LLModel::LOD_HIGH)
+ if ((lod == LLModel::LOD_HIGH) && !mSubmodelID)
{ //try to load skin info and decomp info
std::ios::pos_type cur_pos = is.tellg();
loadSkinInfo(header, is);
is.seekg(cur_pos);
}
- if (lod == LLModel::LOD_HIGH || lod == LLModel::LOD_PHYSICS)
+ if ((lod == LLModel::LOD_HIGH || lod == LLModel::LOD_PHYSICS) && !mSubmodelID)
{
std::ios::pos_type cur_pos = is.tellg();
loadDecomposition(header, is);
is.seekg(cur_pos);
}
- is.seekg(header[nm[lod]]["offset"].asInteger(), std::ios_base::cur);
+ is.seekg(header[lod_name[lod]]["offset"].asInteger(), std::ios_base::cur);
- if (unpackVolumeFaces(is, header[nm[lod]]["size"].asInteger()))
+ if (unpackVolumeFaces(is, header[lod_name[lod]]["size"].asInteger()))
{
if (has_skin)
{
@@ -2133,8 +1246,10 @@ bool LLModel::isMaterialListSubset( LLModel* ref )
break;
}
}
+
if (!foundRef)
{
+ LL_INFOS() << "Could not find material " << mMaterialList[src] << " in reference model " << ref->mLabel << LL_ENDL;
return false;
}
}
@@ -2185,41 +1300,42 @@ bool LLModel::matchMaterialOrder(LLModel* ref, int& refFaceCnt, int& modelFaceCn
for (U32 i = 0; i < mMaterialList.size(); i++)
{
index_map[ref->mMaterialList[i]] = i;
- if (!reorder)
- { //if any material name does not match reference, we need to reorder
- reorder = ref->mMaterialList[i] != mMaterialList[i];
- }
+ //if any material name does not match reference, we need to reorder
+ reorder |= ref->mMaterialList[i] != mMaterialList[i];
base_mat.insert(ref->mMaterialList[i]);
cur_mat.insert(mMaterialList[i]);
}
- if (reorder &&
- base_mat == cur_mat) //don't reorder if material name sets don't match
+ if (reorder && (base_mat == cur_mat)) //don't reorder if material name sets don't match
{
std::vector<LLVolumeFace> new_face_list;
- new_face_list.resize(mVolumeFaces.size());
+ new_face_list.resize(mMaterialList.size());
std::vector<std::string> new_material_list;
- new_material_list.resize(mVolumeFaces.size());
+ new_material_list.resize(mMaterialList.size());
//rebuild face list so materials have the same order
//as the reference model
for (U32 i = 0; i < mMaterialList.size(); ++i)
{
U32 ref_idx = index_map[mMaterialList[i]];
- new_face_list[ref_idx] = mVolumeFaces[i];
+ if (i < mVolumeFaces.size())
+ {
+ new_face_list[ref_idx] = mVolumeFaces[i];
+ }
new_material_list[ref_idx] = mMaterialList[i];
}
llassert(new_material_list == ref->mMaterialList);
mVolumeFaces = new_face_list;
- }
- //override material list with reference model ordering
- mMaterialList = ref->mMaterialList;
+ //override material list with reference model ordering
+ mMaterialList = ref->mMaterialList;
+ }
+
return true;
}
@@ -2250,7 +1366,7 @@ bool LLModel::loadDecomposition(LLSD& header, std::istream& is)
S32 offset = header["physics_convex"]["offset"].asInteger();
S32 size = header["physics_convex"]["size"].asInteger();
- if (offset >= 0 && size > 0)
+ if (offset >= 0 && size > 0 && !mSubmodelID)
{
is.seekg(offset, std::ios_base::cur);
@@ -2658,3 +1774,227 @@ void LLModel::Decomposition::merge(const LLModel::Decomposition* rhs)
}
}
+bool ll_is_degenerate(const LLVector4a& a, const LLVector4a& b, const LLVector4a& c, F32 tolerance)
+{
+ // small area check
+ {
+ LLVector4a edge1; edge1.setSub( a, b );
+ LLVector4a edge2; edge2.setSub( a, c );
+ //////////////////////////////////////////////////////////////////////////
+ /// Linden Modified
+ //////////////////////////////////////////////////////////////////////////
+
+ // If no one edge is more than 10x longer than any other edge, we weaken
+ // the tolerance by a factor of 1e-4f.
+
+ LLVector4a edge3; edge3.setSub( c, b );
+ const F32 len1sq = edge1.dot3(edge1).getF32();
+ const F32 len2sq = edge2.dot3(edge2).getF32();
+ const F32 len3sq = edge3.dot3(edge3).getF32();
+ bool abOK = (len1sq <= 100.f * len2sq) && (len1sq <= 100.f * len3sq);
+ bool acOK = (len2sq <= 100.f * len1sq) && (len1sq <= 100.f * len3sq);
+ bool cbOK = (len3sq <= 100.f * len1sq) && (len1sq <= 100.f * len2sq);
+ if ( abOK && acOK && cbOK )
+ {
+ tolerance *= 1e-4f;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ /// End Modified
+ //////////////////////////////////////////////////////////////////////////
+
+ LLVector4a cross; cross.setCross3( edge1, edge2 );
+
+ LLVector4a edge1b; edge1b.setSub( b, a );
+ LLVector4a edge2b; edge2b.setSub( b, c );
+ LLVector4a crossb; crossb.setCross3( edge1b, edge2b );
+
+ if ( ( cross.dot3(cross).getF32() < tolerance ) || ( crossb.dot3(crossb).getF32() < tolerance ))
+ {
+ return true;
+ }
+ }
+
+ // point triangle distance check
+ {
+ LLVector4a Q; Q.setSub(a, b);
+ LLVector4a R; R.setSub(c, b);
+
+ const F32 QQ = dot3fpu(Q, Q);
+ const F32 RR = dot3fpu(R, R);
+ const F32 QR = dot3fpu(R, Q);
+
+ volatile F32 QQRR = QQ * RR;
+ volatile F32 QRQR = QR * QR;
+ F32 Det = (QQRR - QRQR);
+
+ if( Det == 0.0f )
+ {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+bool validate_face(const LLVolumeFace& face)
+{
+ for (U32 i = 0; i < face.mNumIndices; ++i)
+ {
+ if (face.mIndices[i] >= face.mNumVertices)
+ {
+ LL_WARNS() << "Face has invalid index." << LL_ENDL;
+ return false;
+ }
+ }
+
+ if (face.mNumIndices % 3 != 0 || face.mNumIndices == 0)
+ {
+ LL_WARNS() << "Face has invalid number of indices." << LL_ENDL;
+ return false;
+ }
+
+ /*const LLVector4a scale(0.5f);
+
+ for (U32 i = 0; i < face.mNumIndices; i+=3)
+ {
+ U16 idx1 = face.mIndices[i];
+ U16 idx2 = face.mIndices[i+1];
+ U16 idx3 = face.mIndices[i+2];
+
+ LLVector4a v1; v1.setMul(face.mPositions[idx1], scale);
+ LLVector4a v2; v2.setMul(face.mPositions[idx2], scale);
+ LLVector4a v3; v3.setMul(face.mPositions[idx3], scale);
+
+ if (ll_is_degenerate(v1,v2,v3))
+ {
+ llwarns << "Degenerate face found!" << LL_ENDL;
+ return false;
+ }
+ }*/
+
+ return true;
+}
+
+bool validate_model(const LLModel* mdl)
+{
+ if (mdl->getNumVolumeFaces() == 0)
+ {
+ LL_WARNS() << "Model has no faces!" << LL_ENDL;
+ return false;
+ }
+
+ for (S32 i = 0; i < mdl->getNumVolumeFaces(); ++i)
+ {
+ if (mdl->getVolumeFace(i).mNumVertices == 0)
+ {
+ LL_WARNS() << "Face has no vertices." << LL_ENDL;
+ return false;
+ }
+
+ if (mdl->getVolumeFace(i).mNumIndices == 0)
+ {
+ LL_WARNS() << "Face has no indices." << LL_ENDL;
+ return false;
+ }
+
+ if (!validate_face(mdl->getVolumeFace(i)))
+ {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+LLModelInstance::LLModelInstance(LLSD& data)
+ : LLModelInstanceBase()
+{
+ mLocalMeshID = data["mesh_id"].asInteger();
+ mLabel = data["label"].asString();
+ mTransform.setValue(data["transform"]);
+
+ for (U32 i = 0; i < data["material"].size(); ++i)
+ {
+ LLImportMaterial mat(data["material"][i]);
+ mMaterial[mat.mBinding] = mat;
+ }
+}
+
+
+LLSD LLModelInstance::asLLSD()
+{
+ LLSD ret;
+
+ ret["mesh_id"] = mModel->mLocalID;
+ ret["label"] = mLabel;
+ ret["transform"] = mTransform.getValue();
+
+ U32 i = 0;
+ for (std::map<std::string, LLImportMaterial>::iterator iter = mMaterial.begin(); iter != mMaterial.end(); ++iter)
+ {
+ ret["material"][i++] = iter->second.asLLSD();
+ }
+
+ return ret;
+}
+
+
+LLImportMaterial::~LLImportMaterial()
+{
+}
+
+LLImportMaterial::LLImportMaterial(LLSD& data)
+{
+ mDiffuseMapFilename = data["diffuse"]["filename"].asString();
+ mDiffuseMapLabel = data["diffuse"]["label"].asString();
+ mDiffuseColor.setValue(data["diffuse"]["color"]);
+ mFullbright = data["fullbright"].asBoolean();
+ mBinding = data["binding"].asString();
+}
+
+
+LLSD LLImportMaterial::asLLSD()
+{
+ LLSD ret;
+
+ ret["diffuse"]["filename"] = mDiffuseMapFilename;
+ ret["diffuse"]["label"] = mDiffuseMapLabel;
+ ret["diffuse"]["color"] = mDiffuseColor.getValue();
+ ret["fullbright"] = mFullbright;
+ ret["binding"] = mBinding;
+
+ return ret;
+}
+
+bool LLImportMaterial::operator<(const LLImportMaterial &rhs) const
+{
+
+ if (mDiffuseMapID != rhs.mDiffuseMapID)
+ {
+ return mDiffuseMapID < rhs.mDiffuseMapID;
+ }
+
+ if (mDiffuseMapFilename != rhs.mDiffuseMapFilename)
+ {
+ return mDiffuseMapFilename < rhs.mDiffuseMapFilename;
+ }
+
+ if (mDiffuseMapLabel != rhs.mDiffuseMapLabel)
+ {
+ return mDiffuseMapLabel < rhs.mDiffuseMapLabel;
+ }
+
+ if (mDiffuseColor != rhs.mDiffuseColor)
+ {
+ return mDiffuseColor < rhs.mDiffuseColor;
+ }
+
+ if (mBinding != rhs.mBinding)
+ {
+ return mBinding < rhs.mBinding;
+ }
+
+ return mFullbright < rhs.mFullbright;
+}
+
diff --git a/indra/llprimitive/llmodel.h b/indra/llprimitive/llmodel.h
index aaafc55258..ae602c09df 100755
--- a/indra/llprimitive/llmodel.h
+++ b/indra/llprimitive/llmodel.h
@@ -31,6 +31,7 @@
#include "llvolume.h"
#include "v4math.h"
#include "m4math.h"
+#include <queue>
class daeElement;
class domMesh;
@@ -138,15 +139,16 @@ public:
BOOL upload_skin,
BOOL upload_joints,
BOOL nowrite = FALSE,
- BOOL as_slm = FALSE);
+ BOOL as_slm = FALSE,
+ int submodel_id = 0);
static LLSD writeModelToStream(
std::ostream& ostr,
LLSD& mdl,
BOOL nowrite = FALSE, BOOL as_slm = FALSE);
+
+ void ClearFacesAndMaterials() { mVolumeFaces.clear(); mMaterialList.clear(); }
- static LLModel* loadModelFromDomMesh(domMesh* mesh);
- static std::string getElementLabel(daeElement* element);
std::string getName() const;
std::string getMetric() const {return mMetric;}
EModelStatus getStatus() const {return mStatus;}
@@ -169,20 +171,25 @@ public:
void addFace(const LLVolumeFace& face);
+ void sortVolumeFacesByMaterialName();
void normalizeVolumeFaces();
+ void trimVolumeFacesToSize(U32 new_count = LL_SCULPT_MESH_MAX_FACES, LLVolume::face_list_t* remainder = NULL);
void optimizeVolumeFaces();
void offsetMesh( const LLVector3& pivotPoint );
void getNormalizedScaleTranslation(LLVector3& scale_out, LLVector3& translation_out);
LLVector3 getTransformedCenter(const LLMatrix4& mat);
-
+
//reorder face list based on mMaterialList in this and reference so
//order matches that of reference (material ordering touchup)
bool matchMaterialOrder(LLModel* ref, int& refFaceCnt, int& modelFaceCnt );
bool isMaterialListSubset( LLModel* ref );
bool needToAddFaces( LLModel* ref, int& refFaceCnt, int& modelFaceCnt );
-
- std::vector<std::string> mMaterialList;
+ typedef std::vector<std::string> material_list;
+
+ material_list mMaterialList;
+
+ material_list& getMaterialList() { return mMaterialList; }
//data used for skin weights
class JointWeight
@@ -275,9 +282,115 @@ public:
Decomposition mPhysics;
EModelStatus mStatus ;
+
+ int mSubmodelID;
+};
+
+typedef std::vector<LLPointer<LLModel> > model_list;
+typedef std::queue<LLPointer<LLModel> > model_queue;
+
+class LLModelMaterialBase
+{
+public:
+ std::string mDiffuseMapFilename;
+ std::string mDiffuseMapLabel;
+ std::string mBinding;
+ LLColor4 mDiffuseColor;
+ bool mFullbright;
+
+ LLModelMaterialBase()
+ : mFullbright(false)
+ {
+ mDiffuseColor.set(1,1,1,1);
+ }
+};
+
+class LLImportMaterial : public LLModelMaterialBase
+{
+public:
+ friend class LLMeshUploadThread;
+ friend class LLModelPreview;
+
+ bool operator<(const LLImportMaterial &params) const;
+
+ LLImportMaterial() : LLModelMaterialBase()
+ {
+ mDiffuseColor.set(1,1,1,1);
+ }
+
+ LLImportMaterial(LLSD& data);
+ virtual ~LLImportMaterial();
+
+ LLSD asLLSD();
+
+ const LLUUID& getDiffuseMap() const { return mDiffuseMapID; }
+ void setDiffuseMap(const LLUUID& texId) { mDiffuseMapID = texId; }
+
protected:
- void addVolumeFacesFromDomMesh(domMesh* mesh);
- virtual BOOL createVolumeFacesFromDomMesh(domMesh *mesh);
+
+ LLUUID mDiffuseMapID;
+ void* mOpaqueData; // allow refs to viewer/platform-specific structs for each material
+ // currently only stores an LLPointer< LLViewerFetchedTexture > > to
+ // maintain refs to textures associated with each material for free
+ // ref counting.
};
+typedef std::map<std::string, LLImportMaterial> material_map;
+
+class LLModelInstanceBase
+{
+public:
+ LLPointer<LLModel> mModel;
+ LLPointer<LLModel> mLOD[5];
+ LLUUID mMeshID;
+
+ LLMatrix4 mTransform;
+ material_map mMaterial;
+
+ LLModelInstanceBase(LLModel* model, LLMatrix4& transform, material_map& materials)
+ : mModel(model), mTransform(transform), mMaterial(materials)
+ {
+ }
+
+ LLModelInstanceBase()
+ : mModel(NULL)
+ {
+ }
+};
+
+typedef std::vector<LLModelInstanceBase> model_instance_list;
+
+class LLModelInstance : public LLModelInstanceBase
+{
+public:
+ std::string mLabel;
+ LLUUID mMeshID;
+ S32 mLocalMeshID;
+
+ LLModelInstance(LLModel* model, const std::string& label, LLMatrix4& transform, material_map& materials)
+ : LLModelInstanceBase(model, transform, materials), mLabel(label)
+ {
+ mLocalMeshID = -1;
+ }
+
+ LLModelInstance(LLSD& data);
+
+ LLSD asLLSD();
+};
+
+#define LL_DEGENERACY_TOLERANCE 1e-7f
+
+inline F32 dot3fpu(const LLVector4a& a, const LLVector4a& b)
+{
+ volatile F32 p0 = a[0] * b[0];
+ volatile F32 p1 = a[1] * b[1];
+ volatile F32 p2 = a[2] * b[2];
+ return p0 + p1 + p2;
+}
+
+bool ll_is_degenerate(const LLVector4a& a, const LLVector4a& b, const LLVector4a& c, F32 tolerance = LL_DEGENERACY_TOLERANCE);
+
+bool validate_face(const LLVolumeFace& face);
+bool validate_model(const LLModel* mdl);
+
#endif //LL_LLMODEL_H
diff --git a/indra/llprimitive/llmodelloader.cpp b/indra/llprimitive/llmodelloader.cpp
new file mode 100644
index 0000000000..9cf0f10a7e
--- /dev/null
+++ b/indra/llprimitive/llmodelloader.cpp
@@ -0,0 +1,623 @@
+/**
+ * @file llmodelloader.cpp
+ * @brief LLModelLoader class implementation
+ *
+ * $LicenseInfo:firstyear=2004&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$
+ */
+
+#include "llmodelloader.h"
+#include "llsdserialize.h"
+#include "lljoint.h"
+#include "llcallbacklist.h"
+
+#include "glh/glh_linear.h"
+#include "llmatrix4a.h"
+#include <boost/bind.hpp>
+
+std::list<LLModelLoader*> LLModelLoader::sActiveLoaderList;
+
+void stretch_extents(LLModel* model, LLMatrix4a& mat, LLVector4a& min, LLVector4a& max, BOOL& first_transform)
+{
+ LLVector4a box[] =
+ {
+ LLVector4a(-1, 1,-1),
+ LLVector4a(-1, 1, 1),
+ LLVector4a(-1,-1,-1),
+ LLVector4a(-1,-1, 1),
+ LLVector4a( 1, 1,-1),
+ LLVector4a( 1, 1, 1),
+ LLVector4a( 1,-1,-1),
+ LLVector4a( 1,-1, 1),
+ };
+
+ for (S32 j = 0; j < model->getNumVolumeFaces(); ++j)
+ {
+ const LLVolumeFace& face = model->getVolumeFace(j);
+
+ LLVector4a center;
+ center.setAdd(face.mExtents[0], face.mExtents[1]);
+ center.mul(0.5f);
+ LLVector4a size;
+ size.setSub(face.mExtents[1],face.mExtents[0]);
+ size.mul(0.5f);
+
+ for (U32 i = 0; i < 8; i++)
+ {
+ LLVector4a t;
+ t.setMul(size, box[i]);
+ t.add(center);
+
+ LLVector4a v;
+
+ mat.affineTransform(t, v);
+
+ if (first_transform)
+ {
+ first_transform = FALSE;
+ min = max = v;
+ }
+ else
+ {
+ update_min_max(min, max, v);
+ }
+ }
+ }
+}
+
+void stretch_extents(LLModel* model, LLMatrix4& mat, LLVector3& min, LLVector3& max, BOOL& first_transform)
+{
+ LLVector4a mina, maxa;
+ LLMatrix4a mata;
+
+ mata.loadu(mat);
+ mina.load3(min.mV);
+ maxa.load3(max.mV);
+
+ stretch_extents(model, mata, mina, maxa, first_transform);
+
+ min.set(mina.getF32ptr());
+ max.set(maxa.getF32ptr());
+}
+
+//-----------------------------------------------------------------------------
+// LLModelLoader
+//-----------------------------------------------------------------------------
+LLModelLoader::LLModelLoader(
+ std::string filename,
+ S32 lod,
+ load_callback_t load_cb,
+ joint_lookup_func_t joint_lookup_func,
+ texture_load_func_t texture_load_func,
+ state_callback_t state_cb,
+ void* opaque_userdata,
+ JointTransformMap& jointTransformMap,
+ JointNameSet& jointsFromNodes,
+ JointNameSet& legalJointNames)
+: mJointList( jointTransformMap )
+, mJointsFromNode( jointsFromNodes )
+, LLThread("Model Loader")
+, mFilename(filename)
+, mLod(lod)
+, mFirstTransform(TRUE)
+, mNumOfFetchingTextures(0)
+, mLoadCallback(load_cb)
+, mJointLookupFunc(joint_lookup_func)
+, mTextureLoadFunc(texture_load_func)
+, mStateCallback(state_cb)
+, mOpaqueData(opaque_userdata)
+, mNoNormalize(false)
+, mNoOptimize(false)
+, mCacheOnlyHitIfRigged(false)
+{
+ // Recognize all names we've been told are legal.
+ for (JointNameSet::iterator joint_name_it = legalJointNames.begin();
+ joint_name_it != legalJointNames.end(); ++joint_name_it)
+ {
+ const std::string& name = *joint_name_it;
+ mJointMap[name] = name;
+ }
+
+ // Also support various legacy aliases for commonly used joints
+ mJointMap["avatar_mPelvis"] = "mPelvis";
+ mJointMap["avatar_mTorso"] = "mTorso";
+ mJointMap["avatar_mChest"] = "mChest";
+ mJointMap["avatar_mNeck"] = "mNeck";
+ mJointMap["avatar_mHead"] = "mHead";
+ mJointMap["avatar_mSkull"] = "mSkull";
+ mJointMap["avatar_mEyeRight"] = "mEyeRight";
+ mJointMap["avatar_mEyeLeft"] = "mEyeLeft";
+ mJointMap["avatar_mCollarLeft"] = "mCollarLeft";
+ mJointMap["avatar_mShoulderLeft"] = "mShoulderLeft";
+ mJointMap["avatar_mElbowLeft"] = "mElbowLeft";
+ mJointMap["avatar_mWristLeft"] = "mWristLeft";
+ mJointMap["avatar_mCollarRight"] = "mCollarRight";
+ mJointMap["avatar_mShoulderRight"] = "mShoulderRight";
+ mJointMap["avatar_mElbowRight"] = "mElbowRight";
+ mJointMap["avatar_mWristRight"] = "mWristRight";
+ mJointMap["avatar_mHipRight"] = "mHipRight";
+ mJointMap["avatar_mKneeRight"] = "mKneeRight";
+ mJointMap["avatar_mAnkleRight"] = "mAnkleRight";
+ mJointMap["avatar_mFootRight"] = "mFootRight";
+ mJointMap["avatar_mToeRight"] = "mToeRight";
+ mJointMap["avatar_mHipLeft"] = "mHipLeft";
+ mJointMap["avatar_mKneeLeft"] = "mKneeLeft";
+ mJointMap["avatar_mAnkleLeft"] = "mAnkleLeft";
+ mJointMap["avatar_mFootLeft"] = "mFootLeft";
+ mJointMap["avatar_mToeLeft"] = "mToeLeft";
+
+
+ mJointMap["hip"] = "mPelvis";
+ mJointMap["abdomen"] = "mTorso";
+ mJointMap["chest"] = "mChest";
+ mJointMap["neck"] = "mNeck";
+ mJointMap["head"] = "mHead";
+ mJointMap["figureHair"] = "mSkull";
+ mJointMap["lCollar"] = "mCollarLeft";
+ mJointMap["lShldr"] = "mShoulderLeft";
+ mJointMap["lForeArm"] = "mElbowLeft";
+ mJointMap["lHand"] = "mWristLeft";
+ mJointMap["rCollar"] = "mCollarRight";
+ mJointMap["rShldr"] = "mShoulderRight";
+ mJointMap["rForeArm"] = "mElbowRight";
+ mJointMap["rHand"] = "mWristRight";
+ mJointMap["rThigh"] = "mHipRight";
+ mJointMap["rShin"] = "mKneeRight";
+ mJointMap["rFoot"] = "mFootRight";
+ mJointMap["lThigh"] = "mHipLeft";
+ mJointMap["lShin"] = "mKneeLeft";
+ mJointMap["lFoot"] = "mFootLeft";
+
+ //move into joint mapper class
+ //1. joints for joint offset verification
+ mMasterJointList.push_front("mPelvis");
+ mMasterJointList.push_front("mTorso");
+ mMasterJointList.push_front("mChest");
+ mMasterJointList.push_front("mNeck");
+ mMasterJointList.push_front("mHead");
+ mMasterJointList.push_front("mCollarLeft");
+ mMasterJointList.push_front("mShoulderLeft");
+ mMasterJointList.push_front("mElbowLeft");
+ mMasterJointList.push_front("mWristLeft");
+ mMasterJointList.push_front("mCollarRight");
+ mMasterJointList.push_front("mShoulderRight");
+ mMasterJointList.push_front("mElbowRight");
+ mMasterJointList.push_front("mWristRight");
+ mMasterJointList.push_front("mHipRight");
+ mMasterJointList.push_front("mKneeRight");
+ mMasterJointList.push_front("mFootRight");
+ mMasterJointList.push_front("mHipLeft");
+ mMasterJointList.push_front("mKneeLeft");
+ mMasterJointList.push_front("mFootLeft");
+
+ //2. legacy joint list - used to verify rigs that will not be using joint offsets
+ mMasterLegacyJointList.push_front("mPelvis");
+ mMasterLegacyJointList.push_front("mTorso");
+ mMasterLegacyJointList.push_front("mChest");
+ mMasterLegacyJointList.push_front("mNeck");
+ mMasterLegacyJointList.push_front("mHead");
+ mMasterLegacyJointList.push_front("mHipRight");
+ mMasterLegacyJointList.push_front("mKneeRight");
+ mMasterLegacyJointList.push_front("mFootRight");
+ mMasterLegacyJointList.push_front("mHipLeft");
+ mMasterLegacyJointList.push_front("mKneeLeft");
+ mMasterLegacyJointList.push_front("mFootLeft");
+
+ assert_main_thread();
+ sActiveLoaderList.push_back(this) ;
+}
+
+LLModelLoader::~LLModelLoader()
+{
+ assert_main_thread();
+ sActiveLoaderList.remove(this);
+}
+
+void LLModelLoader::run()
+{
+ doLoadModel();
+ doOnIdleOneTime(boost::bind(&LLModelLoader::loadModelCallback,this));
+}
+
+bool LLModelLoader::doLoadModel()
+{
+ //first, look for a .slm file of the same name that was modified later
+ //than the .dae
+
+ if (mTrySLM)
+ {
+ std::string filename = mFilename;
+
+ std::string::size_type i = filename.rfind(".");
+ if (i != std::string::npos)
+ {
+ filename.replace(i, filename.size()-1, ".slm");
+ llstat slm_status;
+ if (LLFile::stat(filename, &slm_status) == 0)
+ { //slm file exists
+ llstat dae_status;
+ if (LLFile::stat(mFilename, &dae_status) != 0 ||
+ dae_status.st_mtime < slm_status.st_mtime)
+ {
+ if (loadFromSLM(filename))
+ { //slm successfully loaded, if this fails, fall through and
+ //try loading from dae
+
+ mLod = -1; //successfully loading from an slm implicitly sets all
+ //LoDs
+ return true;
+ }
+ }
+ }
+ }
+ }
+
+ return OpenFile(mFilename);
+}
+
+void LLModelLoader::setLoadState(U32 state)
+{
+ mStateCallback(state, mOpaqueData);
+}
+
+bool LLModelLoader::loadFromSLM(const std::string& filename)
+{
+ //only need to populate mScene with data from slm
+ llstat stat;
+
+ if (LLFile::stat(filename, &stat))
+ { //file does not exist
+ return false;
+ }
+
+ S32 file_size = (S32) stat.st_size;
+
+ llifstream ifstream(filename.c_str(), std::ifstream::in | std::ifstream::binary);
+ LLSD data;
+ LLSDSerialize::fromBinary(data, ifstream, file_size);
+ ifstream.close();
+
+ //build model list for each LoD
+ model_list model[LLModel::NUM_LODS];
+
+ if (data["version"].asInteger() != SLM_SUPPORTED_VERSION)
+ { //unsupported version
+ return false;
+ }
+
+ LLSD& mesh = data["mesh"];
+
+ LLVolumeParams volume_params;
+ volume_params.setType(LL_PCODE_PROFILE_SQUARE, LL_PCODE_PATH_LINE);
+
+ for (S32 lod = 0; lod < LLModel::NUM_LODS; ++lod)
+ {
+ for (U32 i = 0; i < mesh.size(); ++i)
+ {
+ std::stringstream str(mesh[i].asString());
+ LLPointer<LLModel> loaded_model = new LLModel(volume_params, (F32) lod);
+ if (loaded_model->loadModel(str))
+ {
+ loaded_model->mLocalID = i;
+ model[lod].push_back(loaded_model);
+
+ if (lod == LLModel::LOD_HIGH)
+ {
+ if (!loaded_model->mSkinInfo.mJointNames.empty())
+ {
+ //check to see if rig is valid
+ critiqueRigForUploadApplicability( loaded_model->mSkinInfo.mJointNames );
+ }
+ else if (mCacheOnlyHitIfRigged)
+ {
+ return false;
+ }
+ }
+ }
+ }
+ }
+
+ if (model[LLModel::LOD_HIGH].empty())
+ { //failed to load high lod
+ return false;
+ }
+
+ //load instance list
+ model_instance_list instance_list;
+
+ LLSD& instance = data["instance"];
+
+ for (U32 i = 0; i < instance.size(); ++i)
+ {
+ //deserialize instance list
+ instance_list.push_back(LLModelInstance(instance[i]));
+
+ //match up model instance pointers
+ S32 idx = instance_list[i].mLocalMeshID;
+ std::string instance_label = instance_list[i].mLabel;
+
+ for (U32 lod = 0; lod < LLModel::NUM_LODS; ++lod)
+ {
+ if (!model[lod].empty())
+ {
+ if (idx >= model[lod].size())
+ {
+ if (model[lod].size())
+ {
+ instance_list[i].mLOD[lod] = model[lod][0];
+ }
+ else
+ {
+ instance_list[i].mLOD[lod] = NULL;
+ }
+ continue;
+ }
+
+ if (model[lod][idx]
+ && model[lod][idx]->mLabel.empty()
+ && !instance_label.empty())
+ {
+ // restore model names
+ std::string name = instance_label;
+ switch (lod)
+ {
+ case LLModel::LOD_IMPOSTOR: name += "_LOD0"; break;
+ case LLModel::LOD_LOW: name += "_LOD1"; break;
+ case LLModel::LOD_MEDIUM: name += "_LOD2"; break;
+ case LLModel::LOD_PHYSICS: name += "_PHYS"; break;
+ case LLModel::LOD_HIGH: break;
+ }
+ model[lod][idx]->mLabel = name;
+ }
+
+ instance_list[i].mLOD[lod] = model[lod][idx];
+ }
+ }
+
+ if (!instance_list[i].mModel)
+ instance_list[i].mModel = model[LLModel::LOD_HIGH][idx];
+ }
+
+ // Set name for UI to use
+ std::string name = data["name"];
+ if (!name.empty())
+ {
+ model[LLModel::LOD_HIGH][0]->mRequestedLabel = name;
+ }
+
+
+ //convert instance_list to mScene
+ mFirstTransform = TRUE;
+ for (U32 i = 0; i < instance_list.size(); ++i)
+ {
+ LLModelInstance& cur_instance = instance_list[i];
+ mScene[cur_instance.mTransform].push_back(cur_instance);
+ stretch_extents(cur_instance.mModel, cur_instance.mTransform, mExtents[0], mExtents[1], mFirstTransform);
+ }
+
+ setLoadState( DONE );
+
+ return true;
+}
+
+//static
+bool LLModelLoader::isAlive(LLModelLoader* loader)
+{
+ if(!loader)
+ {
+ return false ;
+ }
+
+ std::list<LLModelLoader*>::iterator iter = sActiveLoaderList.begin() ;
+ for(; iter != sActiveLoaderList.end() && (*iter) != loader; ++iter) ;
+
+ return *iter == loader ;
+}
+
+void LLModelLoader::loadModelCallback()
+{
+ mLoadCallback(mScene,mModelList,mLod, mOpaqueData);
+
+ while (!isStopped())
+ { //wait until this thread is stopped before deleting self
+ apr_sleep(100);
+ }
+
+ //double check if "this" is valid before deleting it, in case it is aborted during running.
+ if(!isAlive(this))
+ {
+ return ;
+ }
+
+ delete this;
+}
+
+//-----------------------------------------------------------------------------
+// critiqueRigForUploadApplicability()
+//-----------------------------------------------------------------------------
+void LLModelLoader::critiqueRigForUploadApplicability( const std::vector<std::string> &jointListFromAsset )
+{
+ critiqueJointToNodeMappingFromScene();
+
+ //Determines the following use cases for a rig:
+ //1. It is suitable for upload with skin weights & joint positions, or
+ //2. It is suitable for upload as standard av with just skin weights
+
+ bool isJointPositionUploadOK = isRigSuitableForJointPositionUpload( jointListFromAsset );
+ bool isRigLegacyOK = isRigLegacy( jointListFromAsset );
+
+ //It's OK that both could end up being true, both default to false
+ if ( isJointPositionUploadOK )
+ {
+ setRigValidForJointPositionUpload( true );
+ }
+
+ if ( isRigLegacyOK)
+ {
+ setLegacyRigValid( true );
+ }
+
+}
+//-----------------------------------------------------------------------------
+// critiqueJointToNodeMappingFromScene()
+//-----------------------------------------------------------------------------
+void LLModelLoader::critiqueJointToNodeMappingFromScene( void )
+{
+ //Do the actual nodes back the joint listing from the dae?
+ //if yes then this is a fully rigged asset, otherwise it's just a partial rig
+
+ JointNameSet::iterator jointsFromNodeIt = mJointsFromNode.begin();
+ JointNameSet::iterator jointsFromNodeEndIt = mJointsFromNode.end();
+ bool result = true;
+
+ if ( !mJointsFromNode.empty() )
+ {
+ for ( ;jointsFromNodeIt!=jointsFromNodeEndIt;++jointsFromNodeIt )
+ {
+ std::string name = *jointsFromNodeIt;
+ if ( mJointTransformMap.find( name ) != mJointTransformMap.end() )
+ {
+ continue;
+ }
+ else
+ {
+ LL_INFOS() <<"critiqueJointToNodeMappingFromScene is missing a: " << name << LL_ENDL;
+ result = false;
+ }
+ }
+ }
+ else
+ {
+ result = false;
+ }
+
+ //Determines the following use cases for a rig:
+ //1. Full av rig w/1-1 mapping from the scene and joint array
+ //2. Partial rig but w/o parity between the scene and joint array
+ if ( result )
+ {
+ setRigWithSceneParity( true );
+ }
+}
+//-----------------------------------------------------------------------------
+// isRigLegacy()
+//-----------------------------------------------------------------------------
+bool LLModelLoader::isRigLegacy( const std::vector<std::string> &jointListFromAsset )
+{
+ //No joints in asset
+ if ( jointListFromAsset.size() == 0 )
+ {
+ return false;
+ }
+
+ bool result = false;
+
+ JointNameSet :: const_iterator masterJointIt = mMasterLegacyJointList.begin();
+ JointNameSet :: const_iterator masterJointEndIt = mMasterLegacyJointList.end();
+
+ std::vector<std::string> :: const_iterator modelJointIt = jointListFromAsset.begin();
+ std::vector<std::string> :: const_iterator modelJointItEnd = jointListFromAsset.end();
+
+ for ( ;masterJointIt!=masterJointEndIt;++masterJointIt )
+ {
+ result = false;
+ modelJointIt = jointListFromAsset.begin();
+
+ for ( ;modelJointIt!=modelJointItEnd; ++modelJointIt )
+ {
+ if ( *masterJointIt == *modelJointIt )
+ {
+ result = true;
+ break;
+ }
+ }
+ if ( !result )
+ {
+ LL_INFOS() <<" Asset did not contain the joint (if you're u/l a fully rigged asset w/joint positions - it is required)." << *masterJointIt<< LL_ENDL;
+ break;
+ }
+ }
+ return result;
+}
+//-----------------------------------------------------------------------------
+// isRigSuitableForJointPositionUpload()
+//-----------------------------------------------------------------------------
+bool LLModelLoader::isRigSuitableForJointPositionUpload( const std::vector<std::string> &jointListFromAsset )
+{
+ bool result = false;
+
+ JointNameSet :: const_iterator masterJointIt = mMasterJointList.begin();
+ JointNameSet :: const_iterator masterJointEndIt = mMasterJointList.end();
+
+ std::vector<std::string> :: const_iterator modelJointIt = jointListFromAsset.begin();
+ std::vector<std::string> :: const_iterator modelJointItEnd = jointListFromAsset.end();
+
+ for ( ;masterJointIt!=masterJointEndIt;++masterJointIt )
+ {
+ result = false;
+ modelJointIt = jointListFromAsset.begin();
+
+ for ( ;modelJointIt!=modelJointItEnd; ++modelJointIt )
+ {
+ if ( *masterJointIt == *modelJointIt )
+ {
+ result = true;
+ break;
+ }
+ }
+ if ( !result )
+ {
+ LL_INFOS() <<" Asset did not contain the joint (if you're u/l a fully rigged asset w/joint positions - it is required)." << *masterJointIt<< LL_ENDL;
+ break;
+ }
+ }
+ return result;
+}
+
+
+//called in the main thread
+void LLModelLoader::loadTextures()
+{
+ BOOL is_paused = isPaused() ;
+ pause() ; //pause the loader
+
+ for(scene::iterator iter = mScene.begin(); iter != mScene.end(); ++iter)
+ {
+ for(U32 i = 0 ; i < iter->second.size(); i++)
+ {
+ for(std::map<std::string, LLImportMaterial>::iterator j = iter->second[i].mMaterial.begin();
+ j != iter->second[i].mMaterial.end(); ++j)
+ {
+ LLImportMaterial& material = j->second;
+
+ if(!material.mDiffuseMapFilename.empty())
+ {
+ mNumOfFetchingTextures += mTextureLoadFunc(material, mOpaqueData);
+ }
+ }
+ }
+ }
+
+ if(!is_paused)
+ {
+ unpause() ;
+ }
+}
diff --git a/indra/llprimitive/llmodelloader.h b/indra/llprimitive/llmodelloader.h
new file mode 100644
index 0000000000..894de2c76f
--- /dev/null
+++ b/indra/llprimitive/llmodelloader.h
@@ -0,0 +1,213 @@
+/**
+ * @file llmodelloader.h
+ * @brief LLModelLoader class definition
+ *
+ * $LicenseInfo:firstyear=2004&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_LLMODELLOADER_H
+#define LL_LLMODELLOADER_H
+
+#include "llmodel.h"
+#include "llthread.h"
+#include <boost/function.hpp>
+#include <list>
+
+class LLJoint;
+
+typedef std::map<std::string, LLMatrix4> JointTransformMap;
+typedef std::map<std::string, LLMatrix4>::iterator JointTransformMapIt;
+typedef std::map<std::string, std::string> JointMap;
+typedef std::deque<std::string> JointNameSet;
+
+const S32 SLM_SUPPORTED_VERSION = 3;
+const S32 NUM_LOD = 4;
+
+class LLModelLoader : public LLThread
+{
+public:
+
+ typedef std::map<std::string, LLImportMaterial> material_map;
+ typedef std::vector<LLPointer<LLModel > > model_list;
+ typedef std::vector<LLModelInstance> model_instance_list;
+ typedef std::map<LLMatrix4, model_instance_list > scene;
+
+ // Callback with loaded model data and loaded LoD
+ //
+ typedef boost::function<void (scene&,model_list&,S32,void*) > load_callback_t;
+
+ // Function to provide joint lookup by name
+ // (within preview avi skeleton, for example)
+ //
+ typedef boost::function<LLJoint* (const std::string&,void*) > joint_lookup_func_t;
+
+ // Func to load and associate material with all it's textures,
+ // returned value is the number of textures loaded
+ // intentionally non-const so func can modify material to
+ // store platform-specific data
+ //
+ typedef boost::function<U32 (LLImportMaterial&,void*) > texture_load_func_t;
+
+ // Callback to inform client of state changes
+ // during loading process (errors will be reported
+ // as state changes here as well)
+ //
+ typedef boost::function<void (U32,void*) > state_callback_t;
+
+ typedef enum
+ {
+ STARTING = 0,
+ READING_FILE,
+ CREATING_FACES,
+ GENERATING_VERTEX_BUFFERS,
+ GENERATING_LOD,
+ DONE,
+ ERROR_PARSING, //basically loading failed
+ ERROR_MATERIALS,
+ ERROR_PASSWORD_REQUIRED,
+ ERROR_NEED_MORE_MEMORY,
+ ERROR_INVALID_FILE,
+ ERROR_LOADER_SETUP,
+ ERROR_INVALID_PARAMETERS,
+ ERROR_OUT_OF_RANGE,
+ ERROR_FILE_VERSION_INVALID,
+ ERROR_MODEL // this error should always be last in this list, error code is passed as ERROR_MODEL+error_code
+ } eLoadState;
+
+ U32 mState;
+ std::string mFilename;
+
+ S32 mLod;
+
+ LLMatrix4 mTransform;
+ BOOL mFirstTransform;
+ LLVector3 mExtents[2];
+
+ bool mTrySLM;
+ bool mCacheOnlyHitIfRigged; // ignore cached SLM if it does not contain rig info (and we want rig info)
+
+ model_list mModelList;
+ scene mScene;
+
+ typedef std::queue<LLPointer<LLModel> > model_queue;
+
+ //queue of models that need a physics rep
+ model_queue mPhysicsQ;
+
+ //map of avatar joints as named in COLLADA assets to internal joint names
+ JointMap mJointMap;
+ JointTransformMap& mJointList;
+ JointNameSet& mJointsFromNode;
+
+ LLModelLoader(
+ std::string filename,
+ S32 lod,
+ LLModelLoader::load_callback_t load_cb,
+ LLModelLoader::joint_lookup_func_t joint_lookup_func,
+ LLModelLoader::texture_load_func_t texture_load_func,
+ LLModelLoader::state_callback_t state_cb,
+ void* opaque_userdata,
+ JointTransformMap& jointTransformMap,
+ JointNameSet& jointsFromNodes,
+ JointNameSet& legalJointNames);
+ virtual ~LLModelLoader() ;
+
+ virtual void setNoNormalize() { mNoNormalize = true; }
+ virtual void setNoOptimize() { mNoOptimize = true; }
+
+ virtual void run();
+
+ // Will try SLM or derived class OpenFile as appropriate
+ //
+ virtual bool doLoadModel();
+
+ // Derived classes need to provide their parsing of files here
+ //
+ virtual bool OpenFile(const std::string& filename) = 0;
+
+ bool loadFromSLM(const std::string& filename);
+
+ void loadModelCallback();
+ void loadTextures() ; //called in the main thread.
+ void setLoadState(U32 state);
+
+
+
+ S32 mNumOfFetchingTextures ; //updated in the main thread
+ bool areTexturesReady() { return !mNumOfFetchingTextures; } //called in the main thread.
+
+ bool verifyCount( int expected, int result );
+
+ //Determines the viability of an asset to be used as an avatar rig (w or w/o joint upload caps)
+ void critiqueRigForUploadApplicability( const std::vector<std::string> &jointListFromAsset );
+ void critiqueJointToNodeMappingFromScene( void );
+
+ //Determines if a rig is a legacy from the joint list
+ bool isRigLegacy( const std::vector<std::string> &jointListFromAsset );
+
+ //Determines if a rig is suitable for upload
+ bool isRigSuitableForJointPositionUpload( const std::vector<std::string> &jointListFromAsset );
+
+ void setRigWithSceneParity( bool state ) { mRigParityWithScene = state; }
+ const bool getRigWithSceneParity( void ) const { return mRigParityWithScene; }
+
+ const bool isRigValidForJointPositionUpload( void ) const { return mRigValidJointUpload; }
+ void setRigValidForJointPositionUpload( bool rigValid ) { mRigValidJointUpload = rigValid; }
+
+ const bool isLegacyRigValid( void ) const { return mLegacyRigValid; }
+ void setLegacyRigValid( bool rigValid ) { mLegacyRigValid = rigValid; }
+
+ //-----------------------------------------------------------------------------
+ // isNodeAJoint()
+ //-----------------------------------------------------------------------------
+ bool isNodeAJoint(const char* name)
+ {
+ return mJointMap.find(name) != mJointMap.end();
+ }
+
+protected:
+
+ LLModelLoader::load_callback_t mLoadCallback;
+ LLModelLoader::joint_lookup_func_t mJointLookupFunc;
+ LLModelLoader::texture_load_func_t mTextureLoadFunc;
+ LLModelLoader::state_callback_t mStateCallback;
+ void* mOpaqueData;
+
+ bool mRigParityWithScene;
+ bool mRigValidJointUpload;
+ bool mLegacyRigValid;
+
+ bool mNoNormalize;
+ bool mNoOptimize;
+
+ JointNameSet mMasterJointList;
+ JointNameSet mMasterLegacyJointList;
+ JointTransformMap mJointTransformMap;
+
+ static std::list<LLModelLoader*> sActiveLoaderList;
+ static bool isAlive(LLModelLoader* loader) ;
+};
+class LLMatrix4a;
+void stretch_extents(LLModel* model, LLMatrix4a& mat, LLVector4a& min, LLVector4a& max, BOOL& first_transform);
+void stretch_extents(LLModel* model, LLMatrix4& mat, LLVector3& min, LLVector3& max, BOOL& first_transform);
+
+#endif // LL_LLMODELLOADER_H
diff --git a/indra/llprimitive/lltextureentry.h b/indra/llprimitive/lltextureentry.h
index 19edcaa27d..a40c3988f2 100755
--- a/indra/llprimitive/lltextureentry.h
+++ b/indra/llprimitive/lltextureentry.h
@@ -89,6 +89,10 @@ public:
bool operator==(const LLTextureEntry &rhs) const;
bool operator!=(const LLTextureEntry &rhs) const;
+
+ // Added to allow use with std::map
+ //
+ bool operator <(const LLTextureEntry &rhs) const;
LLSD asLLSD() const;
void asLLSD(LLSD& sd) const;
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 536c7740bb..16877c345e 100755
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -140,7 +140,6 @@ set(viewer_SOURCE_FILES
llbreadcrumbview.cpp
llbrowsernotification.cpp
llbuycurrencyhtml.cpp
- llcallbacklist.cpp
llcallingcard.cpp
llcapabilitylistener.cpp
llcaphttpsender.cpp
@@ -756,7 +755,6 @@ set(viewer_HEADER_FILES
llbox.h
llbreadcrumbview.h
llbuycurrencyhtml.h
- llcallbacklist.h
llcallingcard.h
llcapabilitylistener.h
llcapabilityprovider.h
diff --git a/indra/newview/VIEWER_VERSION.txt b/indra/newview/VIEWER_VERSION.txt
index ff313b8c21..0cbfaed0d9 100644
--- a/indra/newview/VIEWER_VERSION.txt
+++ b/indra/newview/VIEWER_VERSION.txt
@@ -1 +1 @@
-3.8.4
+3.8.5
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 0371a819dd..6533344048 100755
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -2,6 +2,39 @@
<llsd xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="llsd.xsd">
<map>
+ <key>ImporterDebug</key>
+ <map>
+ <key>Comment</key>
+ <string>Enable debug output to more precisely identify sources of import errors. Warning: the output can slow down import on many machines.</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
+ <key>ImporterLegacyMatching</key>
+ <map>
+ <key>Comment</key>
+ <string>Enable index based model matching.</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
+ <key>ImporterModelLimit</key>
+ <map>
+ <key>Comment</key>
+ <string>Limits amount of importer generated models for dae files</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>U32</string>
+ <key>Value</key>
+ <integer>768</integer>
+ </map>
<key>IMShowTime</key>
<map>
<key>Comment</key>
@@ -10600,6 +10633,28 @@
<key>Value</key>
<integer>0</integer>
</map>
+ <key>SkeletonFileName</key>
+ <map>
+ <key>Comment</key>
+ <string>Alternative skeleton file name</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>String</string>
+ <key>Value</key>
+ <string>avatar_skeleton.xml</string>
+ </map>
+ <key>AvatarFileName</key>
+ <map>
+ <key>Comment</key>
+ <string>Alternative avatar file name</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>String</string>
+ <key>Value</key>
+ <string>avatar_lad.xml</string>
+ </map>
<key>ShowAdvancedGraphicsSettings</key>
<map>
<key>Comment</key>
diff --git a/indra/newview/app_settings/shaders/class1/avatar/objectSkinV.glsl b/indra/newview/app_settings/shaders/class1/avatar/objectSkinV.glsl
index 6cd38d8ef5..b342abb7c1 100755
--- a/indra/newview/app_settings/shaders/class1/avatar/objectSkinV.glsl
+++ b/indra/newview/app_settings/shaders/class1/avatar/objectSkinV.glsl
@@ -24,8 +24,11 @@
ATTRIBUTE vec4 weight4;
-uniform mat3 matrixPalette[52];
-uniform vec3 translationPalette[52];
+/* BENTO JOINT COUNT LIMITS
+ * Note that the value in these two lines also needs to be updated to value-1 several places below.
+ */
+uniform mat3 matrixPalette[152];
+uniform vec3 translationPalette[152];
mat4 getObjectSkinnedTransform()
{
@@ -34,11 +37,10 @@ mat4 getObjectSkinnedTransform()
vec4 w = fract(weight4);
vec4 index = floor(weight4);
- index = min(index, vec4(51.0));
+ index = min(index, vec4(151.0));
index = max(index, vec4( 0.0));
- float scale = 1.0/(w.x+w.y+w.z+w.w);
- w *= scale;
+ w *= 1.0/(w.x+w.y+w.z+w.w);
int i1 = int(index.x);
int i2 = int(index.y);
@@ -68,8 +70,8 @@ mat4 getObjectSkinnedTransform()
// If it's AMD make sure the GLSL compiler sees the arrays referenced once by static index. Otherwise it seems to optimise the storage awawy which leads to unfun crashes and artifacts.
mat3 dummy1 = matrixPalette[0];
vec3 dummy2 = translationPalette[0];
- mat3 dummy3 = matrixPalette[51];
- vec3 dummy4 = translationPalette[51];
+ mat3 dummy3 = matrixPalette[151];
+ vec3 dummy4 = translationPalette[151];
#endif
}
diff --git a/indra/newview/character/avatar_lad.xml b/indra/newview/character/avatar_lad.xml
index 9ec6428ee6..ac0b8b5704 100755
--- a/indra/newview/character/avatar_lad.xml
+++ b/indra/newview/character/avatar_lad.xml
@@ -413,6 +413,116 @@
rotation="0 0 0"
visible_in_first_person="true" />
+ <attachment_point
+ id="41"
+ group="6"
+ pie_slice="2"
+ name="L Wing Shoulder"
+ joint="mLeftWingShoulder"
+ position="0 0 0"
+ rotation="0 0 0"
+ visible_in_first_person="true" />
+
+ <attachment_point
+ id="42"
+ group="6"
+ pie_slice="2"
+ name="L Wing Elbow"
+ joint="mLeftWingElbow"
+ position="0 0 0"
+ rotation="0 0 0"
+ visible_in_first_person="true" />
+
+ <attachment_point
+ id="43"
+ group="6"
+ pie_slice="2"
+ name="L Wing Wrist"
+ joint="mLeftWingWrist"
+ position="0 0 0"
+ rotation="0 0 0"
+ visible_in_first_person="true" />
+
+ <attachment_point
+ id="44"
+ group="6"
+ pie_slice="2"
+ name="L Wing Tip"
+ joint="mLeftWingTip"
+ position="0 0 0"
+ rotation="0 0 0"
+ visible_in_first_person="true" />
+
+ <attachment_point
+ id="45"
+ group="6"
+ pie_slice="2"
+ name="R Wing Shoulder"
+ joint="mRightWingShoulder"
+ position="0 0 0"
+ rotation="0 0 0"
+ visible_in_first_person="true" />
+
+ <attachment_point
+ id="46"
+ group="6"
+ pie_slice="2"
+ name="R Wing Elbow"
+ joint="mRightWingElbow"
+ position="0 0 0"
+ rotation="0 0 0"
+ visible_in_first_person="true" />
+
+ <attachment_point
+ id="47"
+ group="6"
+ pie_slice="2"
+ name="R Wing Wrist"
+ joint="mRightWingWrist"
+ position="0 0 0"
+ rotation="0 0 0"
+ visible_in_first_person="true" />
+
+ <attachment_point
+ id="48"
+ group="6"
+ pie_slice="2"
+ name="R Wing Tip"
+ joint="mRightWingTip"
+ position="0 0 0"
+ rotation="0 0 0"
+ visible_in_first_person="true" />
+
+ <attachment_point
+ id="49"
+ group="6"
+ pie_slice="2"
+ name="Tail 1"
+ joint="mTail_1"
+ position="0 0 0"
+ rotation="0 0 0"
+ visible_in_first_person="true" />
+
+ <attachment_point
+ id="50"
+ group="6"
+ pie_slice="2"
+ name="Tail 2"
+ joint="mTail_2"
+ position="0 0 0"
+ rotation="0 0 0"
+ visible_in_first_person="true" />
+
+ <attachment_point
+ id="51"
+ group="6"
+ pie_slice="2"
+ name="Tail 3"
+ joint="mTail_3"
+ position="0 0 0"
+ rotation="0 0 0"
+ visible_in_first_person="true" />
+
<param
id="32"
group="1"
diff --git a/indra/newview/character/avatar_lad_orig.xml b/indra/newview/character/avatar_lad_orig.xml
new file mode 100644
index 0000000000..9ec6428ee6
--- /dev/null
+++ b/indra/newview/character/avatar_lad_orig.xml
@@ -0,0 +1,12505 @@
+<?xml version="1.0" encoding="US-ASCII" standalone="yes"?>
+<linden_avatar
+ version="1.0" wearable_definition_version="22">
+ <!-- The wearable_definition_version is checked during asset upload. -->
+ <!-- If you increment it, check indra/lib/python/indra/assetutil.py. -->
+ <skeleton
+ file_name="avatar_skeleton.xml">
+ <attachment_point
+ id="1"
+ group="6"
+ pie_slice="2"
+ name="Chest"
+ joint="mChest"
+ position="0.15 0 -0.1"
+ rotation="0 90 90"
+ visible_in_first_person="true" />
+
+ <attachment_point
+ id="2"
+ group="2"
+ pie_slice="2"
+ name="Skull"
+ joint="mHead"
+ position="0 0 0.15"
+ rotation="0 0 90"
+ visible_in_first_person="false" />
+
+ <attachment_point
+ id="3"
+ group="3"
+ pie_slice="3"
+ name="Left Shoulder"
+ joint="mCollarLeft"
+ position="0 0 0.08"
+ rotation="0 0 0"
+ visible_in_first_person="true" />
+
+ <attachment_point
+ id="4"
+ group="1"
+ pie_slice="1"
+ name="Right Shoulder"
+ joint="mCollarRight"
+ position="0 0 0.08"
+ rotation="0 0 0"
+ visible_in_first_person="true"/>
+
+ <attachment_point
+ id="5"
+ group="4"
+ name="Left Hand"
+ joint="mWristLeft"
+ position="0 0.08 -0.02"
+ rotation="0 0 0"
+ visible_in_first_person="true"
+ max_attachment_offset="1.5" />
+
+ <attachment_point
+ id="6"
+ group="0"
+ name="Right Hand"
+ joint="mWristRight"
+ position="0 -0.08 -0.02"
+ rotation="0 0 0"
+ visible_in_first_person="true"
+ max_attachment_offset="1.5" />
+
+ <attachment_point
+ id="7"
+ group="5"
+ pie_slice="6"
+ name="Left Foot"
+ joint="mFootLeft"
+ position="0 0.0 0.0"
+ rotation="0 0 0"
+ visible_in_first_person="true"/>
+
+ <attachment_point
+ id="8"
+ group="7"
+ pie_slice="6"
+ name="Right Foot"
+ joint="mFootRight"
+ position="0 0.0 0.0"
+ rotation="0 0 0"
+ visible_in_first_person="true"/>
+
+ <attachment_point
+ id="9"
+ group="6"
+ pie_slice="7"
+ name="Spine"
+ joint="mChest"
+ position="-0.15 0 -0.1"
+ rotation="0 -90 90"
+ visible_in_first_person="true" />
+
+ <attachment_point
+ id="10"
+ group="6"
+ pie_slice="6"
+ name="Pelvis"
+ joint="mPelvis"
+ position="0 0 -0.15"
+ rotation="0 0 0"
+ visible_in_first_person="true" />
+
+ <attachment_point
+ id="11"
+ group="2"
+ pie_slice="6"
+ name="Mouth"
+ joint="mHead"
+ position="0.12 0 0.001"
+ rotation="0 0 0"
+ visible_in_first_person="false"/>
+
+ <attachment_point
+ id="12"
+ group="2"
+ pie_slice="7"
+ name="Chin"
+ joint="mHead"
+ position="0.12 0 -0.04"
+ rotation="0 0 0"
+ visible_in_first_person="false" />
+
+ <attachment_point
+ id="13"
+ group="2"
+ pie_slice="4"
+ name="Left Ear"
+ joint="mHead"
+ position="0.015 0.08 0.017"
+ rotation="0 0 0"
+ visible_in_first_person="false" />
+
+ <attachment_point
+ id="14"
+ group="2"
+ pie_slice="0"
+ name="Right Ear"
+ joint="mHead"
+ position="0.015 -0.08 0.017"
+ rotation="0 0 0"
+ visible_in_first_person="false" />
+
+ <attachment_point
+ id="15"
+ group="2"
+ pie_slice="3"
+ name="Left Eyeball"
+ joint="mEyeLeft"
+ position="0 0 0"
+ rotation="0 0 0"
+ visible_in_first_person="false"/>
+
+ <attachment_point
+ id="16"
+ group="2"
+ pie_slice="1"
+ name="Right Eyeball"
+ joint="mEyeRight"
+ position="0 0 0"
+ rotation="0 0 0"
+ visible_in_first_person="false" />
+
+ <attachment_point
+ id="17"
+ group="2"
+ pie_slice="5"
+ name="Nose"
+ joint="mHead"
+ position="0.1 0 0.05"
+ rotation="0 0 0"
+ visible_in_first_person="false"/>
+
+ <attachment_point
+ id="18"
+ group="1"
+ pie_slice="0"
+ name="R Upper Arm"
+ joint="mShoulderRight"
+ position="0.01 -0.13 0.01"
+ rotation="0 0 0"
+ visible_in_first_person="true" />
+
+ <attachment_point
+ id="19"
+ group="1"
+ pie_slice="7"
+ name="R Forearm"
+ joint="mElbowRight"
+ position="0 -0.12 0"
+ rotation="0 0 0"
+ visible_in_first_person="true"/>
+
+ <attachment_point
+ id="20"
+ group="3"
+ pie_slice="4"
+ name="L Upper Arm"
+ joint="mShoulderLeft"
+ position="0.01 0.15 -0.01"
+ rotation="0 0 0"
+ visible_in_first_person="true" />
+
+ <attachment_point
+ id="21"
+ group="3"
+ pie_slice="5"
+ name="L Forearm"
+ joint="mElbowLeft"
+ position="0 0.113 0"
+ rotation="0 0 0"
+ visible_in_first_person="true" />
+
+ <attachment_point
+ id="22"
+ group="7"
+ pie_slice="1"
+ name="Right Hip"
+ joint="mHipRight"
+ position="0 0 0"
+ rotation="0 0 0"
+ visible_in_first_person="true" />
+
+ <attachment_point
+ id="23"
+ group="7"
+ pie_slice="0"
+ name="R Upper Leg"
+ joint="mHipRight"
+ position="-0.017 0.041 -0.310"
+ rotation="0 0 0"
+ visible_in_first_person="true" />
+
+ <attachment_point
+ id="24"
+ group="7"
+ pie_slice="7"
+ name="R Lower Leg"
+ joint="mKneeRight"
+ position="-0.044 -0.007 -0.262"
+ rotation="0 0 0"
+ visible_in_first_person="true" />
+
+ <attachment_point
+ id="25"
+ group="5"
+ pie_slice="3"
+ name="Left Hip"
+ joint="mHipLeft"
+ position="0 0 0"
+ rotation="0 0 0"
+ visible_in_first_person="true" />
+
+ <attachment_point
+ id="26"
+ group="5"
+ pie_slice="4"
+ name="L Upper Leg"
+ joint="mHipLeft"
+ position="-0.019 -0.034 -0.310"
+ rotation="0 0 0"
+ visible_in_first_person="true"/>
+
+ <attachment_point
+ id="27"
+ group="5"
+ pie_slice="5"
+ name="L Lower Leg"
+ joint="mKneeLeft"
+ position="-0.044 -0.007 -0.261"
+ rotation="0 0 0"
+ visible_in_first_person="true" />
+
+ <attachment_point
+ id="28"
+ group="6"
+ pie_slice="5"
+ name="Stomach"
+ joint="mPelvis"
+ position="0.092 0.0 0.088"
+ rotation="0 0 0"
+ visible_in_first_person="true" />
+
+ <attachment_point
+ id="29"
+ group="6"
+ pie_slice="3"
+ name="Left Pec"
+ joint="mTorso"
+ position="0.104 0.082 0.247"
+ rotation="0 0 0"
+ visible_in_first_person="true" />
+
+ <attachment_point
+ id="30"
+ group="6"
+ pie_slice="1"
+ name="Right Pec"
+ joint="mTorso"
+ position="0.104 -0.082 0.247"
+ rotation="0 0 0"
+ visible_in_first_person="true" />
+
+ <attachment_point
+ id="31"
+ group="8"
+ name="Center 2"
+ joint="mScreen"
+ position="0 0 0"
+ rotation="0 0 0"
+ hud="true"
+ max_attachment_offset="2.0"
+ visible_in_first_person="true" />
+
+ <attachment_point
+ id="32"
+ group="8"
+ name="Top Right"
+ joint="mScreen"
+ position="0 -0.5 0.5"
+ rotation="0 0 0"
+ hud="true"
+ max_attachment_offset="2.0"
+ visible_in_first_person="true" />
+
+ <attachment_point
+ id="33"
+ group="8"
+ name="Top"
+ joint="mScreen"
+ position="0 0 0.5"
+ rotation="0 0 0"
+ hud="true"
+ max_attachment_offset="2.0"
+ visible_in_first_person="true" />
+
+ <attachment_point
+ id="34"
+ group="8"
+ name="Top Left"
+ joint="mScreen"
+ position="0 0.5 0.5"
+ rotation="0 0 0"
+ hud="true"
+ max_attachment_offset="2.0"
+ visible_in_first_person="true" />
+
+ <attachment_point
+ id="35"
+ group="8"
+ name="Center"
+ joint="mScreen"
+ position="0 0 0"
+ rotation="0 0 0"
+ hud="true"
+ max_attachment_offset="2.0"
+ visible_in_first_person="true" />
+
+ <attachment_point
+ id="36"
+ group="8"
+ name="Bottom Left"
+ joint="mScreen"
+ position="0 0.5 -0.5"
+ rotation="0 0 0"
+ hud="true"
+ max_attachment_offset="2.0"
+ visible_in_first_person="true" />
+
+ <attachment_point
+ id="37"
+ group="8"
+ name="Bottom"
+ joint="mScreen"
+ position="0 0 -0.5"
+ rotation="0 0 0"
+ hud="true"
+ max_attachment_offset="2.0"
+ visible_in_first_person="true" />
+
+ <attachment_point
+ id="38"
+ group="8"
+ name="Bottom Right"
+ joint="mScreen"
+ position="0 -0.5 -0.5"
+ rotation="0 0 0"
+ hud="true"
+ max_attachment_offset="2.0"
+ visible_in_first_person="true" />
+
+ <attachment_point
+ id="39"
+ group="6"
+ pie_slice="1"
+ name="Neck"
+ joint="mNeck"
+ position="0 0 0"
+ rotation="0 0 0"
+ visible_in_first_person="true" />
+
+ <attachment_point
+ id="40"
+ group="6"
+ pie_slice="2"
+ name="Avatar Center"
+ joint="mRoot"
+ position="0 0 0"
+ rotation="0 0 0"
+ visible_in_first_person="true" />
+
+ <param
+ id="32"
+ group="1"
+ wearable="shape"
+ name="Male_Skeleton"
+ label_min="Female"
+ label_max="Male"
+ value_min="0"
+ value_max="1">
+ <param_skeleton>
+ <bone
+ name="mNeck"
+ scale="0 0 .2" />
+
+ <bone
+ name="mCollarLeft"
+ scale="0 .4 0" />
+
+ <bone
+ name="mCollarRight"
+ scale="0 .4 0" />
+
+ <bone
+ name="mShoulderLeft"
+ scale="0 .35 0" />
+
+ <bone
+ name="mShoulderRight"
+ scale="0 .35 0" />
+
+ <bone
+ name="mElbowLeft"
+ scale="0 .1 0" />
+
+ <bone
+ name="mElbowRight"
+ scale="0 .1 0" />
+
+ <bone
+ name="mChest"
+ scale=".05 .05 .05" />
+
+ <bone
+ name="mTorso"
+ scale="0 0 .05" />
+
+ <bone
+ name="mPelvis"
+ scale="0 0 0" />
+
+ <bone
+ name="mHipLeft"
+ scale=".05 .05 0" />
+
+ <bone
+ name="mHipRight"
+ scale=".05 .05 0" />
+
+ <bone
+ name="mKneeLeft"
+ scale=".05 .05 .1" />
+
+ <bone
+ name="mKneeRight"
+ scale=".05 .05 .1" />
+ </param_skeleton>
+ </param>
+
+ <param
+ id="33"
+ group="0"
+ name="Height"
+ label="Height"
+ wearable="shape"
+ edit_group="shape_body"
+ edit_group_order="1"
+ label_min="Short"
+ label_max="Tall"
+ show_simple="true"
+ value_min="-2.3"
+ value_max="2"
+ camera_distance="2.2">
+ <param_skeleton>
+ <bone
+ name="mNeck"
+ scale="0 0 .02" />
+
+ <bone
+ name="mCollarLeft"
+ scale="0 0 0" />
+
+ <bone
+ name="mCollarRight"
+ scale="0 0 0" />
+
+ <bone
+ name="mShoulderLeft"
+ scale="0 0.08 0" />
+
+ <bone
+ name="mShoulderRight"
+ scale="0 0.08 0" />
+
+ <bone
+ name="mElbowLeft"
+ scale="0 0.06 0" />
+
+ <bone
+ name="mElbowRight"
+ scale="0 0.06 0" />
+
+ <bone
+ name="mChest"
+ scale="0 0 0.05" />
+
+ <bone
+ name="mTorso"
+ scale="0 0 0.05" />
+
+ <bone
+ name="mPelvis"
+ scale="0 0 0" />
+
+ <bone
+ name="mHipLeft"
+ scale="0 0 0.1" />
+
+ <bone
+ name="mHipRight"
+ scale="0 0 0.1" />
+
+ <bone
+ name="mKneeLeft"
+ scale="0 0 0.1" />
+
+ <bone
+ name="mKneeRight"
+ scale="0 0 0.1" />
+ </param_skeleton>
+ </param>
+
+ <param
+ id="34"
+ group="0"
+ name="Thickness"
+ label="Body Thickness"
+ wearable="shape"
+ edit_group="shape_body"
+ edit_group_order="2"
+ label_min="Body Thin"
+ label_max="Body Thick"
+ show_simple="true"
+ value_min="-0.7"
+ value_max="1.5"
+ camera_distance="1.8">
+ <param_skeleton>
+ <bone
+ name="mNeck"
+ scale="0.1 0.1 0" />
+
+ <bone
+ name="mCollarLeft"
+ scale="0 0.2 0" />
+
+ <bone
+ name="mCollarRight"
+ scale="0 0.2 0" />
+
+ <bone
+ name="mShoulderLeft"
+ scale="0.1 0 0.1" />
+
+ <bone
+ name="mShoulderRight"
+ scale="0.1 0 0.1" />
+
+ <bone
+ name="mElbowLeft"
+ scale="0.1 0 0.1" />
+
+ <bone
+ name="mElbowRight"
+ scale="0.1 0 0.1" />
+
+ <bone
+ name="mChest"
+ scale="0.1 0.1 0" />
+
+ <bone
+ name="mTorso"
+ scale="0.1 0.1 0" />
+
+ <bone
+ name="mPelvis"
+ scale="0.1 0.1 0" />
+
+ <bone
+ name="mHipLeft"
+ scale="0.13 0.13 0" />
+
+ <bone
+ name="mHipRight"
+ scale="0.13 0.13 0" />
+
+ <bone
+ name="mKneeLeft"
+ scale="0.12 0.12 0" />
+
+ <bone
+ name="mKneeRight"
+ scale="0.12 0.12 0" />
+ </param_skeleton>
+ </param>
+
+ <param
+ id="36"
+ group="0"
+ name="Shoulders"
+ label="Shoulders"
+ wearable="shape"
+ edit_group="shape_torso"
+ edit_group_order="4"
+ label_min="Narrow"
+ label_max="Broad"
+ show_simple="true"
+ value_min="-1.8"
+ value_max="1.4"
+ value_default="-0.5"
+ camera_elevation=".1"
+ camera_distance="1.2"
+ camera_angle="0">
+ <param_skeleton>
+ <bone
+ name="mNeck"
+ scale="0.01 0.03 0" />
+
+ <bone
+ name="mCollarLeft"
+ scale="0 0 0"
+ offset="0 .02 0" />
+
+ <bone
+ name="mCollarRight"
+ scale="0 0 0"
+ offset="0 -.02 0" />
+
+ <bone
+ name="mChest"
+ scale="0.02 0.08 0" />
+ </param_skeleton>
+ </param>
+
+ <param
+ id="37"
+ group="0"
+ name="Hip Width"
+ label="Hip Width"
+ wearable="shape"
+ edit_group="shape_legs"
+ edit_group_order="3"
+ label_min="Narrow"
+ label_max="Wide"
+ show_simple="true"
+ value_min="-3.2"
+ value_max="2.8"
+ camera_distance="1.8">
+ <param_skeleton>
+ <bone
+ name="mPelvis"
+ scale="0 0.1 0" />
+
+ <bone
+ name="mHipLeft"
+ scale="0 0 0"
+ offset="0 .004 0" />
+
+ <bone
+ name="mHipRight"
+ scale="0 0 0"
+ offset="0 -.004 0" />
+ </param_skeleton>
+ </param>
+
+ <param
+ id="842"
+ group="0"
+ name="Hip Length"
+ wearable="shape"
+ edit_group="shape_legs"
+ edit_group_order="3.2"
+ label_min="Short hips"
+ label_max="Long Hips"
+ value_min="-1"
+ value_max="1"
+ camera_distance="1.8">
+ <param_skeleton>
+ <bone
+ name="mPelvis"
+ scale="0 0 0.3" />
+ </param_skeleton>
+ </param>
+
+ <param
+ id="38"
+ group="0"
+ name="Torso Length"
+ wearable="shape"
+ edit_group="shape_torso"
+ edit_group_order="11"
+ label_min="Short Torso"
+ label_max="Long Torso"
+ value_min="-1"
+ value_max="1"
+ camera_distance="1.8">
+ <param_skeleton>
+ <bone
+ name="mTorso"
+ scale="0 0 .3" />
+
+ <bone
+ name="mPelvis"
+ scale="0 0 .1" />
+
+ <bone
+ name="mHipLeft"
+ scale="0 0 -.1" />
+
+ <bone
+ name="mHipRight"
+ scale="0 0 -.1" />
+
+ <bone
+ name="mKneeRight"
+ scale="0 0 -.05" />
+
+ <bone
+ name="mKneeLeft"
+ scale="0 0 -.05" />
+ </param_skeleton>
+ </param>
+
+ <param
+ id="195"
+ group="1"
+ name="EyeBone_Spread"
+ wearable="shape"
+ edit_group="shape_eyes"
+ label_min="Eyes Together"
+ label_max="Eyes Spread"
+ value_min="-1"
+ value_max="1">
+ <param_skeleton>
+ <bone
+ name="mEyeLeft"
+ scale="0 0 0"
+ offset="0 .009 0" />
+
+ <bone
+ name="mEyeRight"
+ scale="0 0 0"
+ offset="0 -.009 0" />
+ </param_skeleton>
+ </param>
+
+ <param
+ id="661"
+ group="1"
+ name="EyeBone_Head_Shear"
+ wearable="shape"
+ edit_group="shape_eyes"
+ label_min="Eyes Shear Left Up"
+ label_max="Eyes Shear Right Up"
+ value_min="-2"
+ value_max="2">
+ <param_skeleton>
+ <bone
+ name="mEyeLeft"
+ scale="0 0 0"
+ offset="0 0 .004" />
+
+ <bone
+ name="mEyeRight"
+ scale="0 0 0"
+ offset="0 0 -.004" />
+ </param_skeleton>
+ </param>
+
+ <param
+ id="772"
+ group="1"
+ name="EyeBone_Head_Elongate"
+ wearable="shape"
+ edit_group="shape_eyes"
+ label_min="Eyes Short Head"
+ label_max="Eyes Long Head"
+ value_min="-1"
+ value_max="1">
+ <param_skeleton>
+ <bone
+ name="mEyeLeft"
+ scale="0 0 0"
+ offset=".016 0 0" />
+
+ <bone
+ name="mEyeRight"
+ scale="0 0 0"
+ offset=".016 0 0" />
+ </param_skeleton>
+ </param>
+
+ <param
+ id="768"
+ group="1"
+ name="EyeBone_Bug"
+ wearable="shape"
+ edit_group="shape_eyes"
+ label_min="Eyes Sunken"
+ label_max="Eyes Bugged"
+ value_min="-2"
+ value_max="2">
+ <param_skeleton>
+ <bone
+ name="mEyeLeft"
+ scale="0 0 0"
+ offset=".005 0 0" />
+
+ <bone
+ name="mEyeRight"
+ scale="0 0 0"
+ offset=".005 0 0" />
+ </param_skeleton>
+ </param>
+
+ <param
+ id="655"
+ group="1"
+ name="Head Size"
+ label="Head Size"
+ wearable="shape"
+ edit_group="shape_head"
+ label_min="Small Head"
+ label_max="Big Head"
+ show_simple="true"
+ value_min="-.25"
+ value_max=".10">
+ <param_skeleton>
+ <bone
+ name="mSkull"
+ scale="1 1 1"
+ offset="0 0 0.1" />
+
+ <bone
+ name="mHead"
+ scale="1 1 1"
+ offset="0 0 0" />
+
+ <bone
+ name="mEyeLeft"
+ scale="1 1 1"
+ offset="0 0 0" />
+
+ <bone
+ name="mEyeRight"
+ scale="1 1 1"
+ offset="0 0 0" />
+ </param_skeleton>
+ </param>
+
+ <param
+ id="197"
+ group="1"
+ wearable="shoes"
+ name="Shoe_Heels"
+ edit_group="shoes"
+ label_min="No Heels"
+ label_max="High Heels"
+ value_min="0"
+ value_max="1">
+ <param_skeleton>
+ <bone
+ name="mFootRight"
+ scale="0 0 0"
+ offset="0 0 -.08" />
+
+ <bone
+ name="mFootLeft"
+ scale="0 0 0"
+ offset="0 0 -.08" />
+ </param_skeleton>
+ </param>
+
+ <param
+ id="502"
+ group="1"
+ wearable="shoes"
+ name="Shoe_Platform"
+ edit_group="shoes"
+ label_min="No Heels"
+ label_max="High Heels"
+ value_min="0"
+ value_max="1">
+ <param_skeleton>
+ <bone
+ name="mFootRight"
+ scale="0 0 0"
+ offset="0 0 -.07" />
+
+ <bone
+ name="mFootLeft"
+ scale="0 0 0"
+ offset="0 0 -.07" />
+ </param_skeleton>
+ </param>
+
+ <param
+ id="675"
+ group="0"
+ name="Hand Size"
+ wearable="shape"
+ edit_group="shape_torso"
+ edit_group_order="10"
+ label_min="Small Hands"
+ label_max="Large Hands"
+ value_min="-.3"
+ value_max=".3"
+ camera_elevation=".1"
+ camera_distance="1.4"
+ camera_angle="0">
+ <param_skeleton>
+ <bone
+ name="mWristRight"
+ scale="1 1 1"
+ offset="0 0 0" />
+
+ <bone
+ name="mWristLeft"
+ scale="1 1 1"
+ offset="0 0 0" />
+ </param_skeleton>
+ </param>
+
+ <param
+ id="683"
+ group="0"
+ name="Neck Thickness"
+ wearable="shape"
+ edit_group="shape_torso"
+ edit_group_order="2"
+ label_min="Skinny Neck"
+ label_max="Thick Neck"
+ value_min="-.4"
+ value_max=".2"
+ value_default="-.15"
+ camera_elevation=".3"
+ camera_distance=".8"
+ camera_angle="15">
+ <param_skeleton>
+ <bone
+ name="mNeck"
+ scale="1 1 0"
+ offset="0 0 0" />
+ </param_skeleton>
+ </param>
+
+ <param
+ id="689"
+ group="1"
+ wearable="shape"
+ name="EyeBone_Big_Eyes"
+ edit_group="shape_eyes"
+ label_min="Eyes Back"
+ label_max="Eyes Forward"
+ value_min="-1"
+ value_max="1">
+ <param_skeleton>
+ <bone
+ name="mEyeLeft"
+ scale="0 0 0"
+ offset="-.005 0 0" />
+
+ <bone
+ name="mEyeRight"
+ scale="0 0 0"
+ offset="-.005 0 0" />
+ </param_skeleton>
+ </param>
+
+ <param
+ id="692"
+ group="0"
+ name="Leg Length"
+ wearable="shape"
+ edit_group="shape_legs"
+ edit_group_order="2"
+ label_min="Short Legs"
+ label_max="Long Legs"
+ value_min="-1"
+ value_max="1"
+ camera_distance="2.5">
+ <param_skeleton>
+ <bone
+ name="mHipLeft"
+ scale="0 0 .2" />
+
+ <bone
+ name="mHipRight"
+ scale="0 0 .2" />
+
+ <bone
+ name="mKneeRight"
+ scale="0 0 .2" />
+
+ <bone
+ name="mKneeLeft"
+ scale="0 0 .2" />
+ </param_skeleton>
+ </param>
+
+ <param
+ id="693"
+ group="0"
+ name="Arm Length"
+ wearable="shape"
+ edit_group="shape_torso"
+ edit_group_order="9"
+ label_min="Short Arms"
+ label_max="Long arms"
+ value_min="-1"
+ value_max="1"
+ value_default=".6"
+ camera_distance="1.5">
+ <param_skeleton>
+ <bone
+ name="mShoulderLeft"
+ scale="0 .2 0" />
+
+ <bone
+ name="mShoulderRight"
+ scale="0 .2 0" />
+
+ <bone
+ name="mElbowRight"
+ scale="0 .3 0" />
+
+ <bone
+ name="mElbowLeft"
+ scale="0 .3 0" />
+ </param_skeleton>
+ </param>
+
+ <param
+ id="756"
+ group="0"
+ name="Neck Length"
+ wearable="shape"
+ edit_group="shape_torso"
+ edit_group_order="3"
+ label_min="Short Neck"
+ label_max="Long Neck"
+ value_min="-1"
+ value_max="1"
+ value_default="0"
+ camera_elevation=".3"
+ camera_distance=".8"
+ camera_angle="15">
+ <param_skeleton>
+ <bone
+ name="mNeck"
+ scale="0 0 .5" />
+ </param_skeleton>
+ </param>
+ <param
+ id="11001"
+ group="0"
+ name="Hover"
+ wearable="shape"
+ edit_group="shape_body"
+ edit_group_order="4"
+ label_min="Lower"
+ label_max="Higher"
+ value_min="-2"
+ value_max="2"
+ value_default="0"
+ camera_distance="2.5">
+ <param_skeleton />
+ </param>
+
+ </skeleton>
+
+ <mesh
+ type="hairMesh"
+ lod="0"
+ file_name="avatar_hair.llm"
+ min_pixel_width="320">
+ <!-- begin morph targets -->
+ <param
+ id="180"
+ group="1"
+ name="Hair_Volume"
+ label="Hair Volume"
+ show_simple="true"
+ wearable="hair"
+ clothing_morph="true"
+ edit_group="hair_style"
+ label_min="Less"
+ label_max="More"
+ value_min="0"
+ value_max="1.3"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="20">
+ <param_morph />
+ </param>
+
+ <param
+ id="761"
+ group="1"
+ name="Hair_Volume_Small"
+ label="Hair Volume"
+ show_simple="true"
+ wearable="hair"
+ edit_group="hair_style"
+ label_min="Less"
+ label_max="More"
+ value_min="0"
+ value_max="1.3"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="20">
+ <param_morph />
+ </param>
+
+ <param
+ id="181"
+ group="0"
+ name="Hair_Big_Front"
+ label="Big Hair Front"
+ wearable="hair"
+ edit_group="hair_style"
+ edit_group_order="5"
+ label_min="Less"
+ label_max="More"
+ value_min="-1"
+ value_max="1"
+ value_default="0.14"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="90">
+ <param_morph />
+ </param>
+
+ <param
+ id="182"
+ group="0"
+ name="Hair_Big_Top"
+ label="Big Hair Top"
+ wearable="hair"
+ edit_group="hair_style"
+ edit_group_order="6"
+ label_min="Less"
+ label_max="More"
+ value_min="-1"
+ value_max="1"
+ value_default=".7"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="90">
+ <param_morph />
+ </param>
+
+ <param
+ id="183"
+ group="0"
+ name="Hair_Big_Back"
+ clothing_morph="true"
+ label="Big Hair Back"
+ wearable="hair"
+ edit_group="hair_style"
+ edit_group_order="7"
+ label_min="Less"
+ label_max="More"
+ value_min="-1"
+ value_max="1"
+ value_default="0.05"
+ camera_elevation=".1"
+ camera_distance=".7"
+ camera_angle="90">
+ <param_morph />
+ </param>
+
+ <param
+ id="184"
+ group="0"
+ name="Hair_Spiked"
+ label="Spiked Hair"
+ show_simple="true"
+ wearable="hair"
+ clothing_morph="true"
+ edit_group="hair_style"
+ edit_group_order="15"
+ label_min="No Spikes"
+ label_max="Big Spikes"
+ value_min="0"
+ value_max="1"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="20">
+ <param_morph />
+ </param>
+
+ <param
+ id="140"
+ group="0"
+ name="Hair_Part_Middle"
+ label="Middle Part"
+ wearable="hair"
+ edit_group="hair_style"
+ edit_group_order="17"
+ label_min="No Part"
+ label_max="Part"
+ value_min="0"
+ value_max="2"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="0">
+ <param_morph />
+ </param>
+
+ <param
+ id="141"
+ group="0"
+ name="Hair_Part_Right"
+ label="Right Part"
+ wearable="hair"
+ edit_group="hair_style"
+ edit_group_order="18"
+ label_min="No Part"
+ label_max="Part"
+ value_min="0"
+ value_max="2"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="0">
+ <param_morph />
+ </param>
+
+ <param
+ id="142"
+ group="0"
+ name="Hair_Part_Left"
+ label="Left Part"
+ wearable="hair"
+ edit_group="hair_style"
+ edit_group_order="19"
+ label_min="No Part"
+ label_max="Part"
+ value_min="0"
+ value_max="2"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="0">
+ <param_morph />
+ </param>
+
+ <param
+ id="143"
+ group="0"
+ name="Hair_Sides_Full"
+ label="Full Hair Sides"
+ show_simple="true"
+ wearable="hair"
+ edit_group="hair_style"
+ edit_group_order="11"
+ label_min="Mowhawk"
+ label_max="Full Sides"
+ value_min="-4"
+ value_max="1.5"
+ value_default="0.125"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="20">
+ <param_morph />
+ </param>
+
+ <param
+ id="144"
+ group="1"
+ name="Bangs_Front_Up"
+ label="Front Bangs Up"
+ wearable="hair"
+ edit_group="hair_style"
+ label_min="Bangs"
+ label_max="Bangs Up"
+ value_min="0"
+ value_max="1"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="20">
+ <param_morph />
+ </param>
+
+ <param
+ id="145"
+ group="1"
+ clothing_morph="true"
+ name="Bangs_Front_Down"
+ label="Front Bangs Down"
+ wearable="hair"
+ edit_group="hair_style"
+ label_min="Bangs"
+ label_max="Bangs Down"
+ value_min="0"
+ value_max="5"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="20">
+ <param_morph />
+ </param>
+
+ <param
+ id="146"
+ group="1"
+ name="Bangs_Sides_Up"
+ label="Side Bangs Up"
+ wearable="hair"
+ edit_group="hair_style"
+ label_min="Side Bangs"
+ label_max="Side Bangs Up"
+ value_min="0"
+ value_max="1"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="20">
+ <param_morph />
+ </param>
+
+ <param
+ id="147"
+ group="1"
+ clothing_morph="true"
+ name="Bangs_Sides_Down"
+ label="Side Bangs Down"
+ wearable="hair"
+ edit_group="hair_style"
+ label_min="Side Bangs"
+ label_max="Side Bangs Down"
+ value_min="0"
+ value_max="2"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="20">
+ <param_morph />
+ </param>
+
+ <param
+ id="148"
+ group="1"
+ name="Bangs_Back_Up"
+ label="Back Bangs Up"
+ wearable="hair"
+ edit_group="hair_style"
+ label_min="Back Bangs"
+ label_max="Back Bangs Up"
+ value_min="0"
+ value_max="1"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="150">
+ <param_morph />
+ </param>
+
+ <param
+ id="149"
+ group="1"
+ name="Bangs_Back_Down"
+ label="Back Bangs Down"
+ clothing_morph="true"
+ wearable="hair"
+ edit_group="hair_style"
+ label_min="Back Bangs"
+ label_max="Back Bangs Down"
+ value_min="0"
+ value_max="2"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="150">
+ <param_morph />
+ </param>
+
+ <param
+ id="171"
+ group="1"
+ name="Hair_Front_Down"
+ label="Front Hair Down"
+ wearable="hair"
+ edit_group="hair_style"
+ label_min="Front Hair"
+ label_max="Front Hair Down"
+ value_min="0"
+ value_max="1"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="20">
+ <param_morph />
+ </param>
+
+ <param
+ id="172"
+ group="1"
+ name="Hair_Front_Up"
+ label="Front Hair Up"
+ wearable="hair"
+ edit_group="hair_style"
+ label_min="Front Hair"
+ label_max="Front Hair Up"
+ value_min="0"
+ value_max="1"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="20">
+ <param_morph />
+ </param>
+
+ <param
+ id="173"
+ group="1"
+ name="Hair_Sides_Down"
+ label="Sides Hair Down"
+ wearable="hair"
+ edit_group="hair_style"
+ label_min="Sides Hair"
+ label_max="Sides Hair Down"
+ value_min="0"
+ value_max="1"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="20">
+ <param_morph />
+ </param>
+
+ <param
+ id="174"
+ group="1"
+ name="Hair_Sides_Up"
+ label="Sides Hair Up"
+ wearable="hair"
+ edit_group="hair_style"
+ label_min="Sides Hair"
+ label_max="Sides Hair Up"
+ value_min="0"
+ value_max="1"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="20">
+ <param_morph />
+ </param>
+
+ <param
+ id="175"
+ group="1"
+ name="Hair_Back_Down"
+ label="Back Hair Down"
+ clothing_morph="true"
+ wearable="hair"
+ edit_group="hair_style"
+ label_min="Back Hair"
+ label_max="Back Hair Down"
+ value_min="0"
+ value_max="3"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="150">
+ <param_morph />
+ </param>
+
+ <param
+ id="176"
+ group="1"
+ name="Hair_Back_Up"
+ label="Back Hair Up"
+ wearable="hair"
+ edit_group="hair_style"
+ label_min="Back Hair"
+ label_max="Back Hair Up"
+ value_min="0"
+ value_max="1"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="150">
+ <param_morph />
+ </param>
+
+ <param
+ id="177"
+ group="0"
+ name="Hair_Rumpled"
+ label="Rumpled Hair"
+ show_simple="true"
+ wearable="hair"
+ clothing_morph="true"
+ edit_group="hair_style"
+ edit_group_order="14.5"
+ label_min="Smooth Hair"
+ label_max="Rumpled Hair"
+ value_min="0"
+ value_max="1"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="20">
+ <param_morph />
+ </param>
+
+ <param
+ id="178"
+ group="1"
+ name="Hair_Swept_Back"
+ label="Swept Back Hair"
+ wearable="hair"
+ edit_group="hair_style"
+ label_min="NotHair"
+ label_max="Swept Back"
+ value_min="0"
+ value_max="1"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="90">
+ <param_morph />
+ </param>
+
+ <param
+ id="179"
+ group="1"
+ name="Hair_Swept_Forward"
+ label="Swept Forward Hair"
+ wearable="hair"
+ edit_group="hair_style"
+ label_min="Hair"
+ label_max="Swept Forward"
+ value_min="0"
+ value_max="1"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="90">
+ <param_morph />
+ </param>
+
+ <param
+ id="190"
+ group="1"
+ name="Hair_Tilt_Right"
+ label="Hair Tilted Right"
+ wearable="hair"
+ edit_group="hair_style"
+ label_min="Hair"
+ label_max="Tilt Right"
+ value_min="0"
+ value_max="1"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="0">
+ <param_morph />
+ </param>
+
+ <param
+ id="191"
+ group="1"
+ name="Hair_Tilt_Left"
+ label="Hair Tilted Left"
+ wearable="hair"
+ edit_group="hair_style"
+ label_min="Hair"
+ label_max="Tilt Left"
+ value_min="0"
+ value_max="1"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="0">
+ <param_morph />
+ </param>
+
+ <param
+ id="192"
+ group="0"
+ name="Bangs_Part_Middle"
+ label="Part Bangs"
+ wearable="hair"
+ edit_group="hair_style"
+ edit_group_order="20"
+ label_min="No Part"
+ label_max="Part Bangs"
+ value_min="0"
+ value_max="1"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="0">
+ <param_morph />
+ </param>
+
+ <param
+ id="640"
+ group="1"
+ name="Hair_Egg_Head"
+ wearable="hair"
+ edit_group="hair_style"
+ cross_wearable="true"
+ value_min="-1.3"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="641"
+ group="1"
+ name="Hair_Squash_Stretch_Head"
+ wearable="hair"
+ edit_group="hair_style"
+ cross_wearable="true"
+ value_min="-.5"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="642"
+ group="1"
+ name="Hair_Square_Head"
+ wearable="hair"
+ edit_group="hair_style"
+ cross_wearable="true"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="643"
+ group="1"
+ name="Hair_Round_Head"
+ wearable="hair"
+ edit_group="hair_style"
+ cross_wearable="true"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="644"
+ group="1"
+ name="Hair_Forehead_Round"
+ wearable="hair"
+ edit_group="hair_style"
+ cross_wearable="true"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="645"
+ group="1"
+ name="Hair_Forehead_Slant"
+ wearable="hair"
+ edit_group="hair_style"
+ cross_wearable="true"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="774"
+ group="1"
+ name="Shear_Head_Hair"
+ wearable="hair"
+ edit_group="hair_style"
+ cross_wearable="true"
+ value_min="-2"
+ value_max="2">
+ <param_morph />
+ </param>
+
+ <param
+ id="771"
+ group="1"
+ name="Elongate_Head_Hair"
+ wearable="hair"
+ edit_group="hair_style"
+ cross_wearable="true"
+ value_min="-1"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="674"
+ group="0"
+ name="Hair_Shear_Back"
+ wearable="hair"
+ edit_group="hair_style"
+ edit_group_order="12"
+ label="Shear Back"
+ label_min="Full Back"
+ label_max="Sheared Back"
+ value_min="-1"
+ value_max="2"
+ value_default="-0.3"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="100">
+ <param_morph />
+ </param>
+
+ <param
+ id="762"
+ group="0"
+ name="Hair_Shear_Front"
+ wearable="hair"
+ edit_group="hair_style"
+ edit_group_order="11.8"
+ label="Shear Front"
+ show_simple="true"
+ label_min="Full Front"
+ label_max="Sheared Front"
+ value_min="0"
+ value_max="3"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="30">
+ <param_morph />
+ </param>
+
+ <param
+ id="754"
+ group="0"
+ name="Hair_Taper_Back"
+ wearable="hair"
+ edit_group="hair_style"
+ edit_group_order="14"
+ label="Taper Back"
+ label_min="Wide Back"
+ label_max="Narrow Back"
+ value_min="-1"
+ value_max="2"
+ value_default="0"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="160">
+ <param_morph />
+ </param>
+
+ <param
+ id="755"
+ group="0"
+ name="Hair_Taper_Front"
+ wearable="hair"
+ edit_group="hair_style"
+ edit_group_order="13"
+ label="Taper Front"
+ label_min="Wide Front"
+ label_max="Narrow Front"
+ value_min="-1.5"
+ value_max="1.5"
+ value_default="0.05"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="20">
+ <param_morph />
+ </param>
+
+ <param
+ id="782"
+ group="1"
+ clothing_morph="true"
+ name="Hair_Pigtails_Short"
+ wearable="hair"
+ edit_group="hair_style"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="783"
+ group="1"
+ clothing_morph="true"
+ name="Hair_Pigtails_Med"
+ wearable="hair"
+ edit_group="hair_style"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="790"
+ group="1"
+ clothing_morph="true"
+ name="Hair_Pigtails_Medlong"
+ wearable="hair"
+ edit_group="hair_style"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="784"
+ group="1"
+ clothing_morph="true"
+ name="Hair_Pigtails_Long"
+ wearable="hair"
+ edit_group="hair_style"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="786"
+ group="1"
+ name="Hair_Ponytail_Short"
+ wearable="hair"
+ edit_group="hair_style"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="787"
+ group="1"
+ name="Hair_Ponytail_Med"
+ wearable="hair"
+ edit_group="hair_style"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="788"
+ group="1"
+ name="Hair_Ponytail_Long"
+ clothing_morph="true"
+ wearable="hair"
+ edit_group="hair_style"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <!-- #end morph targets -->
+ </mesh>
+
+ <mesh
+ type="hairMesh"
+ lod="1"
+ file_name="avatar_hair_1.llm"
+ min_pixel_width="160"
+ reference="avatar_hair.llm">
+ </mesh>
+
+ <mesh
+ type="hairMesh"
+ lod="2"
+ file_name="avatar_hair_2.llm"
+ min_pixel_width="80"
+ reference="avatar_hair.llm">
+ </mesh>
+
+ <mesh
+ type="hairMesh"
+ lod="3"
+ file_name="avatar_hair_3.llm"
+ min_pixel_width="40"
+ reference="avatar_hair.llm">
+ </mesh>
+
+ <mesh
+ type="hairMesh"
+ lod="4"
+ file_name="avatar_hair_4.llm"
+ min_pixel_width="20"
+ reference="avatar_hair.llm">
+ </mesh>
+
+ <mesh
+ type="hairMesh"
+ lod="5"
+ file_name="avatar_hair_5.llm"
+ min_pixel_width="0"
+ reference="avatar_hair.llm">
+ </mesh>
+
+ <mesh
+ type="headMesh"
+ lod="0"
+ file_name="avatar_head.llm"
+ min_pixel_width="320">
+ <!--
+ begin morph targets
+ #############
+ tweakable morphs
+ #############
+ -->
+ <param
+ id="1"
+ group="0"
+ name="Big_Brow"
+ label="Brow Size"
+ wearable="shape"
+ edit_group="shape_head"
+ edit_group_order="7"
+ label_min="Small"
+ label_max="Large"
+ value_min="-.3"
+ value_max="2"
+ camera_elevation=".1"
+ camera_distance=".4"
+ camera_angle="45">
+ <param_morph />
+ </param>
+
+ <param
+ id="2"
+ group="0"
+ name="Nose_Big_Out"
+ label="Nose Size"
+ wearable="shape"
+ edit_group="shape_nose"
+ edit_group_order="1"
+ label_min="Small"
+ label_max="Large"
+ show_simple="true"
+ value_min="-0.8"
+ value_max="2.5"
+ camera_elevation=".1"
+ camera_distance=".35"
+ camera_angle="50">
+ <param_morph />
+ </param>
+
+ <param
+ id="4"
+ group="0"
+ name="Broad_Nostrils"
+ label="Nostril Width"
+ wearable="shape"
+ edit_group="shape_nose"
+ edit_group_order="3"
+ label_min="Narrow"
+ label_max="Broad"
+ value_min="-.5"
+ value_max="1"
+ camera_elevation=".1"
+ camera_distance=".3"
+ camera_angle="-20">
+ <param_morph />
+ </param>
+
+ <param
+ id="759"
+ group="0"
+ name="Low_Septum_Nose"
+ label="Nostril Division"
+ wearable="shape"
+ edit_group="shape_nose"
+ edit_group_order="3.5"
+ label_min="High"
+ label_max="Low"
+ value_min="-1"
+ value_max="1.5"
+ value_default="0.5"
+ camera_elevation=".1"
+ camera_distance=".3"
+ camera_angle="-20">
+ <param_morph />
+ </param>
+
+ <param
+ id="517"
+ group="0"
+ name="Wide_Nose"
+ label="Nose Width"
+ wearable="shape"
+ edit_group="shape_nose"
+ edit_group_order="2"
+ label_min="Narrow"
+ label_max="Wide"
+ show_simple="true"
+ value_min="-.5"
+ value_max="1"
+ camera_elevation=".1"
+ camera_distance=".3"
+ camera_angle="-20">
+ <param_morph />
+ </param>
+
+ <param
+ id="5"
+ group="0"
+ name="Cleft_Chin"
+ label="Chin Cleft"
+ wearable="shape"
+ edit_group="shape_chin"
+ edit_group_order="6"
+ label_min="Round"
+ label_max="Cleft"
+ value_min="-.1"
+ value_max="1"
+ camera_elevation="0"
+ camera_distance=".28"
+ camera_angle="-20">
+ <param_morph />
+ </param>
+
+ <param
+ id="6"
+ group="0"
+ name="Bulbous_Nose_Tip"
+ label="Nose Tip Shape"
+ wearable="shape"
+ edit_group="shape_nose"
+ edit_group_order="8"
+ label_min="Pointy"
+ label_max="Bulbous"
+ value_min="-.3"
+ value_max="1"
+ camera_elevation=".1"
+ camera_distance=".35"
+ camera_angle="15">
+ <param_morph />
+ </param>
+
+ <param
+ id="7"
+ group="0"
+ name="Weak_Chin"
+ label="Chin Angle"
+ wearable="shape"
+ edit_group="shape_chin"
+ edit_group_order="1"
+ label_min="Chin Out"
+ label_max="Chin In"
+ value_min="-.5"
+ value_max=".5"
+ camera_elevation=".1"
+ camera_distance=".4"
+ camera_angle="45">
+ <param_morph />
+ </param>
+
+ <param
+ id="8"
+ group="0"
+ name="Double_Chin"
+ label="Chin-Neck"
+ wearable="shape"
+ edit_group="shape_chin"
+ edit_group_order="8"
+ label_min="Tight Chin"
+ label_max="Double Chin"
+ value_min="-.5"
+ value_max="1.5"
+ camera_elevation="-.1"
+ camera_distance=".3"
+ camera_angle="60">
+ <param_morph />
+ </param>
+
+ <param
+ id="10"
+ group="0"
+ name="Sunken_Cheeks"
+ label="Lower Cheeks"
+ wearable="shape"
+ edit_group="shape_head"
+ edit_group_order="9"
+ label_min="Well-Fed"
+ label_max="Sunken"
+ show_simple="true"
+ value_min="-1.5"
+ value_max="3"
+ camera_elevation=".1"
+ camera_distance=".4"
+ camera_angle="5">
+ <param_morph />
+ </param>
+
+ <param
+ id="11"
+ group="0"
+ name="Noble_Nose_Bridge"
+ label="Upper Bridge"
+ wearable="shape"
+ edit_group="shape_nose"
+ edit_group_order="5"
+ label_min="Low"
+ label_max="High"
+ value_min="-.5"
+ value_max="1.5"
+ camera_elevation=".1"
+ camera_distance=".35"
+ camera_angle="70">
+ <param_morph />
+ </param>
+
+ <param
+ id="758"
+ group="0"
+ name="Lower_Bridge_Nose"
+ label="Lower Bridge"
+ wearable="shape"
+ edit_group="shape_nose"
+ edit_group_order="5.5"
+ label_min="Low"
+ label_max="High"
+ value_min="-1.5"
+ value_max="1.5"
+ camera_elevation=".1"
+ camera_distance=".35"
+ camera_angle="70">
+ <param_morph />
+ </param>
+
+ <param
+ id="12"
+ group="0"
+ name="Jowls"
+ wearable="shape"
+ edit_group="shape_chin"
+ edit_group_order="5"
+ label_min="Less"
+ label_max="More"
+ value_min="-.5"
+ value_max="2.5"
+ camera_elevation=".1"
+ camera_distance=".4"
+ camera_angle="0">
+ <param_morph />
+ </param>
+
+ <param
+ id="13"
+ group="0"
+ name="Cleft_Chin_Upper"
+ label="Upper Chin Cleft"
+ wearable="shape"
+ edit_group="shape_chin"
+ edit_group_order="7"
+ label_min="Round"
+ label_max="Cleft"
+ value_min="0"
+ value_max="1.5"
+ camera_elevation="0"
+ camera_distance=".28"
+ camera_angle="-20">
+ <param_morph />
+ </param>
+
+ <param
+ id="14"
+ group="0"
+ name="High_Cheek_Bones"
+ label="Cheek Bones"
+ wearable="shape"
+ edit_group="shape_head"
+ edit_group_order="10"
+ label_min="Low"
+ label_max="High"
+ value_min="-.5"
+ value_max="1"
+ camera_elevation=".1"
+ camera_distance=".3"
+ camera_angle="-20">
+ <param_morph />
+ </param>
+
+ <param
+ id="15"
+ group="0"
+ name="Ears_Out"
+ label="Ear Angle"
+ wearable="shape"
+ edit_group="shape_ears"
+ edit_group_order="2"
+ label_min="In"
+ label_max="Out"
+ value_min="-.5"
+ value_max="1.5"
+ camera_elevation=".1"
+ camera_distance=".3"
+ camera_angle="-20">
+ <param_morph />
+ </param>
+
+ <!--Pointy eyebrows became a driver/driven param with new max value for backwards compatibility between 1.0 and 1.1-->
+ <param
+ id="870"
+ group="1"
+ name="Pointy_Eyebrows"
+ label="Eyebrow Points"
+ wearable="hair"
+ edit_group="hair_eyebrows"
+ edit_group_order="4"
+ label_min="Smooth"
+ label_max="Pointy"
+ value_min="-.5"
+ value_max="1"
+ camera_elevation=".1"
+ camera_distance=".3">
+ <param_morph />
+ </param>
+
+ <param
+ id="17"
+ group="0"
+ name="Square_Jaw"
+ label="Jaw Shape"
+ wearable="shape"
+ edit_group="shape_chin"
+ edit_group_order="2"
+ label_min="Pointy"
+ label_max="Square"
+ value_min="-.5"
+ value_max="1"
+ camera_distance=".3"
+ camera_elevation=".04"
+ camera_angle="-20">
+ <param_morph />
+ </param>
+
+ <param
+ id="18"
+ group="0"
+ name="Puffy_Upper_Cheeks"
+ label="Upper Cheeks"
+ wearable="shape"
+ edit_group="shape_head"
+ edit_group_order="8"
+ label_min="Thin"
+ label_max="Puffy"
+ value_min="-1.5"
+ value_max="2.5"
+ camera_elevation=".1"
+ camera_distance=".3"
+ camera_angle="-20">
+ <param_morph />
+ </param>
+
+ <param
+ id="19"
+ group="0"
+ name="Upturned_Nose_Tip"
+ label="Nose Tip Angle"
+ wearable="shape"
+ edit_group="shape_nose"
+ edit_group_order="7"
+ label_min="Downturned"
+ label_max="Upturned"
+ value_min="-1.5"
+ value_max="1"
+ camera_elevation=".1"
+ camera_distance=".35"
+ camera_angle="15">
+ <param_morph />
+ </param>
+
+ <param
+ id="20"
+ group="0"
+ name="Bulbous_Nose"
+ label="Nose Thickness"
+ wearable="shape"
+ edit_group="shape_nose"
+ edit_group_order="4"
+ label_min="Thin Nose"
+ label_max="Bulbous Nose"
+ show_simple="true"
+ value_min="-.5"
+ value_max="1.5"
+ camera_elevation=".1"
+ camera_distance=".3">
+ <param_morph />
+ </param>
+
+ <param
+ id="21"
+ group="0"
+ name="Upper_Eyelid_Fold"
+ label="Upper Eyelid Fold"
+ wearable="shape"
+ edit_group="shape_eyes"
+ edit_group_order="5"
+ label_min="Uncreased"
+ label_max="Creased"
+ value_min="-0.2"
+ value_max="1.3"
+ camera_elevation=".1"
+ camera_distance=".35">
+ <param_morph />
+ </param>
+
+ <param
+ id="22"
+ group="0"
+ name="Attached_Earlobes"
+ label="Attached Earlobes"
+ wearable="shape"
+ edit_group="shape_ears"
+ edit_group_order="3"
+ label_min="Unattached"
+ label_max="Attached"
+ value_min="0"
+ value_max="1"
+ camera_elevation=".1"
+ camera_distance=".3"
+ camera_angle="45">
+ <param_morph />
+ </param>
+
+ <param
+ id="23"
+ group="0"
+ name="Baggy_Eyes"
+ label="Eye Bags"
+ wearable="shape"
+ edit_group="shape_eyes"
+ edit_group_order="6"
+ label_min="Smooth"
+ label_max="Baggy"
+ value_min="-.5"
+ value_max="1.5"
+ camera_elevation=".1"
+ camera_distance=".35">
+ <param_morph />
+ </param>
+
+ <param
+ id="765"
+ group="0"
+ name="Puffy_Lower_Lids"
+ label="Puffy Eyelids"
+ wearable="shape"
+ edit_group="shape_eyes"
+ edit_group_order="6.1"
+ label_min="Flat"
+ label_max="Puffy"
+ value_min="-.3"
+ value_max="2.5"
+ camera_elevation=".1"
+ camera_distance=".35">
+ <param_morph />
+ </param>
+
+ <param
+ id="24"
+ group="0"
+ name="Wide_Eyes"
+ label="Eye Opening"
+ wearable="shape"
+ edit_group="shape_eyes"
+ edit_group_order="1.1"
+ label_min="Narrow"
+ label_max="Wide"
+ value_min="-1.5"
+ value_max="2"
+ show_simple="true"
+ camera_elevation=".1"
+ camera_distance=".35">
+ <param_morph />
+ </param>
+
+ <param
+ id="25"
+ group="0"
+ name="Wide_Lip_Cleft"
+ label="Lip Cleft"
+ wearable="shape"
+ edit_group="shape_mouth"
+ edit_group_order="6"
+ label_min="Narrow"
+ label_max="Wide"
+ value_min="-.8"
+ value_max="1.5"
+ camera_elevation="0"
+ camera_distance=".28">
+ <param_morph />
+ </param>
+
+ <param
+ id="764"
+ group="0"
+ name="Lip_Cleft_Deep"
+ label="Lip Cleft Depth"
+ wearable="shape"
+ edit_group="shape_mouth"
+ edit_group_order="5.8"
+ label_min="Shallow"
+ label_max="Deep"
+ value_min="-.5"
+ value_max="1.2"
+ camera_elevation="0"
+ camera_distance=".28">
+ <param_morph />
+ </param>
+
+ <param
+ id="26"
+ group="1"
+ wearable="shape"
+ name="Lips_Thin"
+ edit_group="driven"
+ value_min="0"
+ value_max=".7">
+ <param_morph />
+ </param>
+
+ <param
+ id="27"
+ group="0"
+ name="Wide_Nose_Bridge"
+ label="Bridge Width"
+ wearable="shape"
+ edit_group="shape_nose"
+ edit_group_order="6"
+ label_min="Narrow"
+ label_max="Wide"
+ value_min="-1.3"
+ value_max="1.2"
+ camera_elevation=".1"
+ camera_distance=".3"
+ camera_angle="-20">
+ <param_morph />
+ </param>
+
+ <param
+ id="28"
+ group="1"
+ name="Lips_Fat"
+ wearable="shape"
+ edit_group="driven"
+ value_min="0"
+ value_max="2">
+ <param_morph />
+ </param>
+
+ <param
+ id="29"
+ group="1"
+ name="Wide_Upper_Lip"
+ wearable="shape"
+ edit_group="driven"
+ value_min="-.7"
+ value_max="1.3">
+ <param_morph />
+ </param>
+
+ <param
+ id="30"
+ group="1"
+ name="Wide_Lower_Lip"
+ wearable="shape"
+ edit_group="driven"
+ value_min="-.7"
+ value_max="1.3">
+ <param_morph />
+ </param>
+
+ <!--Arced eyebrows became a driver/driven param with new max value for backwards compatibility between 1.0 and 1.1-->
+ <param
+ id="872"
+ group="1"
+ name="Arced_Eyebrows"
+ label="Eyebrow Arc"
+ wearable="hair"
+ edit_group="hair_eyebrows"
+ edit_group_order="3"
+ label_min="Flat"
+ label_max="Arced"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <!--Lower eyebrows became a driver/driven param with new min value for backwards compatibility between 1.0 and 1.1-->
+ <param
+ id="871"
+ group="1"
+ name="Lower_Eyebrows"
+ label="Eyebrow Height"
+ show_simple="true"
+ wearable="hair"
+ edit_group="hair_eyebrows"
+ edit_group_order="2.5"
+ label_min="Higher"
+ label_max="Lower"
+ value_min="-2"
+ value_max="2">
+ <param_morph />
+ </param>
+
+ <param
+ id="35"
+ group="0"
+ name="Big_Ears"
+ label="Ear Size"
+ wearable="shape"
+ edit_group="shape_ears"
+ edit_group_order="1"
+ label_min="Small"
+ label_max="Large"
+ value_min="-1"
+ value_max="2"
+ camera_elevation=".1"
+ camera_distance=".3"
+ camera_angle="45">
+ <param_morph />
+ </param>
+
+ <param
+ id="796"
+ group="0"
+ name="Pointy_Ears"
+ label="Ear Tips"
+ wearable="shape"
+ edit_group="shape_ears"
+ edit_group_order="4"
+ label_min="Flat"
+ label_max="Pointy"
+ value_min="-.4"
+ value_max="3"
+ camera_elevation=".1"
+ camera_distance=".3"
+ camera_angle="45">
+ <param_morph />
+ </param>
+
+ <param
+ id="185"
+ group="0"
+ name="Deep_Chin"
+ label="Chin Depth"
+ wearable="shape"
+ edit_group="shape_chin"
+ edit_group_order="3"
+ label_min="Shallow"
+ label_max="Deep"
+ value_min="-1"
+ value_max="1"
+ camera_elevation=".1"
+ camera_distance=".4"
+ camera_angle="30">
+ <param_morph />
+ </param>
+
+ <param
+ id="186"
+ group="1"
+ name="Egg_Head"
+ label="Egg Head"
+ wearable="shape"
+ edit_group="shape_head"
+ label_min="Chin Heavy"
+ label_max="Forehead Heavy"
+ value_min="-1.3"
+ value_max="1"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="20">
+ <param_morph />
+ </param>
+
+ <param
+ id="187"
+ group="1"
+ name="Squash_Stretch_Head"
+ label="Squash/Stretch Head"
+ wearable="shape"
+ edit_group="shape_head"
+ label_min="Squash Head"
+ label_max="Stretch Head"
+ value_min="-.5"
+ value_max="1"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="20">
+ <param_morph>
+ <volume_morph
+ name="HEAD"
+ scale="-0.008 -0.006 0.015"/>
+ </param_morph>
+ </param>
+
+ <param
+ id="188"
+ group="1"
+ name="Square_Head"
+ wearable="shape"
+ label_min="Less Square"
+ label_max="More Square"
+ value_min="0"
+ value_max=".7"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="20">
+ <param_morph />
+ </param>
+
+ <param
+ id="189"
+ group="1"
+ wearable="shape"
+ name="Round_Head"
+ label_min="Less Round"
+ label_max="More Round"
+ value_min="0"
+ value_max="1"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="20">
+ <param_morph />
+ </param>
+
+ <param
+ id="194"
+ group="1"
+ name="Eye_Spread"
+ wearable="shape"
+ edit_group="shape_eyes"
+ label_min="Eyes Together"
+ label_max="Eyes Spread"
+ value_min="-2"
+ value_max="2">
+ <param_morph />
+ </param>
+
+ <param
+ id="400"
+ sex="male"
+ group="1"
+ name="Displace_Hair_Facial"
+ label="Hair Thickess"
+ wearable="hair"
+ edit_group="hair_facial"
+ label_min="Cropped Hair"
+ label_max="Bushy Hair"
+ value_min="0"
+ value_max="2">
+ <param_morph />
+ </param>
+
+ <param
+ id="506"
+ group="0"
+ name="Mouth_Height"
+ wearable="shape"
+ label="Mouth Position"
+ show_simple="true"
+ edit_group="shape_mouth"
+ edit_group_order="4"
+ label_min="High"
+ label_max="Low"
+ value_min="-2"
+ value_max="2"
+ camera_distance=".3"
+ camera_elevation=".04">
+ <param_morph />
+ </param>
+
+ <param
+ id="633"
+ group="1"
+ name="Fat_Head"
+ label="Fat Head"
+ wearable="shape"
+ edit_group="shape_body"
+ label_min="Skinny"
+ label_max="Fat"
+ value_min="0"
+ value_max="1"
+ camera_elevation=".3">
+ <param_morph/>
+ </param>
+
+ <param
+ id="630"
+ group="1"
+ name="Forehead_Round"
+ label="Round Forehead"
+ wearable="shape"
+ label_min="Less"
+ label_max="More"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="631"
+ group="1"
+ name="Forehead_Slant"
+ label="Slanted Forehead"
+ wearable="shape"
+ label_min="Less"
+ label_max="More"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="650"
+ group="0"
+ name="Eyelid_Corner_Up"
+ label="Outer Eye Corner"
+ wearable="shape"
+ edit_group="shape_eyes"
+ edit_group_order="4"
+ label_min="Corner Down"
+ label_max="Corner Up"
+ value_min="-1.3"
+ value_max="1.2"
+ camera_elevation=".1"
+ camera_distance=".30">
+ <param_morph />
+ </param>
+
+ <param
+ id="880"
+ group="0"
+ name="Eyelid_Inner_Corner_Up"
+ label="Inner Eye Corner"
+ wearable="shape"
+ edit_group="shape_eyes"
+ edit_group_order="4.2"
+ label_min="Corner Down"
+ label_max="Corner Up"
+ value_min="-1.3"
+ value_max="1.2"
+ camera_elevation=".1"
+ camera_distance=".30">
+ <param_morph />
+ </param>
+
+
+ <param
+ id="653"
+ group="0"
+ name="Tall_Lips"
+ wearable="shape"
+ label="Lip Fullness"
+ show_simple="true"
+ edit_group="shape_mouth"
+ edit_group_order="2"
+ label_min="Less Full"
+ label_max="More Full"
+ value_min="-1"
+ value_max="2"
+ camera_distance=".3"
+ camera_elevation=".04">
+ <param_morph />
+ </param>
+
+ <param
+ id="656"
+ group="0"
+ name="Crooked_Nose"
+ wearable="shape"
+ label="Crooked Nose"
+ edit_group="shape_nose"
+ edit_group_order="9"
+ label_min="Nose Left"
+ label_max="Nose Right"
+ value_min="-2"
+ value_max="2"
+ camera_distance=".3"
+ camera_elevation=".04"
+ camera_angle="-20">
+ <param_morph />
+ </param>
+
+ <param
+ id="657"
+ group="1"
+ name="Smile_Mouth"
+ wearable="shape"
+ label="Mouth Corner"
+ edit_group="shape_mouth"
+ label_min="Corner Normal"
+ label_max="Corner Up"
+ value_min="0"
+ value_max="1.4"
+ camera_distance=".3"
+ camera_elevation=".04">
+ <param_morph />
+ </param>
+
+ <param
+ id="658"
+ group="1"
+ name="Frown_Mouth"
+ wearable="shape"
+ label="Mouth Corner"
+ edit_group="shape_mouth"
+ label_min="Corner Normal"
+ label_max="Corner Down"
+ value_min="0"
+ value_max="1.2"
+ camera_distance=".3"
+ camera_elevation=".04">
+ <param_morph />
+ </param>
+
+ <param
+ id="797"
+ group="1"
+ name="Fat_Upper_Lip"
+ wearable="shape"
+ label="Fat Upper Lip"
+ edit_group="shape_mouth"
+ label_min="Normal Upper"
+ label_max="Fat Upper"
+ value_min="0"
+ value_max="1.5"
+ camera_distance=".3"
+ camera_elevation=".04">
+ <param_morph />
+ </param>
+
+ <param
+ id="798"
+ group="1"
+ name="Fat_Lower_Lip"
+ wearable="shape"
+ label="Fat Lower Lip"
+ edit_group="shape_mouth"
+ label_min="Normal Lower"
+ label_max="Fat Lower"
+ value_min="0"
+ value_max="1.5"
+ camera_distance=".3"
+ camera_elevation=".04">
+ <param_morph />
+ </param>
+
+ <param
+ id="660"
+ group="1"
+ name="Shear_Head"
+ wearable="shape"
+ label="Shear Face"
+ edit_group="shape_head"
+ label_min="Shear Left"
+ label_max="Shear Right"
+ value_min="-2"
+ value_max="2"
+ value_default="0"
+ camera_distance=".5"
+ camera_elevation=".04">
+ <param_morph />
+ </param>
+
+ <param
+ id="770"
+ group="1"
+ name="Elongate_Head"
+ wearable="shape"
+ label="Shear Face"
+ edit_group="shape_head"
+ label_min="Flat Head"
+ label_max="Long Head"
+ value_min="-1"
+ value_max="1"
+ value_default="0"
+ camera_distance=".5"
+ camera_elevation=".04">
+ <param_morph>
+ <volume_morph
+ name="HEAD"
+ scale="0.02 0.0 0.0"/>
+ </param_morph>
+ </param>
+
+ <param
+ id="663"
+ group="0"
+ name="Shift_Mouth"
+ wearable="shape"
+ label="Shift Mouth"
+ edit_group="shape_mouth"
+ edit_group_order="7"
+ label_min="Shift Left"
+ label_max="Shift Right"
+ value_min="-2"
+ value_max="2"
+ value_default="0"
+ camera_distance=".35"
+ camera_elevation=".04"
+ camera_angle="-20">
+ <param_morph />
+ </param>
+
+ <param
+ id="664"
+ group="0"
+ name="Pop_Eye"
+ wearable="shape"
+ label="Eye Pop"
+ edit_group="shape_eyes"
+ edit_group_order="8"
+ label_min="Pop Right Eye"
+ label_max="Pop Left Eye"
+ value_min="-1.3"
+ value_max="1.3"
+ value_default="0"
+ camera_elevation=".1"
+ camera_distance=".35">
+ <param_morph />
+ </param>
+
+ <param
+ id="760"
+ group="0"
+ name="Jaw_Angle"
+ wearable="shape"
+ label="Jaw Angle"
+ edit_group="shape_chin"
+ edit_group_order="3.5"
+ label_min="Low Jaw"
+ label_max="High Jaw"
+ value_min="-1.2"
+ value_max="2"
+ value_default="0"
+ camera_distance=".5"
+ camera_elevation=".04"
+ camera_angle="70">
+ <param_morph />
+ </param>
+
+ <param
+ id="665"
+ group="0"
+ name="Jaw_Jut"
+ wearable="shape"
+ label="Jaw Jut"
+ edit_group="shape_chin"
+ edit_group_order="4"
+ label_min="Overbite"
+ label_max="Underbite"
+ value_min="-2"
+ value_max="2"
+ value_default="0"
+ camera_distance=".5"
+ camera_elevation=".04"
+ camera_angle="70">
+ <param_morph />
+ </param>
+
+ <param
+ id="686"
+ group="1"
+ name="Head_Eyes_Big"
+ wearable="shape"
+ label="Eye Size"
+ edit_group="shape_eyes"
+ label_min="Beady Eyes"
+ label_max="Anime Eyes"
+ show_simple="true"
+ value_min="-2"
+ value_max="2"
+ value_default="0">
+ <param_morph />
+ </param>
+
+ <param
+ id="767"
+ group="1"
+ name="Bug_Eyed_Head"
+ wearable="shape"
+ label="Eye Depth"
+ edit_group="shape_eyes"
+ edit_group_order="4.5"
+ label_min="Sunken Eyes"
+ label_max="Bug Eyes"
+ value_min="-2"
+ value_max="2"
+ value_default="0">
+ <param_morph />
+ </param>
+
+ <!--
+ #Fat_Lips = Fat_Lips 34 1 0 1
+ #Wide_Lips = Wide_Lips 35 1 0 1
+ #Wide_Nose = Wide_Nose 36 1 0 1
+ -->
+ <!--
+ ##############
+ # Facial Expression morphs
+ ##############
+ -->
+ <param
+ id="300"
+ group="1"
+ name="Express_Closed_Mouth"
+ value_default="1"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="301"
+ group="1"
+ name="Express_Tongue_Out"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="302"
+ group="1"
+ name="Express_Surprise_Emote"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="303"
+ group="1"
+ name="Express_Wink_Emote"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="304"
+ group="1"
+ name="Express_Embarrassed_Emote"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="305"
+ group="1"
+ name="Express_Shrug_Emote"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="306"
+ group="1"
+ name="Express_Kiss"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="307"
+ group="1"
+ name="Express_Bored_Emote"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="308"
+ group="1"
+ name="Express_Repulsed_Emote"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="309"
+ group="1"
+ name="Express_Disdain"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="310"
+ group="1"
+ name="Express_Afraid_Emote"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="311"
+ group="1"
+ name="Express_Worry_Emote"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="312"
+ group="1"
+ name="Express_Cry_Emote"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="313"
+ group="1"
+ name="Express_Sad_Emote"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="314"
+ group="1"
+ name="Express_Anger_Emote"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="315"
+ group="1"
+ name="Express_Frown"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="316"
+ group="1"
+ name="Express_Laugh_Emote"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="317"
+ group="1"
+ name="Express_Toothsmile"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="318"
+ group="1"
+ name="Express_Smile"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="632"
+ group="1"
+ name="Express_Open_Mouth"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <!--
+ ##############
+ # Lipsync morphs
+ ##############
+ -->
+
+ <param
+ id="70"
+ group="1"
+ name="Lipsync_Aah"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="71"
+ group="1"
+ name="Lipsync_Ooh"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <!--
+ ##############
+ # other morphs (not user controlled)
+ ##############
+ -->
+ <param
+ id="40"
+ group="1"
+ name="Male_Head"
+ wearable="shape"
+ edit_group="driven"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="41"
+ group="1"
+ name="Old"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <!--
+ ##############
+ # animatable morphs
+ ##############
+ -->
+ <param
+ id="51"
+ group="1"
+ name="Furrowed_Eyebrows"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="53"
+ group="1"
+ name="Surprised_Eyebrows"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="54"
+ group="1"
+ name="Worried_Eyebrows"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="55"
+ group="1"
+ name="Frown_Mouth"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="57"
+ group="1"
+ name="Smile_Mouth"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="58"
+ group="1"
+ name="Blink_Left"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="59"
+ group="1"
+ name="Blink_Right"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <!--
+ #end morph targets
+ -->
+ </mesh>
+
+ <mesh
+ type="headMesh"
+ lod="1"
+ file_name="avatar_head_1.llm"
+ min_pixel_width="160"
+ reference="avatar_head.llm">
+ </mesh>
+
+ <mesh
+ type="headMesh"
+ lod="2"
+ file_name="avatar_head_2.llm"
+ min_pixel_width="80"
+ reference="avatar_head.llm">
+ </mesh>
+
+ <mesh
+ type="headMesh"
+ lod="3"
+ file_name="avatar_head_3.llm"
+ min_pixel_width="40"
+ reference="avatar_head.llm">
+ </mesh>
+
+ <mesh
+ type="headMesh"
+ lod="4"
+ file_name="avatar_head_4.llm"
+ min_pixel_width="0"
+ reference="avatar_head.llm">
+ </mesh>
+
+ <mesh
+ type="eyelashMesh"
+ lod="0"
+ file_name="avatar_eyelashes.llm"
+ min_pixel_width="320">
+ <param
+ shared="1"
+ id="660"
+ group="1"
+ name="Shear_Head"
+ wearable="shape"
+ label="Shear Face"
+ edit_group="shape_head"
+ label_min="Shear Left"
+ label_max="Shear Right"
+ value_min="-2"
+ value_max="2"
+ value_default="0"
+ camera_distance=".5"
+ camera_elevation=".04">
+ <param_morph />
+ </param>
+
+ <param
+ shared="1"
+ id="770"
+ group="1"
+ name="Elongate_Head"
+ wearable="shape"
+ label="Shear Face"
+ edit_group="shape_head"
+ label_min="Flat Head"
+ label_max="Long Head"
+ value_min="-1"
+ value_max="1"
+ value_default="0"
+ camera_distance=".5"
+ camera_elevation=".04">
+ <param_morph />
+ </param>
+
+ <param
+ shared="1"
+ id="664"
+ group="0"
+ name="Pop_Eye"
+ wearable="shape"
+ label="Eye Pop"
+ edit_group="shape_eyes"
+ edit_group_order="8"
+ label_min="Pop Right Eye"
+ label_max="Pop Left Eye"
+ value_min="-2"
+ value_max="2"
+ value_default="0"
+ camera_distance=".5"
+ camera_elevation=".04"
+ camera_angle="-20">
+ <param_morph />
+ </param>
+
+ <param
+ shared="1"
+ id="21"
+ group="0"
+ name="Upper_Eyelid_Fold"
+ label="Upper Eyelid Fold"
+ wearable="shape"
+ edit_group="shape_eyes"
+ label_min="Uncreased"
+ label_max="Creased"
+ value_min="-0.2"
+ value_max="1.3"
+ camera_elevation=".1"
+ camera_distance=".35">
+ <param_morph />
+ </param>
+
+ <param
+ shared="1"
+ id="24"
+ group="0"
+ name="Wide_Eyes"
+ label="Eye Opening"
+ wearable="shape"
+ edit_group="shape_eyes"
+ label_min="Narrow"
+ label_max="Wide"
+ show_simple="true"
+ value_min="-1.5"
+ value_max="2"
+ camera_elevation=".1"
+ camera_distance=".3">
+ <param_morph />
+ </param>
+
+ <param
+ shared="1"
+ id="186"
+ group="1"
+ name="Egg_Head"
+ label="Egg Head"
+ wearable="shape"
+ edit_group="shape_head"
+ label_min="Chin Heavy"
+ label_max="Forehead Heavy"
+ value_min="-1.3"
+ value_max="1"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="20">
+ <param_morph />
+ </param>
+
+ <param
+ shared="1"
+ id="187"
+ group="1"
+ name="Squash_Stretch_Head"
+ label="Squash/Stretch Head"
+ wearable="shape"
+ edit_group="shape_head"
+ label_min="Squash Head"
+ label_max="Stretch Head"
+ value_min="-.5"
+ value_max="1"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="20">
+ <param_morph />
+ </param>
+
+ <param
+ shared="1"
+ id="194"
+ group="1"
+ name="Eye_Spread"
+ edit_group="shape_eyes"
+ label_min="Eyes Together"
+ label_max="Eyes Spread"
+ value_min="-2"
+ value_max="2">
+ <param_morph />
+ </param>
+
+ <param
+ id="518"
+ group="0"
+ name="Eyelashes_Long"
+ wearable="shape"
+ label="Eyelash Length"
+ edit_group="shape_eyes"
+ edit_group_order="7"
+ label_min="Short"
+ label_max="Long"
+ value_min="-.3"
+ value_max="1.5"
+ camera_elevation=".1"
+ camera_distance=".30"
+ camera_angle="-20">
+ <param_morph />
+ </param>
+
+ <param
+ shared="1"
+ id="650"
+ group="0"
+ name="Eyelid_Corner_Up"
+ label="Outer Eye Corner"
+ wearable="shape"
+ edit_group="shape_eyes"
+ label_min="Corner Down"
+ label_max="Corner Up"
+ value_min="-1.3"
+ value_max="1.2"
+ camera_elevation=".1"
+ camera_distance=".3">
+ <param_morph />
+ </param>
+
+
+ <param
+ shared="1"
+ id="880"
+ group="0"
+ name="Eyelid_Inner_Corner_Up"
+ label="Inner Eye Corner"
+ wearable="shape"
+ edit_group="shape_eyes"
+ label_min="Corner Down"
+ label_max="Corner Up"
+ value_min="-1.3"
+ value_max="1.2"
+ camera_elevation=".1"
+ camera_distance=".3">
+ <param_morph />
+ </param>
+
+ <param
+ shared="1"
+ id="686"
+ group="1"
+ name="Head_Eyes_Big"
+ wearable="shape"
+ label="Eye Size"
+ edit_group="shape_eyes"
+ label_min="Beady Eyes"
+ label_max="Anime Eyes"
+ value_min="-2"
+ value_max="2"
+ show_simple="true"
+ value_default="0">
+ <param_morph />
+ </param>
+
+ <param
+ shared="1"
+ id="767"
+ group="1"
+ name="Bug_Eyed_Head"
+ wearable="shape"
+ label="Eye Depth"
+ edit_group="shape_eyes"
+ edit_group_order="4.5"
+ label_min="Sunken Eyes"
+ label_max="Bug Eyes"
+ value_min="-2"
+ value_max="2"
+ value_default="0">
+ <param_morph />
+ </param>
+
+ <!--
+ ##############
+ # Facial Expression morphs
+ ##############
+ -->
+ <param
+ shared="1"
+ id="301"
+ group="1"
+ name="Express_Tongue_Out"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ shared="1"
+ id="302"
+ group="1"
+ name="Express_Surprise_Emote"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ shared="1"
+ id="303"
+ group="1"
+ name="Express_Wink_Emote"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ shared="1"
+ id="304"
+ group="1"
+ name="Express_Embarrassed_Emote"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ shared="1"
+ id="305"
+ group="1"
+ name="Express_Shrug_Emote"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ shared="1"
+ id="306"
+ group="1"
+ name="Express_Kiss"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ shared="1"
+ id="307"
+ group="1"
+ name="Express_Bored_Emote"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ shared="1"
+ id="308"
+ group="1"
+ name="Express_Repulsed_Emote"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ shared="1"
+ id="309"
+ group="1"
+ name="Express_Disdain"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ shared="1"
+ id="310"
+ group="1"
+ name="Express_Afraid_Emote"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ shared="1"
+ id="312"
+ group="1"
+ name="Express_Cry_Emote"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ shared="1"
+ id="313"
+ group="1"
+ name="Express_Sad_Emote"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ shared="1"
+ id="314"
+ group="1"
+ name="Express_Anger_Emote"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ shared="1"
+ id="315"
+ group="1"
+ name="Express_Frown"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ shared="1"
+ id="316"
+ group="1"
+ name="Express_Laugh_Emote"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ shared="1"
+ id="317"
+ group="1"
+ name="Express_Toothsmile"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ shared="1"
+ id="318"
+ group="1"
+ name="Express_Smile"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <!--
+ ##############
+ # other morphs (not user controlled)
+ ##############
+ -->
+ <param
+ shared="1"
+ id="41"
+ group="1"
+ name="Old"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <!--
+ ##############
+ # animatable morphs
+ ##############
+ -->
+ <param
+ shared="1"
+ id="58"
+ group="1"
+ name="Blink_Left"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ shared="1"
+ id="59"
+ group="1"
+ name="Blink_Right"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+ </mesh>
+
+ <!--
+ #headMesh2 =
+ #headMesh3 =
+ -->
+ <mesh
+ type="upperBodyMesh"
+ lod="0"
+ file_name="avatar_upper_body.llm"
+ min_pixel_width="320">
+ <!--
+ #begin morph targets
+ #############
+ # tweakable morphs
+ #############
+ -->
+ <param
+ id="104"
+ group="1"
+ name="Big_Belly_Torso"
+ wearable="shape"
+ edit_group="driven"
+ value_min="0"
+ value_max="1">
+ <param_morph>
+ <volume_morph
+ name="BELLY"
+ scale="0.075 0.04 0.03"
+ pos="0.07 0 -0.07"/>
+ <volume_morph
+ name="PELVIS"
+ scale="0.075 0.04 0.03"
+ pos="0.07 0 -0.02"/>
+ </param_morph>
+ </param>
+
+ <param
+ id="626"
+ sex="female"
+ group="1"
+ name="Big_Chest"
+ label="Chest Size"
+ wearable="shape"
+ edit_group="shape_torso"
+ label_min="Small"
+ label_max="Large"
+ value_min="0"
+ value_max="1"
+ camera_elevation=".1"
+ camera_distance="1"
+ camera_angle="15">
+ <param_morph>
+ <volume_morph
+ name="LEFT_PEC"
+ scale="0.0273 0.0273 0.0273"
+ pos="0.038 0.024 -0.016"/>
+ <volume_morph
+ name="RIGHT_PEC"
+ scale="0.0273 0.0273 0.0273"
+ pos="0.038 -0.024 -0.016"/>
+ </param_morph>
+ </param>
+
+ <param
+ id="627"
+ sex="female"
+ group="1"
+ name="Small_Chest"
+ label="Chest Size"
+ wearable="shape"
+ edit_group="shape_torso"
+ label_min="Large"
+ label_max="Small"
+ value_min="0"
+ value_max="1"
+ camera_elevation="0"
+ camera_distance=".28">
+ <param_morph>
+ <volume_morph
+ name="LEFT_PEC"
+ scale="-0.05 0.0 0.0"
+ pos="-0.01 -0.01 -0.02"/>
+ <volume_morph
+ name="RIGHT_PEC"
+ scale="-0.05 0.0 0.0"
+ pos="-0.01 -0.01 -0.02"/>
+ </param_morph>
+ </param>
+
+ <param
+ id="843"
+ sex="female"
+ group="1"
+ name="No_Chest"
+ label="Chest Size"
+ wearable="shape"
+ edit_group="shape_torso"
+ label_min="Some"
+ label_max="None"
+ value_min="0"
+ value_max="1"
+ camera_elevation="0"
+ camera_distance=".28">
+ <param_morph>
+ <volume_morph
+ name="LEFT_PEC"
+ scale="-0.051 0.0 0.0"
+ pos="-0.02 -0.01 -0.03"/>
+ <volume_morph
+ name="RIGHT_PEC"
+ scale="-0.051 0.0 0.0"
+ pos="-0.02 -0.01 -0.03"/>
+ </param_morph>
+ </param>
+
+ <param
+ id="106"
+ group="1"
+ name="Muscular_Torso"
+ label="Torso Muscles"
+ show_simple="true"
+ wearable="shape"
+ edit_group="shape_torso"
+ label_min="Regular"
+ label_max="Muscular"
+ value_min="0"
+ value_max="1.4"
+ camera_elevation=".3"
+ camera_distance="1.2">
+ <param_morph>
+ <volume_morph
+ name="L_CLAVICLE"
+ scale="0.02 0.0 0.005"
+ pos="0.0 0 0.005"/>
+ <volume_morph
+ name="L_UPPER_ARM"
+ scale="0.015 0.0 0.005"
+ pos="0.015 0 0"/>
+ <volume_morph
+ name="L_LOWER_ARM"
+ scale="0.005 0.0 0.005"
+ pos="0.005 0 0"/>
+ <volume_morph
+ name="R_CLAVICLE"
+ scale="0.02 0.0 0.005"
+ pos="0.0 0 0.005"/>
+ <volume_morph
+ name="R_UPPER_ARM"
+ scale="0.015 0.0 0.005"
+ pos="0.015 0 0"/>
+ <volume_morph
+ name="R_LOWER_ARM"
+ scale="0.005 0.0 0.005"
+ pos="0.005 0 0"/>
+ </param_morph>
+ </param>
+
+ <param
+ id="648"
+ group="1"
+ sex="female"
+ name="Scrawny_Torso"
+ label="Torso Muscles"
+ show_simple="true"
+ wearable="shape"
+ edit_group="shape_torso"
+ label_min="Regular"
+ label_max="Scrawny"
+ value_min="0"
+ value_max="1.3"
+ camera_elevation=".3"
+ camera_distance="1.2">
+ <param_morph>
+ <volume_morph
+ name="BELLY"
+ scale="0.0 -0.01 0.0"
+ pos="0.0 0.0 0"/>
+ <volume_morph
+ name="UPPER_BACK"
+ scale="-0.01 -0.01 0.0"
+ pos="0.0 0.0 0"/>
+ <volume_morph
+ name="CHEST"
+ scale="-0.01 -0.01 0.0"
+ pos="0.01 0.0 0"/>
+ <volume_morph
+ name="L_CLAVICLE"
+ scale="0.0 -0.03 -0.005"
+ pos="0.0 0 -0.005"/>
+ <volume_morph
+ name="L_UPPER_ARM"
+ scale="-0.01 -0.01 -0.02"
+ pos="0 0 0"/>
+ <volume_morph
+ name="L_LOWER_ARM"
+ scale="-0.005 0.0 -0.01"
+ pos="-0.005 0 0"/>
+ <volume_morph
+ name="R_CLAVICLE"
+ scale="0.0 -0.03 -0.005"
+ pos="0.0 0 -0.005"/>
+ <volume_morph
+ name="R_UPPER_ARM"
+ scale="-0.01 -0.01 -0.02"
+ pos="0 0 0"/>
+ <volume_morph
+ name="R_LOWER_ARM"
+ scale="-0.005 0.0 -0.01"
+ pos="-0.005 0 0"/>
+ </param_morph>
+ </param>
+
+ <param
+ id="677"
+ group="1"
+ sex="male"
+ name="Scrawny_Torso_Male"
+ label="Torso Scrawny"
+ wearable="shape"
+ edit_group="shape_torso"
+ label_min="Regular"
+ label_max="Scrawny"
+ value_min="0"
+ value_max="1.3"
+ camera_elevation=".3"
+ camera_distance="1.2">
+ <param_morph>
+ <volume_morph
+ name="BELLY"
+ scale="-0.01 -0.01 0.0"
+ pos="0.01 0.0 0"/>
+ <volume_morph
+ name="UPPER_BACK"
+ scale="-0.01 -0.01 0.0"
+ pos="0.0 0.0 0"/>
+ <volume_morph
+ name="CHEST"
+ scale="-0.02 -0.02 0.0"
+ pos="0.01 0.0 0"/>
+ <volume_morph
+ name="L_CLAVICLE"
+ scale="0.0 -0.03 -0.005"
+ pos="0.0 0 -0.005"/>
+ <volume_morph
+ name="L_UPPER_ARM"
+ scale="-0.01 -0.01 -0.02"
+ pos="0 0 0"/>
+ <volume_morph
+ name="L_LOWER_ARM"
+ scale="-0.005 0.0 -0.01"
+ pos="-0.005 0 0"/>
+ <volume_morph
+ name="R_CLAVICLE"
+ scale="0.0 -0.03 -0.005"
+ pos="0.0 0 -0.005"/>
+ <volume_morph
+ name="R_UPPER_ARM"
+ scale="-0.01 -0.01 -0.02"
+ pos="0 0 0"/>
+ <volume_morph
+ name="R_LOWER_ARM"
+ scale="-0.005 0.0 -0.01"
+ pos="-0.005 0 0"/>
+ </param_morph>
+ </param>
+
+ <param
+ id="634"
+ group="1"
+ name="Fat_Torso"
+ label="Fat Torso"
+ wearable="shape"
+ edit_group="shape_body"
+ label_min="skinny"
+ label_max="fat"
+ value_min="0"
+ value_max="1"
+ camera_elevation=".3">
+ <param_morph>
+ <volume_morph
+ name="CHEST"
+ scale="0.02 0.03 0.03"
+ pos="0 0 -0.03"/>
+ <volume_morph
+ name="PELVIS"
+ scale="0.02 0.03 0.03"
+ pos="0 0 -0.03"/>
+ <volume_morph
+ name="UPPER_BACK"
+ scale="0.01 0.03 0.0"
+ pos="-0.03 0 0"/>
+ <volume_morph
+ name="LOWER_BACK"
+ scale="0.04 0.06 0.0"
+ pos="-0.06 0 0"/>
+ <volume_morph
+ name="LEFT_HANDLE"
+ pos="0.0 0.08 0.0"/>
+ <volume_morph
+ name="RIGHT_HANDLE"
+ pos="0.0 -0.08 0.0"/>
+ <volume_morph
+ name="LEFT_PEC"
+ scale="0.0367 0.0367 0.016"
+ pos="0.00 -0.005 -0.013"/>
+ <volume_morph
+ name="RIGHT_PEC"
+ scale="0.0367 0.0367 0.016"
+ pos="0.00 0.005 -0.013"/>
+ <volume_morph
+ name="BELLY"
+ scale="0.09 0.08 0.07"
+ pos="0 0 -0.05"/>
+ <volume_morph
+ name="L_CLAVICLE"
+ scale="0.0 0.0 0.015"/>
+ <volume_morph
+ name="L_UPPER_ARM"
+ scale="0.02 0.0 0.02"
+ pos="0.0 0.0 -0.02"/>
+ <volume_morph
+ name="L_LOWER_ARM"
+ scale="0.01 0.0 0.01"
+ pos="0.0 0.0 -0.01"/>
+ <volume_morph
+ name="R_CLAVICLE"
+ scale="0.0 0.0 0.015"/>
+ <volume_morph
+ name="R_UPPER_ARM"
+ scale="0.02 0.0 0.02"
+ pos="0.0 0.0 -0.02"/>
+ <volume_morph
+ name="R_LOWER_ARM"
+ scale="0.01 0.0 0.01"
+ pos="0.0 0.0 -0.01"/>
+ <volume_morph
+ name="NECK"
+ scale="0.015 0.01 0.0"/>
+ <volume_morph
+ name="HEAD"
+ scale="0.0 0.0 0.01"
+ pos="0 0 -0.01"/>
+ </param_morph>
+ </param>
+
+ <param
+ id="507"
+ group="0"
+ sex="female"
+ name="Breast_Gravity"
+ label="Breast Buoyancy"
+ wearable="shape"
+ edit_group="shape_torso"
+ edit_group_order="7"
+ label_min="Less Gravity"
+ label_max="More Gravity"
+ value_default="0"
+ value_min="-1.5"
+ value_max="2"
+ camera_elevation=".3"
+ camera_distance=".8">
+ <param_morph>
+ <volume_morph
+ name="LEFT_PEC"
+ scale="0.0 0.0 0.0"
+ pos="0.004 0.0 -0.01"/>
+ <volume_morph
+ name="RIGHT_PEC"
+ scale="0.0 0.0 0.0"
+ pos="0.004 0.0 -0.01"/>
+ </param_morph>
+ </param>
+
+ <param
+ id="628"
+ group="1"
+ name="Displace_Loose_Upperbody"
+ label="Shirt Fit"
+ wearable="shirt"
+ edit_group="driven"
+ clothing_morph="true"
+ value_min="0"
+ value_max="1"
+ value_default="0">
+ <param_morph />
+ </param>
+
+ <param
+ id="840"
+ group="0"
+ name="Shirtsleeve_flair"
+ label="Sleeve Looseness"
+ show_simple="true"
+ wearable="shirt"
+ edit_group="shirt"
+ edit_group_order="6"
+ clothing_morph="true"
+ label_min="Tight Sleeves"
+ label_max="Loose Sleeves"
+ value_min="0"
+ value_max="1.5"
+ camera_distance="1.8"
+ camera_angle="30"
+ camera_elevation="-.3">
+ <param_morph />
+ </param>
+
+ <param
+ id="855"
+ group="1"
+ name="Love_Handles"
+ wearable="shape"
+ edit_group="driven"
+ value_default="0"
+ value_min="-1"
+ value_max="2">
+ <param_morph>
+ <volume_morph
+ name="BELLY"
+ scale="0.0 0.02 0.0"/>
+ <volume_morph
+ name="LOWER_BACK"
+ scale="0.0 0.02 0.0"/>
+ <volume_morph
+ name="LEFT_HANDLE"
+ pos="0.0 0.025 0.0"/>
+ <volume_morph
+ name="RIGHT_HANDLE"
+ pos="0.0 -0.025 0.0"/>
+ </param_morph>
+ </param>
+
+ <param
+ id="684"
+ group="0"
+ sex="female"
+ name="Breast_Female_Cleavage"
+ label="Breast Cleavage"
+ wearable="shape"
+ edit_group="shape_torso"
+ edit_group_order="8"
+ label_min="Separate"
+ label_max="Join"
+ value_default="0"
+ value_min="-.3"
+ value_max="1.3"
+ camera_elevation=".3"
+ camera_distance=".8">
+ <param_morph>
+ <volume_morph
+ name="LEFT_PEC"
+ scale="0.0 0.0 0.0"
+ pos="0.0 -0.026 0.0"/>
+ <volume_morph
+ name="RIGHT_PEC"
+ scale="0.0 0.0 0.0"
+ pos="0.0 0.026 0.0"/>
+ </param_morph>
+ </param>
+
+ <param
+ id="685"
+ group="0"
+ sex="male"
+ name="Chest_Male_No_Pecs"
+ label="Pectorals"
+ wearable="shape"
+ edit_group="shape_torso"
+ edit_group_order="5"
+ label_min="Big Pectorals"
+ label_max="Sunken Chest"
+ value_default="0"
+ value_min="-0.5"
+ value_max="1.1"
+ camera_elevation=".3"
+ camera_distance="1.2">
+ <param_morph>
+ <volume_morph
+ name="LEFT_PEC"
+ scale="0.0 0.0 0.0"
+ pos="-0.03 -0.024 -0.01"/>
+ <volume_morph
+ name="RIGHT_PEC"
+ scale="0.0 0.0 0.0"
+ pos="-0.03 0.024 -0.01"/>
+ </param_morph>
+ </param>
+
+ <!-- ############# #
+ other morphs (not user controlled)
+ ############# -->
+ <param
+ id="100"
+ group="1"
+ name="Male_Torso"
+ wearable="shape"
+ edit_group="driven"
+ label_min="Male_Torso"
+ value_min="0"
+ value_max="1">
+ <param_morph>
+ <volume_morph
+ name="CHEST"
+ scale="0.03 0.04 0.02"
+ pos="-0.03 0 -0.01"/>
+ <volume_morph
+ name="BELLY"
+ scale="0.03 0.03 0.0"
+ pos="-0.03 0 0.02"/>
+ <volume_morph
+ name="LEFT_PEC"
+ scale="0.0 0.0 0.0"
+ pos="0.008 -0.03 0.01"/>
+ <volume_morph
+ name="RIGHT_PEC"
+ scale="0.0 0.0 0.0"
+ pos="0.008 0.03 0.01"/>
+ <volume_morph
+ name="L_CLAVICLE"
+ scale="0.02 0.0 0.01"
+ pos="-0.02 0 0"/>
+ <volume_morph
+ name="L_UPPER_ARM"
+ scale="0.01 0.0 0.01"
+ pos="0.0 0.0 -0.01"/>
+ <volume_morph
+ name="L_LOWER_ARM"
+ scale="0.005 0.0 0.005"
+ pos="0.0 0.0 -0.005"/>
+ <volume_morph
+ name="R_CLAVICLE"
+ scale="0.02 0.0 0.01"
+ pos="-0.02 0 0"/>
+ <volume_morph
+ name="R_UPPER_ARM"
+ scale="0.01 0.0 0.01"
+ pos="0.0 0.0 -0.01"/>
+ <volume_morph
+ name="R_LOWER_ARM"
+ scale="0.005 0.0 0.005"
+ pos="0.0 0.0 -0.005"/>
+ <volume_morph
+ name="NECK"
+ scale="0.015 0.01 0.0"/>
+ <volume_morph
+ name="HEAD"
+ scale="0.0 0.0 0.01"
+ pos="0 0 -0.01"/>
+ </param_morph>
+ </param>
+
+ <!--
+ ##############
+ # animatable morphs
+ ##############
+ -->
+ <param
+ id="101"
+ group="1"
+ name="Hands_Relaxed"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="102"
+ group="1"
+ name="Hands_Point"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="103"
+ group="1"
+ name="Hands_Fist"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="666"
+ group="1"
+ name="Hands_Relaxed_L"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="667"
+ group="1"
+ name="Hands_Point_L"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="668"
+ group="1"
+ name="Hands_Fist_L"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="669"
+ group="1"
+ name="Hands_Relaxed_R"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="670"
+ group="1"
+ name="Hands_Point_R"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="671"
+ group="1"
+ name="Hands_Fist_R"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="672"
+ group="1"
+ name="Hands_Typing"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="766"
+ group="1"
+ name="Hands_Salute_R"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="791"
+ group="1"
+ name="Hands_Peace_R"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="792"
+ group="1"
+ name="Hands_Spread_R"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <!--
+ #############
+ # physics morphs (not user controlled)
+ #############
+ -->
+ <param
+ id="1200"
+ group="1"
+ sex="female"
+ name="Breast_Physics_UpDown_Driven"
+ wearable="physics"
+ edit_group="driven"
+ value_default="0"
+ value_min="-3"
+ value_max="3">
+ <param_morph>
+ <volume_morph
+ name="LEFT_PEC"
+ scale="0.0 0.0 0.0"
+ pos="0.0 0.0 -0.01"/>
+ <volume_morph
+ name="RIGHT_PEC"
+ scale="0.0 0.0 0.0"
+ pos="0.0 0.0 -0.01"/>
+ </param_morph>
+ </param>
+
+ <param
+ id="1201"
+ group="1"
+ sex="female"
+ name="Breast_Physics_InOut_Driven"
+ wearable="physics"
+ edit_group="driven"
+ value_default="0"
+ value_min="-1.25"
+ value_max="1.25">
+ <param_morph>
+ <volume_morph
+ name="LEFT_PEC"
+ scale="0.0 0.0 0.0"
+ pos="0.0 -0.026 0.0"/>
+ <volume_morph
+ name="RIGHT_PEC"
+ scale="0.0 0.0 0.0"
+ pos="0.0 0.026 -0.0"/>
+ </param_morph>
+ </param>
+
+ <param
+ id="1204"
+ group="1"
+ name="Belly_Physics_Torso_UpDown_Driven"
+ wearable="physics"
+ edit_group="driven"
+ value_default="0"
+ value_min="-1"
+ value_max="1">
+ <param_morph>
+ <volume_morph
+ name="BELLY"
+ scale="0.0 0.0 0.0"
+ pos="0.0 0.0 0.05"/>
+ </param_morph>
+ </param>
+
+ <param
+ id="1207"
+ group="1"
+ name="Breast_Physics_LeftRight_Driven"
+ wearable="physics"
+ edit_group="driven"
+ value_default="0"
+ value_min="-2"
+ value_max="2">
+ <param_morph>
+ <volume_morph
+ name="LEFT_PEC"
+ scale="0.0 0.0 0.0"
+ pos="0.0 0.03 0.0"/>
+ <volume_morph
+ name="RIGHT_PEC"
+ scale="0.0 0.0 0.0"
+ pos="0.0 0.03 0.0"/>
+ </param_morph>
+ </param>
+
+ <!--
+ #end morph targets
+ -->
+
+ </mesh>
+
+ <mesh
+ type="upperBodyMesh"
+ lod="1"
+ file_name="avatar_upper_body_1.llm"
+ min_pixel_width="160"
+ reference="avatar_upper_body.llm">
+ </mesh>
+
+ <mesh
+ type="upperBodyMesh"
+ lod="2"
+ file_name="avatar_upper_body_2.llm"
+ min_pixel_width="80"
+ reference="avatar_upper_body.llm">
+ </mesh>
+
+ <mesh
+ type="upperBodyMesh"
+ lod="3"
+ file_name="avatar_upper_body_3.llm"
+ min_pixel_width="40"
+ reference="avatar_upper_body.llm">
+ </mesh>
+
+ <mesh
+ type="upperBodyMesh"
+ lod="4"
+ file_name="avatar_upper_body_4.llm"
+ min_pixel_width="0"
+ reference="avatar_upper_body.llm">
+ </mesh>
+
+ <!--
+ #upperBodyMesh2 =
+ #upperBodyMesh3 =
+ -->
+ <mesh
+ type="lowerBodyMesh"
+ lod="0"
+ file_name="avatar_lower_body.llm"
+ min_pixel_width="320">
+ <!--
+ #begin morph targets
+ #############
+ # tweakable morphs
+ #############
+ -->
+ <param
+ id="156"
+ group="1"
+ name="Big_Belly_Legs"
+ wearable="shape"
+ edit_group="driven"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+
+ <param
+ id="151"
+ group="1"
+ name="Big_Butt_Legs"
+ label="Butt Size"
+ wearable="shape"
+ edit_group="shape_legs"
+ label_min="Regular"
+ label_max="Large"
+ value_min="0"
+ value_max="1">
+ <param_morph>
+ <volume_morph
+ name="PELVIS"
+ scale="0.03 0.0 0.02"
+ pos="-0.03 0 -0.025"/>
+ </param_morph>
+ </param>
+
+ <param
+ id="794"
+ group="1"
+ name="Small_Butt"
+ label="Butt Size"
+ wearable="shape"
+ edit_group="shape_legs"
+ label_min="Regular"
+ label_max="Small"
+ value_min="0"
+ value_max="1">
+ <param_morph>
+ <volume_morph
+ name="PELVIS"
+ scale="-0.01 0.0 0.0"
+ pos="0.01 0 0.0"/>
+ <volume_morph
+ name="BUTT"
+ scale="0.0 0.0886 0.0"
+ pos="0.03 0 0.0"/>
+ </param_morph>
+ </param>
+
+ <param
+ id="152"
+ group="1"
+ name="Muscular_Legs"
+ label="Leg Muscles"
+ show_simple="true"
+ wearable="shape"
+ edit_group="shape_legs"
+ label_min="Regular Muscles"
+ label_max="More Muscles"
+ value_min="0"
+ value_max="1.5"
+ camera_distance="1.3"
+ camera_elevation="-.5">
+ <param_morph>
+ <volume_morph
+ name="L_UPPER_LEG"
+ scale="0.015 0.015 0.0"
+ pos="0.0 0 0.0"/>
+ <volume_morph
+ name="L_LOWER_LEG"
+ scale="0.01 0.01 0.0"
+ pos="0.0 0 0.0"/>
+ <volume_morph
+ name="R_UPPER_LEG"
+ scale="0.015 0.015 0.0"
+ pos="0.0 0 0.0"/>
+ <volume_morph
+ name="R_LOWER_LEG"
+ scale="0.01 0.01 0.0"
+ pos="0.0 0 0.0"/>
+ </param_morph>
+ </param>
+
+ <param
+ id="651"
+ group="1"
+ name="Scrawny_Legs"
+ label="Scrawny Leg"
+ wearable="shape"
+ edit_group="shape_legs"
+ label_min="Regular Muscles"
+ label_max="Less Muscles"
+ value_min="0"
+ value_max="1.5"
+ camera_distance="1.3"
+ camera_elevation="-.5">
+ <param_morph>
+ <volume_morph
+ name="L_UPPER_LEG"
+ scale="-0.03 -0.03 0.0"
+ pos="0.0 0 0.0"/>
+ <volume_morph
+ name="L_LOWER_LEG"
+ scale="-0.015 -0.015 0.0"
+ pos="0.0 0 0.0"/>
+ <volume_morph
+ name="R_UPPER_LEG"
+ scale="-0.03 -0.03 0.0"
+ pos="0.0 0 0.0"/>
+ <volume_morph
+ name="R_LOWER_LEG"
+ scale="-0.015 -0.015 0.0"
+ pos="0.0 0 0.0"/>
+ </param_morph>
+ </param>
+
+ <param
+ id="853"
+ group="1"
+ name="Bowed_Legs"
+ label="Knee Angle"
+ wearable="shape"
+ value_min="-1"
+ value_max="1">
+ <param_morph>
+ <volume_morph
+ name="L_UPPER_LEG"
+ pos="0.0 0.03 0.0"/>
+ <volume_morph
+ name="L_LOWER_LEG"
+ pos="0.0 0.03 0.0"/>
+ <volume_morph
+ name="R_UPPER_LEG"
+ pos="0.0 -0.03 0.0"/>
+ <volume_morph
+ name="R_LOWER_LEG"
+ pos="0.0 -0.03 0.0"/>
+ </param_morph>
+ </param>
+
+ <param
+ id="500"
+ group="1"
+ name="Shoe_Heel_Height"
+ label="Heel Height"
+ wearable="shoes"
+ edit_group="shoes"
+ label_min="Low Heels"
+ label_max="High Heels"
+ value_min="0"
+ value_max="1"
+ camera_distance="1.5"
+ camera_elevation="-.5">
+ <param_morph />
+ </param>
+
+ <param
+ id="501"
+ group="1"
+ name="Shoe_Platform_Height"
+ label="Platform Height"
+ wearable="shoes"
+ edit_group="shoes"
+ label_min="Low Platforms"
+ label_max="High Platforms"
+ value_min="0"
+ value_max="1"
+ camera_distance="1.5"
+ camera_elevation="-.5">
+ <param_morph />
+ </param>
+
+ <param
+ id="508"
+ group="0"
+ name="Shoe_Platform_Width"
+ label="Platform Width"
+ wearable="shoes"
+ edit_group="shoes"
+ edit_group_order="7"
+ label_min="Narrow"
+ label_max="Wide"
+ value_min="-1"
+ value_max="2"
+ camera_angle="15"
+ camera_distance="1.5"
+ camera_elevation="-1">
+ <param_morph />
+ </param>
+
+ <param
+ id="509"
+ group="1"
+ name="Shoe_Heel_Point"
+ label="Heel Shape"
+ wearable="shoes"
+ edit_group="shoes"
+ label_min="Default Heels"
+ label_max="Pointy Heels"
+ value_min="0"
+ value_max="1"
+ camera_distance="1.3"
+ camera_elevation="-.5">
+ <param_morph />
+ </param>
+
+ <param
+ id="510"
+ group="1"
+ name="Shoe_Heel_Thick"
+ label="Heel Shape"
+ wearable="shoes"
+ edit_group="shoes"
+ label_min="default Heels"
+ label_max="Thick Heels"
+ value_min="0"
+ value_max="1"
+ camera_distance="1.3"
+ camera_elevation="-.5">
+ <param_morph />
+ </param>
+
+ <param
+ id="511"
+ group="1"
+ name="Shoe_Toe_Point"
+ label="Toe Shape"
+ wearable="shoes"
+ edit_group="shoes"
+ label_min="Default Toe"
+ label_max="Pointy Toe"
+ value_min="0"
+ value_max="1"
+ camera_distance="1.3"
+ camera_elevation="-.5">
+ <param_morph />
+ </param>
+
+ <param
+ id="512"
+ group="1"
+ name="Shoe_Toe_Square"
+ label="Toe Shape"
+ wearable="shoes"
+ edit_group="shoes"
+ label_min="Default Toe"
+ label_max="Square Toe"
+ value_min="0"
+ value_max="1"
+ camera_distance="1.5"
+ camera_elevation="-.5">
+ <param_morph />
+ </param>
+
+ <param
+ id="654"
+ group="0"
+ name="Shoe_Toe_Thick"
+ label="Toe Thickness"
+ wearable="shoes"
+ edit_group="shoes"
+ edit_group_order="5"
+ label_min="Flat Toe"
+ label_max="Thick Toe"
+ value_min="0"
+ value_max="2"
+ camera_angle="15"
+ camera_distance="1.5"
+ camera_elevation="-1">
+ <param_morph />
+ </param>
+
+ <param
+ id="515"
+ group="0"
+ name="Foot_Size"
+ label="Foot Size"
+ wearable="shape"
+ edit_group="shape_legs"
+ edit_group_order="6"
+ label_min="Small"
+ label_max="Big"
+ value_min="-1"
+ value_max="3"
+ camera_angle="45"
+ camera_distance="1.1"
+ camera_elevation="-1">
+ <param_morph>
+ <volume_morph
+ name="L_FOOT"
+ scale="0.02 0.01 0.0"
+ pos="0.01 0 0"/>
+ <volume_morph
+ name="R_FOOT"
+ scale="0.02 0.01 0.0"
+ pos="0.01 0 0"/>
+ </param_morph>
+ </param>
+
+ <param
+ id="516"
+ group="1"
+ name="Displace_Loose_Lowerbody"
+ label="Pants Fit"
+ wearable="pants"
+ edit_group="driven"
+ clothing_morph="true"
+ value_min="0"
+ value_max="1"
+ value_default="0">
+ <param_morph />
+ </param>
+
+ <param
+ id="625"
+ group="0"
+ name="Leg_Pantflair"
+ label="Cuff Flare"
+ show_simple="true"
+ wearable="pants"
+ edit_group="pants"
+ edit_group_order="3"
+ clothing_morph="true"
+ label_min="Tight Cuffs"
+ label_max="Flared Cuffs"
+ value_min="0"
+ value_max="1.5"
+ camera_distance="1.8"
+ camera_angle="30"
+ camera_elevation="-.3">
+ <param_morph />
+ </param>
+
+ <param
+ id="793"
+ group="1"
+ name="Leg_Longcuffs"
+ label="Longcuffs"
+ wearable="pants"
+ edit_group="driven"
+ clothing_morph="true"
+ value_min="0"
+ value_max="3"
+ value_default="0">
+ <param_morph />
+ </param>
+
+ <param
+ id="638"
+ group="0"
+ name="Low_Crotch"
+ label="Pants Crotch"
+ wearable="pants"
+ clothing_morph="true"
+ edit_group="pants"
+ edit_group_order="4"
+ label_min="High and Tight"
+ label_max="Low and Loose"
+ value_min="0"
+ value_max="1.3"
+ camera_distance="1.2"
+ camera_angle="-20"
+ camera_elevation="-.3">
+ <param_morph />
+ </param>
+
+ <param
+ id="635"
+ group="1"
+ name="Fat_Legs"
+ label="Fat Torso"
+ wearable="shape"
+ edit_group="shape_body"
+ label_min="skinny"
+ label_max="fat"
+ value_min="0"
+ value_max="1">
+ <param_morph>
+ <volume_morph
+ name="PELVIS"
+ scale="0.03 0.06 0.0"/>
+ <volume_morph
+ name="R_UPPER_LEG"
+ scale="0.02 0.02 0.0"
+ pos="0.0 -0.02 0.0"/>
+ <volume_morph
+ name="R_LOWER_LEG"
+ scale="0.01 0.01 0.0"/>
+ <volume_morph
+ name="L_UPPER_LEG"
+ scale="0.02 0.02 0.0"
+ pos="0.0 0.02 0.0"/>
+ <volume_morph
+ name="L_LOWER_LEG"
+ scale="0.01 0.01 0.0"/>
+ </param_morph>
+ </param>
+
+ <param
+ id="854"
+ group="1"
+ name="Saddlebags"
+ wearable="shape"
+ edit_group="driven"
+ value_min="-.5"
+ value_max="3">
+ <param_morph>
+ <volume_morph
+ name="PELVIS"
+ scale="0.0 0.025 0.0"/>
+ </param_morph>
+
+ </param>
+
+ <param
+ id="879"
+ group="0"
+ sex="male"
+ name="Male_Package"
+ label="Package"
+ wearable="shape"
+ edit_group="shape_legs"
+ edit_group_order="4.6"
+ label_min="Coin Purse"
+ label_max="Duffle Bag"
+ value_default="0"
+ value_min="-.5"
+ value_max="2"
+ camera_angle="60"
+ camera_distance=".6">
+ <param_morph />
+ </param>
+
+ <!--
+ #############
+ # other morphs (not user controlled)
+ #############
+ -->
+ <param
+ id="153"
+ group="1"
+ name="Male_Legs"
+ wearable="shape"
+ edit_group="driven"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <!--
+ #############
+ # physics morphs (not user controlled)
+ #############
+ -->
+ <param
+ id="1202"
+ group="1"
+ name="Belly_Physics_Legs_UpDown_Driven"
+ wearable="physics"
+ cross_wearable="true"
+ edit_group="driven"
+ value_min="-1"
+ value_max="1">
+ <param_morph />
+ </param>
+
+
+ <param
+ id="1205"
+ group="1"
+ name="Butt_Physics_UpDown_Driven"
+ wearable="physics"
+ cross_wearable="true"
+ edit_group="driven"
+ value_default="0"
+ value_min="-1"
+ value_max="1">
+ <param_morph>
+ <volume_morph
+ name="BUTT"
+ pos="0.0 0.0 0.05"/>
+ </param_morph>
+ </param>
+
+ <param
+ id="1206"
+ group="1"
+ name="Butt_Physics_LeftRight_Driven"
+ wearable="physics"
+ cross_wearable="true"
+ edit_group="driven"
+ value_default="0"
+ value_min="-1"
+ value_max="1">
+ <param_morph>
+ <volume_morph
+ name="BUTT"
+ pos="0.0 0.05 0.0"/>
+ </param_morph>
+ </param>
+
+ <!--
+ #end morph targets
+ -->
+
+ </mesh>
+
+ <mesh
+ type="lowerBodyMesh"
+ lod="1"
+ file_name="avatar_lower_body_1.llm"
+ min_pixel_width="160"
+ reference="avatar_lower_body.llm">
+ </mesh>
+
+ <mesh
+ type="lowerBodyMesh"
+ lod="2"
+ file_name="avatar_lower_body_2.llm"
+ min_pixel_width="80"
+ reference="avatar_lower_body.llm">
+ </mesh>
+
+ <mesh
+ type="lowerBodyMesh"
+ lod="3"
+ file_name="avatar_lower_body_3.llm"
+ min_pixel_width="40"
+ reference="avatar_lower_body.llm">
+ </mesh>
+
+ <mesh
+ type="lowerBodyMesh"
+ lod="4"
+ file_name="avatar_lower_body_4.llm"
+ min_pixel_width="0"
+ reference="avatar_lower_body.llm">
+ </mesh>
+
+ <!--
+ #lowerBodyMesh2 =
+ #lowerBodyMesh3 =
+ -->
+ <!--
+ #eyeLidLeftMesh =
+ -->
+ <mesh
+ type="eyeBallLeftMesh"
+ lod="0"
+ file_name="avatar_eye.llm"
+ min_pixel_width="320">
+ <!-- begin morph_params -->
+ <param
+ id="679"
+ group="1"
+ name="Eyeball_Size"
+ label="Eyeball Size"
+ wearable="shape"
+ edit_group="shape_eyes"
+ label_min="small eye"
+ label_max="big eye"
+ value_min="-.25"
+ value_max=".10">
+ <param_morph />
+ </param>
+
+ <param
+ id="687"
+ group="1"
+ name="Eyeball_Size"
+ label="Big Eyeball"
+ wearable="shape"
+ edit_group="shape_eyes"
+ label_min="small eye"
+ label_max="big eye"
+ value_min="-.25"
+ value_max=".25">
+ <param_morph />
+ </param>
+ </mesh>
+
+ <mesh
+ type="eyeBallLeftMesh"
+ lod="1"
+ file_name="avatar_eye_1.llm"
+ min_pixel_width="80">
+ <!-- begin morph_params -->
+ <param
+ id="694"
+ group="1"
+ name="Eyeball_Size"
+ label="Eyeball Size"
+ wearable="shape"
+ edit_group="shape_eyes"
+ label_min="small eye"
+ label_max="big eye"
+ value_min="-.25"
+ value_max=".10">
+ <param_morph />
+ </param>
+
+ <param
+ id="695"
+ group="1"
+ name="Eyeball_Size"
+ label="Big Eyeball"
+ wearable="shape"
+ edit_group="shape_eyes"
+ label_min="small eye"
+ label_max="big eye"
+ value_min="-.25"
+ value_max=".25">
+ <param_morph />
+ </param>
+ </mesh>
+
+ <!--
+ #eyeLidRightMesh =
+ -->
+ <mesh
+ type="eyeBallRightMesh"
+ lod="0"
+ file_name="avatar_eye.llm"
+ min_pixel_width="320">
+ <!-- begin morph_params -->
+ <param
+ id="680"
+ group="1"
+ name="Eyeball_Size"
+ label="Eyeball Size"
+ wearable="shape"
+ label_min="small eye"
+ label_max="big eye"
+ value_min="-.25"
+ value_max=".10">
+ <param_morph />
+ </param>
+
+ <param
+ id="688"
+ group="1"
+ name="Eyeball_Size"
+ label="Big Eyeball"
+ wearable="shape"
+ label_min="small eye"
+ label_max="big eye"
+ value_min="-.25"
+ value_max=".25">
+ <param_morph />
+ </param>
+ </mesh>
+
+ <mesh
+ type="eyeBallRightMesh"
+ lod="1"
+ file_name="avatar_eye_1.llm"
+ min_pixel_width="80">
+ <!-- begin morph_params -->
+ <param
+ id="681"
+ group="1"
+ name="Eyeball_Size"
+ label="Eyeball Size"
+ wearable="shape"
+ edit_group="shape_eyes"
+ label_min="small eye"
+ label_max="big eye"
+ value_min="-.25"
+ value_max=".10">
+ <param_morph />
+ </param>
+
+ <param
+ id="691"
+ group="1"
+ name="Eyeball_Size"
+ label="Big Eyeball"
+ wearable="shape"
+ edit_group="shape_eyes"
+ label_min="small eye"
+ label_max="big eye"
+ value_min="-.25"
+ value_max=".25">
+ <param_morph />
+ </param>
+ </mesh>
+
+ <mesh
+ type="skirtMesh"
+ lod="0"
+ file_name="avatar_skirt.llm"
+ min_pixel_width="320">
+ <param
+ id="845"
+ group="1"
+ name="skirt_poofy"
+ label="poofy skirt"
+ clothing_morph="true"
+ wearable="skirt"
+ edit_group="skirt"
+ label_min="less poofy"
+ label_max="more poofy"
+ value_min="0"
+ value_max="1.5">
+ <param_morph />
+ </param>
+
+ <param
+ id="846"
+ group="1"
+ name="skirt_loose"
+ label="loose skirt"
+ clothing_morph="true"
+ wearable="skirt"
+ edit_group="skirt"
+ label_min="form fitting"
+ label_max="loose"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="866"
+ group="1"
+ name="skirt_tight"
+ label="tight skirt"
+ clothing_morph="true"
+ wearable="skirt"
+ edit_group="skirt"
+ label_min="form fitting"
+ label_max="loose"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="867"
+ group="1"
+ name="skirt_smallbutt"
+ label="tight skirt"
+ clothing_morph="false"
+ wearable="skirt"
+ edit_group="skirt"
+ cross_wearable="true"
+ label_min="form fitting"
+ label_max="loose"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="848"
+ group="0"
+ name="skirt_bustle"
+ label="bustle skirt"
+ clothing_morph="true"
+ wearable="skirt"
+ edit_group_order="3"
+ edit_group="skirt"
+ label_min="no bustle"
+ label_max="more bustle"
+ value_min="0"
+ value_max="2"
+ value_default=".2"
+ camera_angle="100"
+ camera_distance="1.3"
+ camera_elevation="-.5">
+ <param_morph />
+ </param>
+
+ <param
+ id="847"
+ group="1"
+ name="skirt_bowlegs"
+ label="legs skirt"
+ wearable="skirt"
+ edit_group="driven"
+ cross_wearable="true"
+ value_min="-1"
+ value_max="1"
+ value_default="0">
+ <param_morph />
+ </param>
+
+ <param
+ id="852"
+ group="1"
+ name="skirt_bigbutt"
+ wearable="skirt"
+ edit_group="driven"
+ cross_wearable="true"
+ label="bigbutt skirt"
+ label_min="less"
+ label_max="more"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="849"
+ group="1"
+ name="skirt_belly"
+ wearable="skirt"
+ edit_group="driven"
+ cross_wearable="true"
+ label="big belly skirt"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="850"
+ group="1"
+ wearable="skirt"
+ edit_group="driven"
+ cross_wearable="true"
+ name="skirt_saddlebags"
+ value_min="-.5"
+ value_max="3">
+ <param_morph />
+ </param>
+
+ <param
+ id="851"
+ group="1"
+ name="skirt_chubby"
+ wearable="skirt"
+ edit_group="driven"
+ cross_wearable="true"
+ label_min="less"
+ label_max="more"
+ value_min="0"
+ value_max="1"
+ value_default="0">
+ <param_morph />
+ </param>
+
+ <param
+ id="856"
+ group="1"
+ name="skirt_lovehandles"
+ wearable="skirt"
+ edit_group="driven"
+ cross_wearable="true"
+ label_min="less"
+ label_max="more"
+ value_min="-1"
+ value_max="2"
+ value_default="0">
+ <param_morph />
+ </param>
+
+ <!--
+ #############
+ # other morphs (not user controlled)
+ #############
+ -->
+ <param
+ id="857"
+ group="1"
+ name="skirt_male"
+ wearable="skirt"
+ edit_group="driven"
+ cross_wearable="true"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <!--
+ #############
+ # physics morphs (not user controlled)
+ #############
+ -->
+ <param
+ id="1203"
+ group="1"
+ name="Belly_Physics_Skirt_UpDown_Driven"
+ wearable="physics"
+ cross_wearable="true"
+ edit_group="driven"
+ value_default="0"
+ value_min="-1"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ </mesh>
+
+ <mesh
+ type="skirtMesh"
+ lod="1"
+ file_name="avatar_skirt_1.llm"
+ min_pixel_width="160"
+ reference="avatar_skirt.llm">
+ </mesh>
+
+ <mesh
+ type="skirtMesh"
+ lod="2"
+ file_name="avatar_skirt_2.llm"
+ min_pixel_width="80"
+ reference="avatar_skirt.llm">
+ </mesh>
+
+ <mesh
+ type="skirtMesh"
+ lod="3"
+ file_name="avatar_skirt_3.llm"
+ min_pixel_width="40"
+ reference="avatar_skirt.llm">
+ </mesh>
+
+ <mesh
+ type="skirtMesh"
+ lod="4"
+ file_name="avatar_skirt_4.llm"
+ min_pixel_width="0"
+ reference="avatar_skirt.llm">
+ </mesh>
+
+ <!-- =========================================================== -->
+ <global_color
+ name="skin_color">
+ <param
+ id="111"
+ group="0"
+ wearable="skin"
+ edit_group="skin_color"
+ edit_group_order="1"
+ name="Pigment"
+ show_simple="true"
+ label_min="Light"
+ label_max="Dark"
+ value_min="0"
+ value_max="1"
+ value_default=".5">
+ <param_color>
+ <value
+ color="252, 215, 200, 255" />
+
+ <value
+ color="240, 177, 112, 255" />
+
+ <value
+ color="90, 40, 16, 255" />
+
+ <value
+ color="29, 9, 6, 255" />
+ </param_color>
+ </param>
+
+ <param
+ id="110"
+ group="0"
+ wearable="skin"
+ edit_group="skin_color"
+ edit_group_order="2"
+ name="Red Skin"
+ label="Ruddiness"
+ label_min="Pale"
+ label_max="Ruddy"
+ value_min="0"
+ value_max="0.1">
+ <param_color
+ operation="blend">
+ <value
+ color="218, 41, 37, 255" />
+ </param_color>
+ </param>
+
+ <param
+ id="108"
+ group="0"
+ wearable="skin"
+ edit_group="skin_color"
+ edit_group_order="3"
+ name="Rainbow Color"
+ show_simple="true"
+ label_min="None"
+ label_max="Wild"
+ value_min="0"
+ value_max="1"
+ camera_elevation=".1"
+ camera_distance=".5">
+ <param_color>
+ <value
+ color=" 0, 0, 0, 255" />
+
+ <value
+ color="255, 0, 255, 255" />
+
+ <value
+ color="255, 0, 0, 255" />
+
+ <value
+ color="255, 255, 0, 255" />
+
+ <value
+ color=" 0, 255, 0, 255" />
+
+ <value
+ color=" 0, 255, 255, 255" />
+
+ <value
+ color=" 0, 0, 255, 255" />
+
+ <value
+ color="255, 0, 255, 255" />
+ </param_color>
+ </param>
+ </global_color>
+
+ <!-- =========================================================== -->
+ <global_color
+ name="hair_color">
+ <param
+ id="114"
+ group="0"
+ wearable="hair"
+ edit_group="hair_color"
+ edit_group_order="3"
+ name="Blonde Hair"
+ show_simple="true"
+ label_min="Black"
+ label_max="Blonde"
+ value_min="0"
+ value_max="1"
+ value_default=".5"
+ camera_elevation=".1"
+ camera_distance=".5">
+ <param_color>
+ <value
+ color="0, 0, 0, 255" />
+
+ <value
+ color="22, 6, 6, 255" />
+
+ <value
+ color="29, 9, 6, 255" />
+
+ <value
+ color="45, 21, 11, 255" />
+
+ <value
+ color="78, 39, 11, 255" />
+
+ <value
+ color="90, 53, 16, 255" />
+
+ <value
+ color="136, 92, 21, 255" />
+
+ <value
+ color="150, 106, 33, 255" />
+
+ <value
+ color="198, 156, 74, 255" />
+
+ <value
+ color="233, 192, 103, 255" />
+
+ <value
+ color="238, 205, 136, 255" />
+ </param_color>
+ </param>
+
+ <param
+ id="113"
+ group="0"
+ wearable="hair"
+ edit_group="hair_color"
+ edit_group_order="4"
+ name="Red Hair"
+ show_simple="true"
+ label_min="No Red"
+ label_max="Very Red"
+ value_min="0"
+ value_max="1"
+ camera_elevation=".1"
+ camera_distance=".5">
+ <param_color>
+ <value
+ color="0, 0, 0, 255" />
+
+ <value
+ color="118, 47, 19, 255" />
+ </param_color>
+ </param>
+
+ <param
+ id="115"
+ group="0"
+ wearable="hair"
+ edit_group="hair_color"
+ edit_group_order="1"
+ name="White Hair"
+ show_simple="true"
+ label_min="No White"
+ label_max="All White"
+ value_min="0"
+ value_max="1"
+ camera_elevation=".1"
+ camera_distance=".5">
+ <param_color>
+ <value
+ color="0, 0, 0, 255" />
+
+ <value
+ color="255, 255, 255, 255" />
+ </param_color>
+ </param>
+
+ <param
+ id="112"
+ group="0"
+ wearable="hair"
+ edit_group="hair_color"
+ edit_group_order="2"
+ name="Rainbow Color"
+ show_simple="true"
+ label_min="None"
+ label_max="Wild"
+ value_min="0"
+ value_max="1"
+ camera_elevation=".1"
+ camera_distance=".5">
+ <param_color>
+ <value
+ color=" 0, 0, 0, 255" />
+
+ <value
+ color="255, 0, 255, 255" />
+
+ <value
+ color="255, 0, 0, 255" />
+
+ <value
+ color="255, 255, 0, 255" />
+
+ <value
+ color=" 0, 255, 0, 255" />
+
+ <value
+ color=" 0, 255, 255, 255" />
+
+ <value
+ color=" 0, 0, 255, 255" />
+
+ <value
+ color="255, 0, 255, 255" />
+ </param_color>
+ </param>
+ </global_color>
+
+ <!-- =========================================================== -->
+ <global_color
+ name="eye_color">
+ <param
+ id="99"
+ group="0"
+ wearable="eyes"
+ edit_group="eyes"
+ edit_group_order="1"
+ name="Eye Color"
+ show_simple="true"
+ label_min="Natural"
+ label_max="Unnatural"
+ value_min="0"
+ value_max="1"
+ value_default="0"
+ camera_elevation=".1"
+ camera_distance=".3">
+ <!-- default to natural brown eyes-->
+ <param_color>
+ <value
+ color="50, 25, 5, 255" />
+
+ <!-- natural dark brown eyes-->
+ <value
+ color="109, 55, 15, 255" />
+
+ <!-- natural brown eyes-->
+ <value
+ color="150, 93, 49, 255" />
+
+ <!-- natural light brown eyes-->
+ <value
+ color="152, 118, 25, 255" />
+
+ <!--natural hazel eyes-->
+ <value
+ color="95, 179, 107, 255" />
+
+ <!--natural green eyes-->
+ <value
+ color="87, 192, 191, 255" />
+
+ <!--natural aqua eyes-->
+ <value
+ color="95, 172, 179, 255" />
+
+ <!--natural blue eyes-->
+ <value
+ color="128, 128, 128, 255" />
+
+ <!--natural grey eyes-->
+ <value
+ color="0, 0, 0, 255" />
+
+ <!--black eyes-->
+ <value
+ color="255, 255, 0, 255" />
+
+ <!--bright yellow eyes-->
+ <value
+ color=" 0, 255, 0, 255" />
+
+ <!-- bright green eyes-->
+ <value
+ color=" 0, 255, 255, 255" />
+
+ <!-- bright cyan eyes-->
+ <value
+ color=" 0, 0, 255, 255" />
+
+ <!--bright blue eyes-->
+ <value
+ color="255, 0, 255, 255" />
+
+ <!-- bright violet eyes-->
+ <value
+ color="255, 0, 0, 255" />
+
+ <!--bright red eyes-->
+ </param_color>
+ </param>
+
+ <param
+ id="98"
+ group="0"
+ wearable="eyes"
+ edit_group="eyes"
+ edit_group_order="2"
+ name="Eye Lightness"
+ show_simple="true"
+ label_min="Darker"
+ label_max="Lighter"
+ value_min="0"
+ value_max="1"
+ camera_elevation=".1"
+ camera_distance=".3">
+ <param_color>
+ <value
+ color="0, 0, 0, 0" />
+
+ <value
+ color="255, 255, 255, 255" />
+ </param_color>
+ </param>
+ </global_color>
+
+ <!-- =========================================================== -->
+ <layer_set
+ body_region="hair"
+ width="512"
+ height="512"
+ clear_alpha="false">
+ <layer
+ name="base"
+ global_color="hair_color"
+ write_all_channels="true">
+ <texture
+ local_texture="hair_grain" />
+ </layer>
+
+ <layer
+ name="hair texture alpha layer"
+ visibility_mask="TRUE">
+ <texture
+ local_texture="hair_grain" />
+ </layer>
+
+ <layer
+ name="hair alpha"
+ visibility_mask="TRUE">
+ <texture
+ local_texture="hair_alpha" />
+ </layer>
+
+ </layer_set>
+ <!-- =========================================================== -->
+
+ <layer_set
+ body_region="head"
+ width="512"
+ height="512">
+ <layer
+ name="head bump base"
+ fixed_color = "128,128,128,255"
+ render_pass="bump">
+ </layer>
+
+ <layer
+ name="head bump definition"
+ render_pass="bump">
+
+
+ <texture
+ tga_file="bump_head_base.tga"
+ file_is_mask="FALSE"/>
+
+ <param
+ id="873"
+ group="1"
+ wearable="skin"
+ edit_group="driven"
+ edit_group_order="12"
+ name="Bump base"
+ value_min="0"
+ value_max="1">
+ <param_alpha
+ domain="0" />
+ </param>
+ </layer>
+
+ <layer
+ name="base"
+ global_color="skin_color">
+ <texture
+ tga_file="head_skingrain.tga" />
+ </layer>
+
+ <layer
+ name="headcolor">
+ <texture
+ tga_file="head_color.tga" />
+ </layer>
+
+ <layer
+ name="shadow">
+ <texture
+ tga_file="head_shading_alpha.tga"
+ file_is_mask="TRUE" />
+
+ <param
+ id="158"
+ group="1"
+ wearable="skin"
+ name="Shading"
+ value_min="0"
+ value_max="1">
+ <param_color>
+ <value
+ color="0, 0, 0, 0" />
+
+ <value
+ color="0, 0, 0, 128" />
+ </param_color>
+ </param>
+ </layer>
+
+ <layer
+ name="highlight">
+ <texture
+ tga_file="head_highlights_alpha.tga"
+file_is_mask="TRUE" />
+
+
+ <param
+ id="159"
+ group="1"
+ name="Shading"
+ wearable="skin"
+ value_min="0"
+ value_max="1">
+ <param_color>
+ <value
+color="255, 255, 255, 0" />
+
+
+ <value
+ color="255, 255, 255, 64" />
+ </param_color>
+ </param>
+ </layer>
+ <layer
+ name="rosyface">
+ <texture
+ tga_file="rosyface_alpha.tga"
+ file_is_mask="true" />
+
+ <param
+ id="116"
+ group="0"
+ wearable="skin"
+ edit_group="skin_facedetail"
+ edit_group_order="4"
+ name="Rosy Complexion"
+ label_min="Less Rosy"
+ label_max="More Rosy"
+ value_min="0"
+ value_max="1"
+ camera_distance=".3"
+ camera_elevation=".07">
+ <param_color>
+ <value
+ color="198, 71, 71, 0" />
+
+ <value
+ color="198, 71, 71, 255" />
+ </param_color>
+ </param>
+ </layer>
+
+ <layer
+ name="lips">
+ <texture
+ tga_file="lips_mask.tga"
+ file_is_mask="true" />
+
+ <param
+ id="117"
+ group="0"
+ wearable="skin"
+ edit_group="skin_facedetail"
+ edit_group_order="5"
+ name="Lip Pinkness"
+ label_min="Darker"
+ label_max="Pinker"
+ value_min="0"
+ value_max="1"
+ camera_distance=".25">
+ <param_color>
+ <value
+ color="220, 115, 115, 0" />
+
+ <value
+ color="220, 115, 115, 128" />
+ </param_color>
+ </param>
+ </layer>
+
+ <layer
+ name="wrinkles_shading"
+ render_pass="bump"
+ fixed_color="0,0,0,100">
+ <param
+ id="118"
+ group="1"
+ wearable="skin"
+ name="Wrinkles"
+ value_min="0"
+ value_max="1">
+ <param_alpha
+ tga_file="bump_face_wrinkles.tga"
+ skip_if_zero="true"
+ domain="0.3" />
+ </param>
+ </layer>
+
+ <!--<layer
+ name="wrinkles_highlights"
+ fixed_color="255,255,255,64">
+ <param
+ id="128"
+ group="1"
+ name="Wrinkles"
+ value_min="0"
+ value_max="1">
+ <param_alpha
+ tga_file="head_wrinkles_highlights_alpha.tga"
+ skip_if_zero="true"
+ domain="0.3" />
+ </param>
+ </layer>-->
+ <layer
+ name="freckles"
+ fixed_color="120,47,20,128">
+ <param
+ id="165"
+ group="0"
+ wearable="skin"
+ edit_group="skin_facedetail"
+ edit_group_order="2"
+ name="Freckles"
+ label_min="Less"
+ label_max="More"
+ value_min="0"
+ value_max="1"
+ camera_distance=".3"
+camera_elevation=".07">
+ <param_alpha
+ tga_file="freckles_alpha.tga"
+ skip_if_zero="true"
+domain="0.5" />
+ </param>
+ </layer>
+ <layer
+name="eyebrowsbump"
+render_pass="bump">
+ <texture
+ tga_file="head_hair.tga"
+ file_is_mask="false" />
+
+ <param
+ id="1000"
+ group="1"
+ wearable="hair"
+ edit_group="driven"
+ name="Eyebrow Size Bump"
+ value_min="0"
+ value_max="1">
+ <param_alpha
+ tga_file="eyebrows_alpha.tga"
+ domain="0.1" />
+ </param>
+
+ <param
+ id="1002"
+ group="1"
+ wearable="hair"
+ edit_group="driven"
+ name="Eyebrow Density Bump"
+ value_min="0"
+ value_max="1">
+ <param_color>
+ <value
+ color="255,255,255,0" />
+
+ <value
+ color="255,255,255,255" />
+ </param_color>
+ </param>
+ </layer>
+
+ <layer
+ name="eyebrows"
+ global_color="hair_color">
+ <texture
+ tga_file="head_hair.tga"
+ file_is_mask="false" />
+
+ <param
+ id="1001"
+ group="1"
+ wearable="hair"
+ edit_group="hair_eyebrows"
+ name="Eyebrow Size"
+ show_simple="true"
+ value_min="0"
+ value_max="1"
+ value_default="0.5">
+ <param_alpha
+ tga_file="eyebrows_alpha.tga"
+ domain="0.1" />
+ </param>
+
+ <param
+ id="1003"
+ group="1"
+ wearable="hair"
+ edit_group="driven"
+ name="Eyebrow Density"
+ value_min="0"
+ value_max="1">
+ <param_color
+ operation="multiply">
+ <value
+ color="255,255,255,0" />
+
+ <value
+ color="255,255,255,255" />
+ </param_color>
+ </param>
+ </layer>
+
+ <layer
+ name="lipstick">
+ <param
+ id="700"
+ group="0"
+ wearable="skin"
+ edit_group="skin_makeup"
+ edit_group_order="2"
+ name="Lipstick Color"
+ label_min="Pink"
+ label_max="Black"
+ value_min="0"
+ value_max="1"
+ value_default=".25"
+ camera_distance=".25">
+ <param_color>
+ <value
+ color="245,161,177,200" />
+
+ <value
+ color="216,37,67,200" />
+
+ <value
+ color="178,48,76,200" />
+
+ <value
+ color="68,0,11,200" />
+
+ <value
+ color="252,207,184,200" />
+
+ <value
+ color="241,136,106,200" />
+
+ <value
+ color="208,110,85,200" />
+
+ <value
+ color="106,28,18,200" />
+
+ <value
+ color="58,26,49,200" />
+
+ <value
+ color="14,14,14,200" />
+ </param_color>
+ </param>
+
+ <param
+ id="701"
+ group="0"
+ wearable="skin"
+ edit_group="skin_makeup"
+ edit_group_order="1"
+ name="Lipstick"
+ label_min="No Lipstick"
+ label_max="More Lipstick"
+ value_min="0"
+ value_max=".9"
+ value_default="0.0"
+ camera_distance=".25">
+ <param_alpha
+ tga_file="lipstick_alpha.tga"
+ skip_if_zero="true"
+ domain="0.05" />
+ </param>
+ </layer>
+
+ <layer
+ name="lipgloss"
+ fixed_color="255,255,255,190">
+ <param
+ id="702"
+ name="Lipgloss"
+ label_min="No Lipgloss"
+ label_max="Glossy"
+ wearable="skin"
+ edit_group="skin_makeup"
+ edit_group_order="3"
+ group="0"
+ value_min="0"
+ value_max="1"
+ camera_distance=".25">
+ <param_alpha
+ tga_file="lipgloss_alpha.tga"
+ skip_if_zero="true"
+ domain="0.2" />
+ </param>
+ </layer>
+
+ <layer
+ name="blush">
+ <param
+ id="704"
+ group="0"
+ wearable="skin"
+ edit_group="skin_makeup"
+ edit_group_order="4"
+ name="Blush"
+ label_min="No Blush"
+ label_max="More Blush"
+ value_min="0"
+ value_max=".9"
+ value_default="0"
+ camera_distance=".3"
+ camera_elevation=".07"
+ camera_angle="20">
+ <param_alpha
+ tga_file="blush_alpha.tga"
+ skip_if_zero="true"
+ domain="0.3" />
+ </param>
+
+ <param
+ id="705"
+ group="0"
+ wearable="skin"
+ edit_group="skin_makeup"
+ edit_group_order="5"
+ name="Blush Color"
+ label_min="Pink"
+ label_max="Orange"
+ value_min="0"
+ value_max="1"
+ value_default=".5"
+ camera_distance=".3"
+ camera_elevation=".07"
+ camera_angle="20">
+ <param_color>
+ <value
+ color="253,162,193,200" />
+
+ <value
+ color="247,131,152,200" />
+
+ <value
+ color="213,122,140,200" />
+
+ <value
+ color="253,152,144,200" />
+
+ <value
+ color="236,138,103,200" />
+
+ <value
+ color="195,128,122,200" />
+
+ <value
+ color="148,103,100,200" />
+
+ <value
+ color="168,95,62,200" />
+ </param_color>
+ </param>
+
+ <param
+ id="711"
+ group="0"
+ wearable="skin"
+ edit_group="skin_makeup"
+ edit_group_order="6"
+ name="Blush Opacity"
+ label_min="Clear"
+ label_max="Opaque"
+ value_min="0"
+ value_max="1"
+ value_default=".5"
+ camera_distance=".3"
+ camera_elevation=".07"
+ camera_angle="20">
+ <param_color
+ operation="multiply">
+ <value
+ color="255,255,255,0" />
+
+ <value
+ color="255,255,255,255" />
+ </param_color>
+ </param>
+ </layer>
+
+ <layer
+ name="Outer Eye Shadow">
+ <param
+ id="708"
+ group="0"
+ wearable="skin"
+ edit_group="skin_makeup"
+ edit_group_order="11"
+ name="Out Shdw Color"
+ label_min="Light"
+ label_max="Dark"
+ value_min="0"
+ value_max="1"
+ camera_distance=".3"
+ camera_elevation=".14">
+ <param_color>
+ <value
+ color="252,247,246,255" />
+
+ <value
+ color="255,206,206,255" />
+
+ <value
+ color="233,135,149,255" />
+
+ <value
+ color="220,168,192,255" />
+
+ <value
+ color="228,203,232,255" />
+
+ <value
+ color="255,234,195,255" />
+
+ <value
+ color="230,157,101,255" />
+
+ <value
+ color="255,147,86,255" />
+
+ <value
+ color="228,110,89,255" />
+
+ <value
+ color="228,150,120,255" />
+
+ <value
+ color="223,227,213,255" />
+
+ <value
+ color="96,116,87,255" />
+
+ <value
+ color="88,143,107,255" />
+
+ <value
+ color="194,231,223,255" />
+
+ <value
+ color="207,227,234,255" />
+
+ <value
+ color="41,171,212,255" />
+
+ <value
+ color="180,137,130,255" />
+
+ <value
+ color="173,125,105,255" />
+
+ <value
+ color="144,95,98,255" />
+
+ <value
+ color="115,70,77,255" />
+
+ <value
+ color="155,78,47,255" />
+
+ <value
+ color="239,239,239,255" />
+
+ <value
+ color="194,194,194,255" />
+
+ <value
+ color="120,120,120,255" />
+
+ <value
+ color="10,10,10,255" />
+ </param_color>
+ </param>
+
+ <param
+ id="706"
+ group="0"
+ wearable="skin"
+ edit_group="skin_makeup"
+ edit_group_order="12"
+ name="Out Shdw Opacity"
+ label_min="Clear"
+ label_max="Opaque"
+ value_min=".2"
+ value_max="1"
+ value_default=".6"
+ camera_distance=".3"
+ camera_elevation=".14">
+ <param_color
+ operation="multiply">
+ <value
+ color="255,255,255,0" />
+
+ <value
+ color="255,255,255,255" />
+ </param_color>
+ </param>
+
+ <param
+ id="707"
+ group="0"
+ wearable="skin"
+ edit_group="skin_makeup"
+ edit_group_order="10"
+ name="Outer Shadow"
+ label_min="No Eyeshadow"
+ label_max="More Eyeshadow"
+ value_min="0"
+ value_max=".7"
+ camera_distance=".3"
+ camera_elevation=".14">
+ <param_alpha
+ tga_file="eyeshadow_outer_alpha.tga"
+ skip_if_zero="true"
+ domain="0.05" />
+ </param>
+ </layer>
+
+ <layer
+ name="Inner Eye Shadow">
+ <param
+ id="712"
+ group="0"
+ wearable="skin"
+ edit_group="skin_makeup"
+ edit_group_order="8"
+ name="In Shdw Color"
+ label_min="Light"
+ label_max="Dark"
+ value_min="0"
+ value_max="1"
+ camera_distance=".3"
+ camera_elevation=".14">
+ <param_color>
+ <value
+ color="252,247,246,255" />
+
+ <value
+ color="255,206,206,255" />
+
+ <value
+ color="233,135,149,255" />
+
+ <value
+ color="220,168,192,255" />
+
+ <value
+ color="228,203,232,255" />
+
+ <value
+ color="255,234,195,255" />
+
+ <value
+ color="230,157,101,255" />
+
+ <value
+ color="255,147,86,255" />
+
+ <value
+ color="228,110,89,255" />
+
+ <value
+ color="228,150,120,255" />
+
+ <value
+ color="223,227,213,255" />
+
+ <value
+ color="96,116,87,255" />
+
+ <value
+ color="88,143,107,255" />
+
+ <value
+ color="194,231,223,255" />
+
+ <value
+ color="207,227,234,255" />
+
+ <value
+ color="41,171,212,255" />
+
+ <value
+ color="180,137,130,255" />
+
+ <value
+ color="173,125,105,255" />
+
+ <value
+ color="144,95,98,255" />
+
+ <value
+ color="115,70,77,255" />
+
+ <value
+ color="155,78,47,255" />
+
+ <value
+ color="239,239,239,255" />
+
+ <value
+ color="194,194,194,255" />
+
+ <value
+ color="120,120,120,255" />
+
+ <value
+ color="10,10,10,255" />
+ </param_color>
+ </param>
+
+ <param
+ id="713"
+ group="0"
+ wearable="skin"
+ edit_group="skin_makeup"
+ edit_group_order="9"
+ name="In Shdw Opacity"
+ label_min="Clear"
+ label_max="Opaque"
+ value_min=".2"
+ value_max="1"
+ value_default=".7"
+ camera_distance=".3"
+ camera_elevation=".14">
+ <param_color
+ operation="multiply">
+ <value
+ color="255,255,255,0" />
+
+ <value
+ color="255,255,255,255" />
+ </param_color>
+ </param>
+
+ <param
+ id="709"
+ group="0"
+ wearable="skin"
+ edit_group="skin_makeup"
+ edit_group_order="7"
+ name="Inner Shadow"
+ label_min="No Eyeshadow"
+ label_max="More Eyeshadow"
+ value_min="0"
+ value_max="1"
+ value_default="0"
+ camera_distance=".3"
+ camera_elevation=".14">
+ <param_alpha
+ tga_file="eyeshadow_inner_alpha.tga"
+ skip_if_zero="true"
+ domain="0.2" />
+ </param>
+ </layer>
+
+ <layer
+ name="eyeliner"
+ fixed_color="0,0,0,200">
+ <param
+ id="703"
+ group="0"
+ wearable="skin"
+ edit_group="skin_makeup"
+ edit_group_order="13"
+ name="Eyeliner"
+ label_min="No Eyeliner"
+ label_max="Full Eyeliner"
+ value_min="0"
+ value_max="1"
+ value_default="0.0"
+ camera_distance=".3"
+ camera_elevation=".14">
+ <param_alpha
+ tga_file="eyeliner_alpha.tga"
+ skip_if_zero="true"
+ domain="0.1" />
+ </param>
+
+ <param
+ id="714"
+ group="0"
+ wearable="skin"
+ edit_group="skin_makeup"
+ edit_group_order="14"
+ name="Eyeliner Color"
+ label_min="Dark Green"
+ label_max="Black"
+ value_min="0"
+ value_max="1"
+ camera_distance=".3"
+ camera_elevation=".14">
+ <param_color>
+ <value
+ color="24,98,40,250" />
+
+ <!-- dark green -->
+ <value
+ color="9,100,127,250" />
+
+ <!-- lt.aqua blue -->
+ <value
+ color="61,93,134,250" />
+
+ <!-- aqua -->
+ <value
+ color="70,29,27,250" />
+
+ <!-- dark brown -->
+ <value
+ color="115,75,65,250" />
+
+ <!-- lt. brown blue -->
+ <value
+ color="100,100,100,250" />
+
+ <!-- grey -->
+ <value
+ color="91,80,74,250" />
+
+ <!-- grey/brown -->
+ <value
+ color="112,42,76,250" />
+
+ <!-- plum -->
+ <value
+ color="14,14,14,250" />
+
+ <!-- black -->
+ </param_color>
+ </param>
+ </layer>
+
+ <layer
+ name="facialhair bump"
+ render_pass="bump">
+ <texture
+ tga_file="head_hair.tga"
+ file_is_mask="false" />
+
+ <param
+ id="1004"
+ sex="male"
+ group="1"
+ wearable="hair"
+ edit_group="driven"
+ name="Sideburns bump"
+ value_min="0"
+ value_max="1">
+ <param_alpha
+ tga_file="facehair_sideburns_alpha.tga"
+ skip_if_zero="true"
+ domain="0.05" />
+ </param>
+
+ <param
+ id="1006"
+ sex="male"
+ group="1"
+ wearable="hair"
+ edit_group="driven"
+ name="Moustache bump"
+ value_min="0"
+ value_max="1">
+ <param_alpha
+ tga_file="facehair_moustache_alpha.tga"
+ skip_if_zero="true"
+ domain="0.05" />
+ </param>
+
+ <param
+ id="1008"
+ sex="male"
+ group="1"
+ wearable="hair"
+ edit_group="driven"
+ name="Soulpatch bump"
+ value_min="0"
+ value_max="1">
+ <param_alpha
+ tga_file="facehair_soulpatch_alpha.tga"
+ skip_if_zero="true"
+ domain="0.1" />
+ </param>
+
+ <param
+ id="1010"
+ sex="male"
+ group="1"
+ edit_group="driven"
+ wearable="hair"
+ name="Chin Curtains bump"
+ value_min="0"
+ value_max="1">
+ <param_alpha
+ tga_file="facehair_chincurtains_alpha.tga"
+ skip_if_zero="true"
+ domain="0.03" />
+ </param>
+
+ <param
+ id="1012"
+ group="1"
+ sex="male"
+ wearable="hair"
+ edit_group="driven"
+ name="5 O'Clock Shadow bump"
+ value_min="0"
+ value_max="1">
+ <param_color>
+ <value
+ color="255,255,255,255" />
+
+ <value
+ color="255,255,255,0" />
+ </param_color>
+ </param>
+ </layer>
+
+ <layer
+ name="facialhair"
+ global_color="hair_color">
+
+ <texture
+ tga_file="head_hair.tga"
+ file_is_mask="false" />
+
+ <param
+ id="1005"
+ sex="male"
+ group="1"
+ wearable="hair"
+ edit_group="driven"
+ name="Sideburns"
+ value_min="0"
+ value_max="1">
+ <param_alpha
+ tga_file="facehair_sideburns_alpha.tga"
+ skip_if_zero="true"
+ domain="0.05" />
+ </param>
+
+ <param
+ id="1007"
+ sex="male"
+ group="1"
+ wearable="hair"
+ edit_group="driven"
+ name="Moustache"
+ value_min="0"
+ value_max="1">
+ <param_alpha
+ tga_file="facehair_moustache_alpha.tga"
+ skip_if_zero="true"
+ domain="0.05" />
+ </param>
+
+ <param
+ id="1009"
+ sex="male"
+ group="1"
+ wearable="hair"
+ edit_group="driven"
+ name="Soulpatch"
+ value_min="0"
+ value_max="1">
+ <param_alpha
+ tga_file="facehair_soulpatch_alpha.tga"
+ skip_if_zero="true"
+ domain="0.1" />
+ </param>
+
+ <param
+ id="1011"
+ sex="male"
+ group="1"
+ wearable="hair"
+ edit_group="driven"
+ name="Chin Curtains"
+ value_min="0"
+ value_max="1">
+ <param_alpha
+ tga_file="facehair_chincurtains_alpha.tga"
+ skip_if_zero="true"
+ domain="0.03" />
+ </param>
+
+ <param
+ id="751"
+ group="1"
+ wearable="hair"
+ sex="male"
+ edit_group="hair_facial"
+ name="5 O'Clock Shadow"
+ label_min="Dense hair"
+ label_max="Shadow hair"
+ value_min="0"
+ value_max="1"
+ value_default="0.7"
+ camera_elevation=".1"
+ camera_distance=".3">
+ <param_color
+ operation="multiply">
+ <value
+ color="255,255,255,255" />
+
+ <value
+ color="255,255,255,30" />
+ </param_color>
+ </param>
+ </layer>
+
+ <layer
+ name="head_bodypaint">
+ <texture
+ local_texture="head_bodypaint" />
+ </layer>
+ <layer
+ name="eyelash alpha"
+ visibility_mask="TRUE">
+ <texture
+ tga_file="head_alpha.tga"
+ file_is_mask="TRUE" />
+ </layer>
+ <layer
+ name="head alpha"
+ visibility_mask="TRUE">
+ <texture
+ local_texture="head_alpha" />
+ </layer>
+ <layer
+ name="head_tattoo">
+ <texture
+ local_texture="head_tattoo" />
+ <param
+ id="1062"
+ group="1"
+ edit_group="colorpicker_driven"
+ wearable="tattoo"
+ name="tattoo_head_red"
+ value_min="0"
+ value_max="1"
+ value_default="1">
+ <param_color>
+ <value
+ color="0, 0, 0, 255" />
+
+ <value
+ color="255, 0, 0, 255" />
+ </param_color>
+ </param>
+
+ <param
+ id="1063"
+ group="1"
+ edit_group="colorpicker_driven"
+ wearable="tattoo"
+ name="tattoo_head_green"
+ value_min="0"
+ value_max="1"
+ value_default="1">
+ <param_color>
+ <value
+ color="0, 0, 0, 255" />
+
+ <value
+ color="0, 255, 0, 255" />
+ </param_color>
+ </param>
+
+ <param
+ id="1064"
+ group="1"
+ edit_group="colorpicker_driven"
+ wearable="tattoo"
+ name="tattoo_head_blue"
+ value_min="0"
+ value_max="1"
+ value_default="1">
+ <param_color>
+ <value
+ color="0, 0, 0, 255" />
+
+ <value
+ color="0, 0, 255, 255" />
+ </param_color>
+ </param>
+
+ </layer>
+
+
+ </layer_set>
+
+ <!-- =========================================================== -->
+ <layer_set
+ body_region="upper_body"
+ width="512"
+ height="512">
+ <layer
+ name="base_upperbody bump"
+ render_pass="bump"
+ fixed_color="128,128,128,255">
+ </layer>
+ <layer
+ name="upperbody bump definition"
+ render_pass="bump">
+ <texture
+ tga_file="bump_upperbody_base.tga"
+ file_is_mask="FALSE"/>
+
+ <param
+ id="874"
+ group="1"
+ wearable="skin"
+ edit_group="driven"
+ edit_group_order="20"
+ name="Bump upperdef"
+ value_min="0"
+ value_max="1">
+ <param_alpha
+ domain="0" />
+ </param>
+ </layer>
+
+ <layer
+ name="base"
+ global_color="skin_color">
+ <texture
+ tga_file="body_skingrain.tga" />
+ </layer>
+
+ <layer
+ name="nipples">
+ <texture
+ tga_file="upperbody_color.tga" />
+ </layer>
+
+ <layer
+ name="shadow">
+ <texture
+ tga_file="upperbody_shading_alpha.tga"
+ file_is_mask="TRUE" />
+
+ <param
+ id="125"
+ group="1"
+ name="Shading"
+ wearable="skin"
+ value_min="0"
+ value_max="1">
+ <param_color>
+ <value
+ color="0, 0, 0, 0" />
+
+ <value
+ color="0, 0, 0, 128" />
+ </param_color>
+ </param>
+ </layer>
+
+ <layer
+ name="highlight">
+ <texture
+ tga_file="upperbody_highlights_alpha.tga"
+ file_is_mask="TRUE" />
+
+ <param
+ id="126"
+ group="1"
+ wearable="skin"
+ name="Shading"
+ value_min="0"
+ value_max="1">
+ <param_color>
+ <value
+ color="255, 255, 255, 0" />
+
+ <value
+ color="255, 255, 255, 64" />
+ </param_color>
+ </param>
+ </layer>
+
+ <layer
+ name="upper_bodypaint">
+ <texture
+ local_texture="upper_bodypaint" />
+ </layer>
+
+ <layer
+ name="freckles upper"
+ fixed_color="120,47,20,128">
+ <param
+ id="776"
+ group="1"
+ name="freckles upper"
+ wearable="skin"
+ value_min="0"
+ value_max="1">
+ <param_alpha
+ tga_file="upperbodyfreckles_alpha.tga"
+ skip_if_zero="true"
+ domain="0.6" />
+ </param>
+ </layer>
+
+ <layer
+ name="upper_tattoo">
+ <texture
+ local_texture="upper_tattoo" />
+
+ <param
+ id="1065"
+ group="1"
+ edit_group="colorpicker_driven"
+ wearable="tattoo"
+ name="tattoo_upper_red"
+ value_min="0"
+ value_max="1"
+ value_default="1">
+ <param_color>
+ <value
+ color="0, 0, 0, 255" />
+
+ <value
+ color="255, 0, 0, 255" />
+ </param_color>
+ </param>
+
+ <param
+ id="1066"
+ group="1"
+ edit_group="colorpicker_driven"
+ wearable="tattoo"
+ name="tattoo_upper_green"
+ value_min="0"
+ value_max="1"
+ value_default="1">
+ <param_color>
+ <value
+ color="0, 0, 0, 255" />
+
+ <value
+ color="0, 255, 0, 255" />
+ </param_color>
+ </param>
+
+ <param
+ id="1067"
+ group="1"
+ edit_group="colorpicker_driven"
+ wearable="tattoo"
+ name="tattoo_upper_blue"
+ value_min="0"
+ value_max="1"
+ value_default="1">
+ <param_color>
+ <value
+ color="0, 0, 0, 255" />
+
+ <value
+ color="0, 0, 255, 255" />
+ </param_color>
+ </param>
+
+ </layer>
+
+
+ <layer
+ name="upper_undershirt bump"
+ render_pass="bump"
+ fixed_color="128,128,128,255">
+ <texture
+ local_texture="upper_undershirt"
+ local_texture_alpha_only="true" />
+
+ <param
+ id="1043"
+ group="1"
+ wearable="undershirt"
+ edit_group="driven"
+ name="Sleeve Length bump"
+ value_min=".01"
+ value_max="1"
+ value_default=".4">
+ <param_alpha
+ tga_file="shirt_sleeve_alpha.tga"
+ multiply_blend="false"
+ domain="0.01" />
+ </param>
+
+ <param
+ id="1045"
+ group="1"
+ wearable="undershirt"
+ edit_group="undershirt"
+ edit_group_order="2"
+ name="Bottom bump"
+ value_min="0"
+ value_max="1"
+ value_default=".8">
+ <param_alpha
+ tga_file="shirt_bottom_alpha.tga"
+ multiply_blend="true"
+ domain="0.05" />
+ </param>
+
+ <param
+ id="1047"
+ group="1"
+ wearable="undershirt"
+ edit_group="driven"
+ name="Collar Front bump"
+ value_min="0"
+ value_max="1"
+ value_default=".8">
+ <param_alpha
+ tga_file="shirt_collar_alpha.tga"
+ multiply_blend="true"
+ domain="0.05" />
+ </param>
+
+ <param
+ id="1049"
+ group="1"
+ wearable="undershirt"
+ edit_group="driven"
+ name="Collar Back bump"
+ value_min="0"
+ value_max="1"
+ value_default=".8">
+ <param_alpha
+ tga_file="shirt_collar_back_alpha.tga"
+ multiply_blend="true"
+ domain="0.05" />
+ </param>
+ </layer>
+
+ <layer
+ name="upper_undershirt">
+ <texture
+ local_texture="upper_undershirt" />
+
+ <param
+ id="821"
+ group="0"
+ wearable="undershirt"
+ edit_group="colorpicker"
+ name="undershirt_red"
+ value_min="0"
+ value_max="1"
+ value_default="1">
+ <param_color>
+ <value
+ color="0, 0, 0, 255" />
+
+ <value
+ color="255, 0, 0, 255" />
+ </param_color>
+ </param>
+
+ <param
+ id="822"
+ group="0"
+ wearable="undershirt"
+ edit_group="colorpicker"
+ name="undershirt_green"
+ value_min="0"
+ value_max="1"
+ value_default="1">
+ <param_color>
+ <value
+ color="0, 0, 0, 255" />
+
+ <value
+ color="0, 255, 0, 255" />
+ </param_color>
+ </param>
+
+ <param
+ id="823"
+ group="0"
+ wearable="undershirt"
+ edit_group="colorpicker"
+ name="undershirt_blue"
+ value_min="0"
+ value_max="1"
+ value_default="1">
+ <param_color>
+ <value
+ color="0, 0, 0, 255" />
+
+ <value
+ color="0, 0, 255, 255" />
+ </param_color>
+ </param>
+
+ <param
+ id="1042"
+ group="1"
+ wearable="undershirt"
+ edit_group="driven"
+ name="Sleeve Length"
+ value_min=".01"
+ value_max="1"
+ value_default=".4">
+ <param_alpha
+ tga_file="shirt_sleeve_alpha.tga"
+ multiply_blend="false"
+ domain="0.01" />
+ </param>
+
+ <param
+ id="1044"
+ group="1"
+ wearable="undershirt"
+ edit_group="driven"
+ name="Bottom"
+ value_min="0"
+ value_max="1"
+ value_default=".8">
+ <param_alpha
+ tga_file="shirt_bottom_alpha.tga"
+ multiply_blend="true"
+ domain="0.05" />
+ </param>
+
+ <param
+ id="1046"
+ group="1"
+ wearable="undershirt"
+ edit_group="driven"
+ name="Collar Front"
+ value_min="0"
+ value_max="1"
+ value_default=".8">
+ <param_alpha
+ tga_file="shirt_collar_alpha.tga"
+ multiply_blend="true"
+ domain="0.05" />
+ </param>
+
+ <param
+ id="1048"
+ group="1"
+ wearable="undershirt"
+ edit_group="driven"
+ name="Collar Back"
+ label_min="Low"
+ label_max="High"
+ value_min="0"
+ value_max="1"
+ value_default=".8">
+ <param_alpha
+ tga_file="shirt_collar_back_alpha.tga"
+ multiply_blend="true"
+ domain="0.05" />
+ </param>
+ </layer>
+
+ <layer
+ name="Nail Polish">
+ <param
+ id="710"
+ group="0"
+ wearable="skin"
+ edit_group="skin_makeup"
+ edit_group_order="15"
+ name="Nail Polish"
+ label_min="No Polish"
+ label_max="Painted Nails"
+ value_min="0"
+ value_max="1"
+ value_default="0.0"
+ camera_distance="1.6"
+ camera_elevation="-.4"
+ camera_angle="70">
+ <param_alpha
+ tga_file="nailpolish_alpha.tga"
+ skip_if_zero="true"
+ domain="0.1" />
+ </param>
+
+ <param
+ id="715"
+ group="0"
+ wearable="skin"
+ edit_group="skin_makeup"
+ edit_group_order="16"
+ name="Nail Polish Color"
+ label_min="Pink"
+ label_max="Black"
+ value_min="0"
+ value_max="1"
+ camera_distance="1.6"
+ camera_elevation="-.4"
+ camera_angle="70">
+ <param_color>
+ <value
+ color="255,187,200,255" />
+
+ <value
+ color="194,102,127,255" />
+
+ <value
+ color="227,34,99,255" />
+
+ <value
+ color="168,41,60,255" />
+
+ <value
+ color="97,28,59,255" />
+
+ <value
+ color="234,115,93,255" />
+
+ <value
+ color="142,58,47,255" />
+
+ <value
+ color="114,30,46,255" />
+
+ <value
+ color="14,14,14,255" />
+ </param_color>
+ </param>
+ </layer>
+
+ <layer
+ name="upper_gloves bump"
+ render_pass="bump"
+ fixed_color="128,128,128,255">
+ <texture
+ local_texture="upper_gloves"
+ local_texture_alpha_only="true" />
+
+ <param
+ id="1059"
+ group="1"
+ wearable="gloves"
+ edit_group="driven"
+ name="Glove Length bump"
+ value_min=".01"
+ value_max="1"
+ value_default=".8">
+ <param_alpha
+ tga_file="glove_length_alpha.tga"
+ domain="0.01" />
+ </param>
+
+ <param
+ id="1061"
+ group="1"
+ wearable="gloves"
+ edit_group="driven"
+ name="Glove Fingers bump"
+ value_min=".01"
+ value_max="1"
+ value_default="1">
+ <param_alpha
+ tga_file="gloves_fingers_alpha.tga"
+ multiply_blend="true"
+ domain="0.01" />
+ </param>
+ </layer>
+
+ <layer
+ name="upper_gloves">
+ <texture
+ local_texture="upper_gloves" />
+
+ <param
+ id="827"
+ group="0"
+ wearable="gloves"
+ edit_group="colorpicker"
+ name="gloves_red"
+ value_min="0"
+ value_max="1"
+ value_default="1">
+ <param_color>
+ <value
+ color="0, 0, 0, 255" />
+
+ <value
+ color="255, 0, 0, 255" />
+ </param_color>
+ </param>
+
+ <param
+ id="829"
+ group="0"
+ wearable="gloves"
+ edit_group="colorpicker"
+ name="gloves_green"
+ value_min="0"
+ value_max="1"
+ value_default="1">
+ <param_color>
+ <value
+ color="0, 0, 0, 255" />
+
+ <value
+ color="0, 255, 0, 255" />
+ </param_color>
+ </param>
+
+ <param
+ id="830"
+ group="0"
+ wearable="gloves"
+ edit_group="colorpicker"
+ name="gloves_blue"
+ value_min="0"
+ value_max="1"
+ value_default="1">
+ <param_color>
+ <value
+ color="0, 0, 0, 255" />
+
+ <value
+ color="0, 0, 255, 255" />
+ </param_color>
+ </param>
+
+ <param
+ id="1058"
+ group="1"
+ wearable="gloves"
+ edit_group="driven"
+ name="Glove Length"
+ value_min=".01"
+ value_max="1"
+ value_default=".8">
+ <param_alpha
+ tga_file="glove_length_alpha.tga"
+ domain="0.01" />
+ </param>
+
+ <param
+ id="1060"
+ group="1"
+ wearable="gloves"
+ edit_group="driven"
+ name="Glove Fingers"
+ value_min=".01"
+ value_max="1"
+ value_default="1">
+ <param_alpha
+ tga_file="gloves_fingers_alpha.tga"
+ multiply_blend="true"
+ domain="0.01" />
+ </param>
+ </layer>
+
+ <layer
+ name="upper_clothes_shadow">
+ <texture
+ local_texture="upper_shirt" />
+
+ <param
+ id="899"
+ group="1"
+ edit_group="driven"
+ wearable="shirt"
+ name="Upper Clothes Shading"
+ value_min="0"
+ value_max="1"
+ value_default="0">
+ <param_color>
+ <value
+ color="0, 0, 0, 0" />
+
+ <value
+ color="0, 0, 0, 80" />
+ </param_color>
+ </param>
+
+ <param
+ id="900"
+ group="1"
+ wearable="shirt"
+ edit_group="driven"
+ name="Sleeve Length Shadow"
+ value_min="0.02"
+ value_max=".87"
+ value_default="0.02">
+ <param_alpha
+ multiply_blend="false"
+ tga_file="shirt_sleeve_alpha.tga"
+ skip_if_zero="true"
+ domain="0.03" />
+ </param>
+
+ <param
+ id="901"
+ group="1"
+ wearable="shirt"
+ edit_group="driven"
+ name="Shirt Shadow Bottom"
+ value_min="0.02"
+ value_max="1">
+ <param_alpha
+ multiply_blend="true"
+ tga_file="shirt_bottom_alpha.tga"
+ skip_if_zero="true"
+ domain="0.05" />
+ </param>
+
+ <param
+ id="902"
+ group="1"
+ wearable="shirt"
+ edit_group="driven"
+ name="Collar Front Shadow Height"
+ value_min="0.02"
+ value_max="1">
+ <param_alpha
+ multiply_blend="true"
+ tga_file="shirt_collar_alpha.tga"
+ skip_if_zero="true"
+ domain="0.02" />
+ </param>
+
+ <param
+ id="903"
+ group="1"
+ wearable="shirt"
+ edit_group="driven"
+ name="Collar Back Shadow Height"
+ value_min="0.02"
+ value_max="1">
+ <param_alpha
+ multiply_blend="true"
+ tga_file="shirt_collar_back_alpha.tga"
+ skip_if_zero="true"
+ domain="0.02" />
+ </param>
+ </layer>
+
+ <layer
+ name="upper_shirt base bump"
+ render_pass="bump"
+ fixed_color="128,128,128,255">
+ <texture
+ local_texture="upper_shirt"
+ local_texture_alpha_only="true" />
+
+ <param
+ id="1029"
+ group="1"
+ wearable="shirt"
+ edit_group="driven"
+ name="Sleeve Length Cloth"
+ value_min="0"
+ value_max="0.85">
+ <param_alpha
+ multiply_blend="false"
+ tga_file="shirt_sleeve_alpha.tga"
+ domain="0.01" />
+ </param>
+
+ <param
+ id="1030"
+ group="1"
+ wearable="shirt"
+ edit_group="driven"
+ name="Shirt Bottom Cloth"
+ value_min="0"
+ value_max="1">
+ <param_alpha
+ multiply_blend="true"
+ tga_file="shirt_bottom_alpha.tga"
+ domain="0.05" />
+ </param>
+
+ <param
+ id="1031"
+ group="1"
+ wearable="shirt"
+ edit_group="driven"
+ name="Collar Front Height Cloth"
+ value_min="0"
+ value_max="1">
+ <param_alpha
+ multiply_blend="true"
+ tga_file="shirt_collar_alpha.tga"
+ domain="0.05" />
+ </param>
+
+ <param
+ id="1032"
+ group="1"
+ wearable="shirt"
+ edit_group="driven"
+ name="Collar Back Height Cloth"
+ value_min="0"
+ value_max="1">
+ <param_alpha
+ multiply_blend="true"
+ tga_file="shirt_collar_back_alpha.tga"
+ domain="0.05" />
+ </param>
+ </layer>
+
+ <layer
+ name="upper_clothes bump"
+ render_pass="bump">
+ <texture
+ tga_file="bump_shirt_wrinkles.tga" />
+
+ <texture
+ local_texture="upper_shirt"
+ local_texture_alpha_only="true" />
+
+ <param
+ id="868"
+ group="3"
+ wearable="shirt"
+ edit_group="shirt"
+ edit_group_order="8"
+ name="Shirt Wrinkles"
+ value_min="0"
+ value_max="1"
+ value_default="0">
+ <param_color>
+ <value
+ color="255, 255, 255, 0" />
+
+ <value
+ color="255, 255, 255, 255" />
+ </param_color>
+ </param>
+
+ <param
+ id="1013"
+ group="1"
+ wearable="shirt"
+ edit_group="driven"
+ name="Sleeve Length Cloth"
+ value_min="0"
+ value_max="0.85">
+ <param_alpha
+ multiply_blend="false"
+ tga_file="shirt_sleeve_alpha.tga"
+ domain="0.01" />
+ </param>
+
+ <param
+ id="1014"
+ group="1"
+ wearable="shirt"
+ edit_group="driven"
+ name="Shirt Bottom Cloth"
+ value_min="0"
+ value_max="1">
+ <param_alpha
+ multiply_blend="true"
+ tga_file="shirt_bottom_alpha.tga"
+ domain="0.05" />
+ </param>
+
+ <param
+ id="1015"
+ group="1"
+ wearable="shirt"
+ edit_group="driven"
+ name="Collar Front Height Cloth"
+ value_min="0"
+ value_max="1">
+ <param_alpha
+ multiply_blend="true"
+ tga_file="shirt_collar_alpha.tga"
+ domain="0.05" />
+ </param>
+
+ <param
+ id="1016"
+ group="1"
+ wearable="shirt"
+ edit_group="driven"
+ name="Collar Back Height Cloth"
+ value_min="0"
+ value_max="1">
+ <param_alpha
+ multiply_blend="true"
+ tga_file="shirt_collar_back_alpha.tga"
+ domain="0.05" />
+ </param>
+ </layer>
+
+ <layer
+ name="upper_clothes">
+ <texture
+ local_texture="upper_shirt" />
+
+ <param
+ id="803"
+ group="0"
+ wearable="shirt"
+ edit_group="colorpicker"
+ name="shirt_red"
+ value_min="0"
+ value_max="1"
+ value_default="1">
+ <param_color>
+ <value
+ color="0, 0, 0, 255" />
+
+ <value
+ color="255, 0, 0, 255" />
+ </param_color>
+ </param>
+
+ <param
+ id="804"
+ group="0"
+ wearable="shirt"
+ edit_group="colorpicker"
+ name="shirt_green"
+ value_min="0"
+ value_max="1"
+ value_default="1">
+ <param_color>
+ <value
+ color="0, 0, 0, 255" />
+
+ <value
+ color="0, 255, 0, 255" />
+ </param_color>
+ </param>
+
+ <param
+ id="805"
+ group="0"
+ wearable="shirt"
+ edit_group="colorpicker"
+ name="shirt_blue"
+ value_min="0"
+ value_max="1"
+ value_default="1">
+ <param_color>
+ <value
+ color="0, 0, 0, 255" />
+
+ <value
+ color="0, 0, 255, 255" />
+ </param_color>
+ </param>
+
+ <param
+ id="600"
+ group="1"
+ wearable="shirt"
+ edit_group="driven"
+ name="Sleeve Length Cloth"
+ value_min="0"
+ value_max="0.85"
+ value_default=".7">
+ <param_alpha
+ multiply_blend="false"
+ tga_file="shirt_sleeve_alpha.tga"
+ domain="0.01" />
+ </param>
+
+ <param
+ id="601"
+ group="1"
+ wearable="shirt"
+ edit_group="driven"
+ name="Shirt Bottom Cloth"
+ value_min="0"
+ value_max="1"
+ value_default=".8">
+ <param_alpha
+ multiply_blend="true"
+ tga_file="shirt_bottom_alpha.tga"
+ domain="0.05" />
+ </param>
+
+ <param
+ id="602"
+ group="1"
+ wearable="shirt"
+ edit_group="driven"
+ name="Collar Front Height Cloth"
+ value_min="0"
+ value_max="1"
+ value_default=".8">
+ <param_alpha
+ multiply_blend="true"
+ tga_file="shirt_collar_alpha.tga"
+ domain="0.05" />
+ </param>
+
+ <param
+ id="778"
+ group="1"
+ wearable="shirt"
+ edit_group="driven"
+ name="Collar Back Height Cloth"
+ value_min="0"
+ value_max="1"
+ value_default=".8">
+ <param_alpha
+ multiply_blend="true"
+ tga_file="shirt_collar_back_alpha.tga"
+ domain="0.05" />
+ </param>
+ </layer>
+
+ <layer
+ name="upper_jacket base bump"
+ render_pass="bump"
+ fixed_color="128,128,128,255">
+ <texture
+ local_texture="upper_jacket"
+ local_texture_alpha_only="true" />
+
+ <param
+ id="1039"
+ group="1"
+ wearable="jacket"
+ edit_group="driven"
+ edit_group_order="1"
+ name="Jacket Sleeve Length bump"
+ value_min="0"
+ value_max="1">
+ <param_alpha
+ multiply_blend="false"
+ tga_file="shirt_sleeve_alpha.tga"
+ domain="0.01" />
+ </param>
+
+ <param
+ id="1040"
+ group="1"
+ wearable="jacket"
+ edit_group="driven"
+ name="Jacket Collar Front bump"
+ value_min="0"
+ value_max="1">
+ <param_alpha
+ multiply_blend="true"
+ tga_file="shirt_collar_alpha.tga"
+ domain="0.05" />
+ </param>
+
+ <param
+ id="1041"
+ group="1"
+ wearable="jacket"
+ edit_group="driven"
+ edit_group_order="3.5"
+ name="Jacket Collar Back bump"
+ value_min="0"
+ value_max="1">
+ <param_alpha
+ multiply_blend="true"
+ tga_file="shirt_collar_back_alpha.tga"
+ domain="0.05" />
+ </param>
+
+ <param
+ id="1037"
+ group="1"
+ wearable="jacket"
+ edit_group="driven"
+ name="jacket bottom length upper bump"
+ value_min="0"
+ value_max="1">
+ <param_alpha
+ multiply_blend="true"
+ tga_file="jacket_length_upper_alpha.tga"
+ domain="0.01" />
+ </param>
+
+ <param
+ id="1038"
+ group="1"
+ wearable="jacket"
+ edit_group="driven"
+ name="jacket open upper bump"
+ value_min="0"
+ value_max="1">
+ <param_alpha
+ multiply_blend="true"
+ tga_file="jacket_open_upper_alpha.tga"
+ domain="0.01" />
+ </param>
+ </layer>
+
+ <layer
+ name="upper_jacket bump"
+ render_pass="bump">
+ <texture
+ tga_file="bump_shirt_wrinkles.tga" />
+
+ <texture
+ local_texture="upper_jacket"
+ local_texture_alpha_only="true" />
+
+
+ <param
+ id="875"
+ group="1"
+ wearable="jacket"
+ name="jacket upper Wrinkles"
+ value_min="0"
+ value_max="1"
+ value_default="0">
+ <param_color>
+ <value
+ color="255, 255, 255, 0" />
+
+ <value
+ color="255, 255, 255, 255" />
+ </param_color>
+ </param>
+
+ <param
+ id="1019"
+ group="1"
+ wearable="jacket"
+ edit_group="driven"
+ edit_group_order="1"
+ name="Jacket Sleeve Length bump"
+ value_min="0"
+ value_max="1">
+ <param_alpha
+ multiply_blend="false"
+ tga_file="shirt_sleeve_alpha.tga"
+ domain="0.01" />
+ </param>
+
+ <param
+ id="1021"
+ group="1"
+ wearable="jacket"
+ edit_group="driven"
+ name="Jacket Collar Front bump"
+ value_min="0"
+ value_max="1">
+ <param_alpha
+ multiply_blend="true"
+ tga_file="shirt_collar_alpha.tga"
+ domain="0.05" />
+ </param>
+
+ <param
+ id="1023"
+ group="1"
+ wearable="jacket"
+ edit_group="driven"
+ edit_group_order="3.5"
+ name="Jacket Collar Back bump"
+ value_min="0"
+ value_max="1">
+ <param_alpha
+ multiply_blend="true"
+ tga_file="shirt_collar_back_alpha.tga"
+ domain="0.05" />
+ </param>
+
+ <param
+ id="1025"
+ group="1"
+ wearable="jacket"
+ edit_group="driven"
+ name="jacket bottom length upper bump"
+ value_min="0"
+ value_max="1">
+ <param_alpha
+ multiply_blend="true"
+ tga_file="jacket_length_upper_alpha.tga"
+ domain="0.01" />
+ </param>
+
+ <param
+ id="1026"
+ group="1"
+ wearable="jacket"
+ edit_group="driven"
+ name="jacket open upper bump"
+ value_min="0"
+ value_max="1">
+ <param_alpha
+ multiply_blend="true"
+ tga_file="jacket_open_upper_alpha.tga"
+ domain="0.01" />
+ </param>
+ </layer>
+
+ <layer
+ name="upper_jacket">
+ <texture
+ local_texture="upper_jacket" />
+
+ <param
+ id="831"
+ group="1"
+ edit_group="colorpicker_driven"
+ wearable="jacket"
+ name="upper_jacket_red"
+ value_min="0"
+ value_max="1"
+ value_default="1">
+ <param_color>
+ <value
+ color="0, 0, 0, 255" />
+
+ <value
+ color="255, 0, 0, 255" />
+ </param_color>
+ </param>
+
+ <param
+ id="832"
+ group="1"
+ edit_group="colorpicker_driven"
+ wearable="jacket"
+ name="upper_jacket_green"
+ value_min="0"
+ value_max="1"
+ value_default="1">
+ <param_color>
+ <value
+ color="0, 0, 0, 255" />
+
+ <value
+ color="0, 255, 0, 255" />
+ </param_color>
+ </param>
+
+ <param
+ id="833"
+ group="1"
+ edit_group="colorpicker_driven"
+ wearable="jacket"
+ name="upper_jacket_blue"
+ value_min="0"
+ value_max="1"
+ value_default="1">
+ <param_color>
+ <value
+ color="0, 0, 0, 255" />
+
+ <value
+ color="0, 0, 255, 255" />
+ </param_color>
+ </param>
+
+ <param
+ id="1020"
+ group="1"
+ edit_group="driven"
+ wearable="jacket"
+ name="jacket Sleeve Length" value_min="0"
+ value_max="1">
+ <param_alpha
+ multiply_blend="false"
+ tga_file="shirt_sleeve_alpha.tga"
+ domain="0.01" />
+ </param>
+
+ <param
+ id="1022"
+ group="1"
+ wearable="jacket"
+ edit_group="driven"
+ name="jacket Collar Front"
+ value_min="0"
+ value_max="1">
+ <param_alpha
+ multiply_blend="true"
+ tga_file="shirt_collar_alpha.tga"
+ domain="0.05" />
+ </param>
+
+ <param
+ id="1024"
+ group="1"
+ wearable="jacket"
+ edit_group="driven"
+ edit_group_order="3.5"
+ name="jacket Collar Back"
+ value_min="0"
+ value_max="1">
+ <param_alpha
+ multiply_blend="true"
+ tga_file="shirt_collar_back_alpha.tga"
+ domain="0.05" />
+ </param>
+
+ <param
+ id="620"
+ group="1"
+ wearable="jacket"
+ edit_group="jacket"
+ name="bottom length upper"
+ label_min="hi cut"
+ label_max="low cut"
+ value_min="0"
+ value_max="1"
+ value_default=".8"
+ camera_distance="1.2"
+ camera_angle="30"
+ camera_elevation=".2">
+ <param_alpha
+ multiply_blend="true"
+ tga_file="jacket_length_upper_alpha.tga"
+ domain="0.01" />
+ </param>
+
+ <param
+ id="622"
+ group="1"
+ wearable="jacket"
+ edit_group="jacket"
+ name="open upper"
+ label_min="closed"
+ label_max="open"
+ value_min="0"
+ value_max="1"
+ value_default=".8"
+ camera_distance="1.2"
+ camera_angle="30"
+ camera_elevation=".2">
+ <param_alpha
+ multiply_blend="true"
+ tga_file="jacket_open_upper_alpha.tga"
+ domain="0.01" />
+ </param>
+ </layer>
+
+ <layer
+ name="upper alpha"
+ visibility_mask="TRUE">
+ <texture
+ local_texture="upper_alpha" />
+ </layer>
+
+ </layer_set>
+
+ <!-- =========================================================== -->
+ <layer_set
+ body_region="lower_body"
+ width="512"
+ height="512">
+ <layer
+ name="lower body bump base"
+ fixed_color = "128,128,128,255"
+ render_pass="bump">
+ </layer>
+ <layer
+ name="base_lowerbody bump"
+ render_pass="bump">
+ <texture
+ tga_file="bump_lowerbody_base.tga"
+ file_is_mask="FALSE" />
+
+ <param
+ id="878"
+ group="1"
+ wearable="skin"
+ edit_group="driven"
+ edit_group_order="20"
+ name="Bump upperdef"
+ value_min="0"
+ value_max="1">
+ <param_alpha
+ domain="0" />
+ </param>
+ </layer>
+
+ <layer
+ name="base"
+ global_color="skin_color">
+ <texture
+ tga_file="body_skingrain.tga" />
+ </layer>
+
+ <layer
+ name="shadow">
+ <texture
+ tga_file="lowerbody_shading_alpha.tga"
+ file_is_mask="TRUE" />
+
+ <param
+ id="160"
+ group="1"
+ name="Shading"
+ wearable="pants"
+ cross_wearable="true"
+ value_min="0"
+ value_max="1">
+ <param_color>
+ <value
+ color="0, 0, 0, 0" />
+
+ <value
+ color="0, 0, 0, 128" />
+ </param_color>
+ </param>
+ </layer>
+
+ <layer
+ name="highlight">
+ <texture
+ tga_file="lowerbody_highlights_alpha.tga"
+ file_is_mask="TRUE" />
+
+ <param
+ id="161"
+ group="1"
+ name="Shading"
+ wearable="skin"
+ value_min="0"
+ value_max="1">
+ <param_color>
+ <value
+ color="255, 255, 255, 0" />
+
+ <value
+ color="255, 255, 255, 64" />
+ </param_color>
+ </param>
+ </layer>
+
+ <layer
+ name="toenails">
+ <texture
+ tga_file="lowerbody_color.tga" />
+ </layer>
+
+ <layer
+ name="lower_bodypaint">
+ <texture
+ local_texture="lower_bodypaint" />
+ </layer>
+
+ <layer
+ name="freckles lower"
+ fixed_color="120,47,20,128">
+ <param
+ id="777"
+ group="1"
+ name="freckles lower"
+ wearable="skin"
+ value_min="0"
+ value_max="1">
+ <param_alpha
+ tga_file="bodyfreckles_alpha.tga"
+ skip_if_zero="true"
+ domain="0.6" />
+ </param>
+ </layer>
+
+ <layer
+ name="lower_tattoo">
+ <texture
+ local_texture="lower_tattoo" />
+
+ <param
+ id="1068"
+ group="1"
+ edit_group="colorpicker_driven"
+ wearable="tattoo"
+ name="tattoo_lower_red"
+ value_min="0"
+ value_max="1"
+ value_default="1">
+ <param_color>
+ <value
+ color="0, 0, 0, 255" />
+
+ <value
+ color="255, 0, 0, 255" />
+ </param_color>
+ </param>
+
+ <param
+ id="1069"
+ group="1"
+ edit_group="colorpicker_driven"
+ wearable="tattoo"
+ name="tattoo_lower_green"
+ value_min="0"
+ value_max="1"
+ value_default="1">
+ <param_color>
+ <value
+ color="0, 0, 0, 255" />
+
+ <value
+ color="0, 255, 0, 255" />
+ </param_color>
+ </param>
+
+ <param
+ id="1070"
+ group="1"
+ edit_group="colorpicker_driven"
+ wearable="tattoo"
+ name="tattoo_lower_blue"
+ value_min="0"
+ value_max="1"
+ value_default="1">
+ <param_color>
+ <value
+ color="0, 0, 0, 255" />
+
+ <value
+ color="0, 0, 255, 255" />
+ </param_color>
+ </param>
+
+ </layer>
+
+ <layer
+ name="lower_underpants bump"
+ render_pass="bump"
+ fixed_color="128,128,128,255">
+ <texture
+ local_texture="lower_underpants"
+ local_texture_alpha_only="true" />
+
+ <param
+ id="1055"
+ group="1"
+ wearable="underpants"
+ edit_group="underpants"
+ name="Pants Length"
+ value_min="0"
+ value_max="1"
+ value_default=".3">
+ <param_alpha
+ tga_file="pants_length_alpha.tga"
+ domain="0.01" />
+ </param>
+
+ <param
+ id="1057"
+ group="1"
+ wearable="underpants"
+ edit_group="underpants"
+ name="Pants Waist"
+ value_min="0"
+ value_max="1"
+ value_default=".8">
+ <param_alpha
+ tga_file="pants_waist_alpha.tga"
+ domain="0.05" />
+ </param>
+ </layer>
+
+ <layer
+ name="lower_underpants">
+ <texture
+ local_texture="lower_underpants" />
+
+ <param
+ id="824"
+ group="0"
+ wearable="underpants"
+ edit_group="colorpicker"
+ name="underpants_red"
+ value_min="0"
+ value_max="1"
+ value_default="1">
+ <param_color>
+ <value
+ color="0, 0, 0, 255" />
+
+ <value
+ color="255, 0, 0, 255" />
+ </param_color>
+ </param>
+
+ <param
+ id="825"
+ group="0"
+ wearable="underpants"
+ edit_group="colorpicker"
+ name="underpants_green"
+ value_min="0"
+ value_max="1"
+ value_default="1">
+ <param_color>
+ <value
+ color="0, 0, 0, 255" />
+
+ <value
+ color="0, 255, 0, 255" />
+ </param_color>
+ </param>
+
+ <param
+ id="826"
+ group="0"
+ wearable="underpants"
+ edit_group="colorpicker"
+ name="underpants_blue"
+ value_min="0"
+ value_max="1"
+ value_default="1">
+ <param_color>
+ <value
+ color="0, 0, 0, 255" />
+
+ <value
+ color="0, 0, 255, 255" />
+ </param_color>
+ </param>
+
+ <param
+ id="1054"
+ group="1"
+ wearable="underpants"
+ edit_group="driven"
+ name="Pants Length"
+ value_min="0"
+ value_max="1"
+ value_default=".3"
+ camera_distance="1.2"
+ camera_angle="30"
+ camera_elevation="-.3">
+ <param_alpha
+ tga_file="pants_length_alpha.tga"
+ domain="0.01" />
+ </param>
+
+ <param
+ id="1056"
+ group="1"
+ wearable="underpants"
+ edit_group="driven"
+ name="Pants Waist"
+ value_min="0"
+ value_max="1"
+ value_default=".8">
+ <param_alpha
+ tga_file="pants_waist_alpha.tga"
+ domain="0.05" />
+ </param>
+ </layer>
+
+ <layer
+ name="lower_socks bump"
+ render_pass="bump"
+ fixed_color="128,128,128,255">
+ <texture
+ local_texture="lower_socks"
+ local_texture_alpha_only="true" />
+
+ <param
+ id="1051"
+ group="1"
+ wearable="socks"
+ edit_group="driven"
+ name="Socks Length bump"
+ value_min="0"
+ value_max="1"
+ value_default="0.35">
+ <param_alpha
+ tga_file="shoe_height_alpha.tga"
+ domain="0.01" />
+ </param>
+ </layer>
+
+ <layer
+ name="lower_socks">
+ <texture
+ local_texture="lower_socks" />
+
+ <param
+ id="818"
+ group="0"
+ wearable="socks"
+ edit_group="colorpicker"
+ name="socks_red"
+ value_min="0"
+ value_max="1"
+ value_default="1">
+ <param_color>
+ <value
+ color="0, 0, 0, 255" />
+
+ <value
+ color="255, 0, 0, 255" />
+ </param_color>
+ </param>
+
+ <param
+ id="819"
+ group="0"
+ wearable="socks"
+ edit_group="colorpicker"
+ name="socks_green"
+ value_min="0"
+ value_max="1"
+ value_default="1">
+ <param_color>
+ <value
+ color="0, 0, 0, 255" />
+
+ <value
+ color="0, 255, 0, 255" />
+ </param_color>
+ </param>
+
+ <param
+ id="820"
+ group="0"
+ wearable="socks"
+ edit_group="colorpicker"
+ name="socks_blue"
+ value_min="0"
+ value_max="1"
+ value_default="1">
+ <param_color>
+ <value
+ color="0, 0, 0, 255" />
+
+ <value
+ color="0, 0, 255, 255" />
+ </param_color>
+ </param>
+
+ <param
+ id="1050"
+ group="1"
+ wearable="socks"
+ edit_group="driven"
+ name="Socks Length bump"
+ value_min="0"
+ value_max="1"
+ value_default="0.35">
+ <param_alpha
+ tga_file="shoe_height_alpha.tga"
+ domain="0.01" />
+ </param>
+ </layer>
+
+ <layer
+ name="lower_shoes bump"
+ render_pass="bump"
+ fixed_color="128,128,128,255">
+ <texture
+ local_texture="lower_shoes"
+ local_texture_alpha_only="true" />
+
+ <param
+ id="1053"
+ group="1"
+ wearable="shoes"
+ edit_group="driven"
+ name="Shoe Height bump"
+ value_min="0"
+ value_max="1"
+ value_default="0.1">
+ <param_alpha
+ tga_file="shoe_height_alpha.tga"
+ domain="0.01" />
+ </param>
+ </layer>
+
+ <layer
+ name="lower_shoes">
+ <texture
+ local_texture="lower_shoes" />
+
+ <param
+ id="812"
+ group="0"
+ wearable="shoes"
+ edit_group="colorpicker"
+ name="shoes_red"
+ value_min="0"
+ value_max="1"
+ value_default="1">
+ <param_color>
+ <value
+ color="0, 0, 0, 255" />
+
+ <value
+ color="255, 0, 0, 255" />
+ </param_color>
+ </param>
+
+ <param
+ id="813"
+ group="0"
+ wearable="shoes"
+ edit_group="colorpicker"
+ name="shoes_green"
+ value_min="0"
+ value_max="1"
+ value_default="1">
+ <param_color>
+ <value
+ color="0, 0, 0, 255" />
+
+ <value
+ color="0, 255, 0, 255" />
+ </param_color>
+ </param>
+
+ <param
+ id="817"
+ group="0"
+ wearable="shoes"
+ edit_group="colorpicker"
+ name="shoes_blue"
+ value_min="0"
+ value_max="1"
+ value_default="1">
+ <param_color>
+ <value
+ color="0, 0, 0, 255" />
+
+ <value
+ color="0, 0, 255, 255" />
+ </param_color>
+ </param>
+
+ <param
+ id="1052"
+ group="1"
+ wearable="shoes"
+ edit_group="driven"
+ name="Shoe Height"
+ value_min="0"
+ value_max="1"
+ value_default="0.1">
+ <param_alpha
+ tga_file="shoe_height_alpha.tga"
+ domain="0.01" />
+ </param>
+ </layer>
+
+ <layer
+ name="lower_clothes_shadow">
+ <texture
+ local_texture="lower_pants" />
+
+ <param
+ id="913"
+ group="1"
+ edit_group="driven"
+ wearable="pants"
+ name="Lower Clothes Shading"
+ value_min="0"
+ value_max="1"
+ value_default="0">
+ <param_color>
+ <value
+ color="0, 0, 0, 0" />
+
+ <value
+ color="0, 0, 0, 80" />
+ </param_color>
+ </param>
+
+ <param
+ id="914"
+ group="1"
+ edit_group="driven"
+ wearable="pants"
+ name="Waist Height Shadow"
+ value_min="0.02"
+ value_max="1">
+ <param_alpha
+ tga_file="pants_waist_alpha.tga"
+ skip_if_zero="true"
+ domain="0.04" />
+ </param>
+
+ <param
+ id="915"
+ group="1"
+ edit_group="driven"
+ wearable="pants"
+ name="Pants Length Shadow"
+ value_min="0.02"
+ value_max="1">
+ <param_alpha
+ tga_file="pants_length_alpha.tga"
+ skip_if_zero="true"
+ domain="0.03" />
+ </param>
+ </layer>
+
+ <layer
+ name="lower_pants base bump"
+ render_pass="bump"
+ fixed_color="128,128,128,255">
+ <texture
+ local_texture="lower_pants"
+ local_texture_alpha_only="true" />
+
+ <param
+ id="1035"
+ group="1"
+ edit_group="driven"
+ wearable="pants"
+ name="Waist Height Cloth"
+ value_min="0"
+ value_max="1">
+ <param_alpha
+ tga_file="pants_waist_alpha.tga"
+ domain="0.05" />
+ </param>
+
+ <param
+ id="1036"
+ group="1"
+ edit_group="driven"
+ wearable="pants"
+ name="Pants Length Cloth"
+ value_min="0"
+ value_max="1">
+ <param_alpha
+ tga_file="pants_length_alpha.tga"
+ domain="0.01" />
+ </param>
+ </layer>
+
+ <layer
+ name="lower_pants bump"
+ render_pass="bump">
+ <texture
+ tga_file="bump_pants_wrinkles.tga" />
+
+ <texture
+ local_texture="lower_pants"
+ local_texture_alpha_only="true" />
+
+ <param
+ id="869"
+ group="3"
+ wearable="pants"
+ edit_group="pants"
+ edit_group_order="6"
+ name="Pants Wrinkles"
+ value_min="0"
+ value_max="1"
+ value_default="0">
+ <param_color>
+ <value
+ color="255, 255, 255, 0" />
+
+ <value
+ color="255, 255, 255, 255" />
+ </param_color>
+ </param>
+
+ <param
+ id="1017"
+ group="1"
+ edit_group="driven"
+ wearable="pants"
+ name="Waist Height Cloth"
+ value_min="0"
+ value_max="1">
+ <param_alpha
+ tga_file="pants_waist_alpha.tga"
+ domain="0.05" />
+ </param>
+
+ <param
+ id="1018"
+ group="1"
+ edit_group="driven"
+ wearable="pants"
+ name="Pants Length Cloth"
+ value_min="0"
+ value_max="1">
+ <param_alpha
+ tga_file="pants_length_alpha.tga"
+ domain="0.01" />
+ </param>
+ </layer>
+
+ <layer
+ name="lower_pants">
+ <texture
+ local_texture="lower_pants" />
+
+ <param
+ id="806"
+ group="0"
+ wearable="pants"
+ edit_group="colorpicker"
+ name="pants_red"
+ value_min="0"
+ value_max="1"
+ value_default="1">
+ <param_color>
+ <value
+ color="0, 0, 0, 255" />
+
+ <value
+ color="255, 0, 0, 255" />
+ </param_color>
+ </param>
+
+ <param
+ id="807"
+ group="0"
+ wearable="pants"
+ edit_group="colorpicker"
+ name="pants_green"
+ value_min="0"
+ value_max="1"
+ value_default="1">
+ <param_color>
+ <value
+ color="0, 0, 0, 255" />
+
+ <value
+ color="0, 255, 0, 255" />
+ </param_color>
+ </param>
+
+ <param
+ id="808"
+ group="0"
+ wearable="pants"
+ edit_group="colorpicker"
+ name="pants_blue"
+ value_min="0"
+ value_max="1"
+ value_default="1">
+ <param_color>
+ <value
+ color="0, 0, 0, 255" />
+
+ <value
+ color="0, 0, 255, 255" />
+ </param_color>
+ </param>
+
+ <param
+ id="614"
+ group="1"
+ edit_group="driven"
+ wearable="pants"
+ name="Waist Height Cloth"
+ value_min="0"
+ value_max="1"
+ value_default=".8">
+ <param_alpha
+ tga_file="pants_waist_alpha.tga"
+ domain="0.05" />
+ </param>
+
+ <param
+ id="615"
+ group="1"
+ edit_group="driven"
+ wearable="pants"
+ name="Pants Length Cloth"
+ value_min="0"
+ value_max="1"
+ value_default=".8">
+ <param_alpha
+ tga_file="pants_length_alpha.tga"
+ domain="0.01" />
+ </param>
+ </layer>
+
+ <layer
+ name="lower_jacket base bump"
+ render_pass="bump"
+ fixed_color="128,128,128,255">
+ <texture
+ local_texture="lower_jacket"
+ local_texture_alpha_only="true" />
+
+ <param
+ id="1033"
+ group="1"
+ wearable="jacket"
+ edit_group="driven"
+ cross_wearable="true"
+ name="jacket bottom length lower bump"
+ value_min="0"
+ value_max="1">
+ <param_alpha
+ multiply_blend="false"
+ tga_file="jacket_length_lower_alpha.tga"
+ domain="0.01" />
+ </param>
+
+ <param
+ id="1034"
+ group="1"
+ wearable="jacket"
+ edit_group="driven"
+ name="jacket open lower bump"
+ value_min="0"
+ value_max="1">
+ <param_alpha
+ multiply_blend="true"
+ tga_file="jacket_open_lower_alpha.tga"
+ domain="0.01" />
+ </param>
+ </layer>
+
+ <layer
+ name="lower_jacket bump"
+ render_pass="bump">
+ <texture
+ tga_file="bump_pants_wrinkles.tga" />
+
+ <texture
+ local_texture="lower_jacket"
+ local_texture_alpha_only="true" />
+
+
+ <param
+ id="876"
+ group="1"
+ wearable="jacket"
+ name="jacket upper Wrinkles"
+ value_min="0"
+ value_max="1"
+ value_default="0">
+ <param_color>
+ <value
+ color="255, 255, 255, 0" />
+
+ <value
+ color="255, 255, 255, 255" />
+ </param_color>
+ </param>
+
+ <param
+ id="1027"
+ group="1"
+ wearable="jacket"
+ edit_group="driven"
+ name="jacket bottom length lower bump"
+ value_min="0"
+ value_max="1">
+ <param_alpha
+ multiply_blend="false"
+ tga_file="jacket_length_lower_alpha.tga"
+ domain="0.01" />
+ </param>
+
+ <param
+ id="1028"
+ group="1"
+ wearable="jacket"
+ edit_group="driven"
+ name="jacket open lower bump"
+ value_min="0"
+ value_max="1">
+ <param_alpha
+ multiply_blend="true"
+ tga_file="jacket_open_lower_alpha.tga"
+ domain="0.01" />
+ </param>
+ </layer>
+
+ <layer
+ name="lower_jacket">
+ <texture
+ local_texture="lower_jacket" />
+
+ <param
+ id="809"
+ group="1"
+ edit_group="colorpicker_driven"
+ wearable="jacket"
+ name="lower_jacket_red"
+ value_min="0"
+ value_max="1"
+ value_default="1">
+ <param_color>
+ <value
+ color="0, 0, 0, 255" />
+
+ <value
+ color="255, 0, 0, 255" />
+ </param_color>
+ </param>
+
+ <param
+ id="810"
+ group="1"
+ edit_group="colorpicker_driven"
+ wearable="jacket"
+ name="lower_jacket_green"
+ value_min="0"
+ value_max="1"
+ value_default="1">
+ <param_color>
+ <value
+ color="0, 0, 0, 255" />
+
+ <value
+ color="0, 255, 0, 255" />
+ </param_color>
+ </param>
+
+ <param
+ id="811"
+ group="1"
+ edit_group="colorpicker_driven"
+ wearable="jacket"
+ name="lower_jacket_blue"
+ value_min="0"
+ value_max="1"
+ value_default="1">
+ <param_color>
+ <value
+ color="0, 0, 0, 255" />
+
+ <value
+ color="0, 0, 255, 255" />
+ </param_color>
+ </param>
+
+ <param
+ id="621"
+ group="1"
+ wearable="jacket"
+ edit_group="jacket"
+ name="bottom length lower"
+ label_min="hi cut"
+ label_max="low cut"
+ value_min="0"
+ value_max="1"
+ value_default=".8"
+ camera_distance="1.2"
+ camera_angle="30"
+ camera_elevation=".2">
+ <param_alpha
+ multiply_blend="false"
+ tga_file="jacket_length_lower_alpha.tga"
+ domain="0.01" />
+ </param>
+
+ <param
+ id="623"
+ group="1"
+ wearable="jacket"
+ edit_group="jacket"
+ name="open lower"
+ label_min="open"
+ label_max="closed"
+ value_min="0"
+ value_max="1"
+ value_default=".8"
+ camera_distance="1.2"
+ camera_angle="30"
+ camera_elevation=".2">
+ <param_alpha
+ multiply_blend="true"
+ tga_file="jacket_open_lower_alpha.tga"
+ domain="0.01" />
+ </param>
+ </layer>
+
+ <layer
+ name="lower alpha"
+ visibility_mask="TRUE">
+ <texture
+ local_texture="lower_alpha" />
+ </layer>
+
+ </layer_set>
+
+ <!-- =========================================================== -->
+ <layer_set
+ body_region="eyes"
+ width="128"
+ height="128">
+ <layer
+ name="whites">
+ <texture
+ tga_file="eyewhite.tga" />
+ </layer>
+
+ <layer
+ name="iris"
+ global_color="eye_color">
+ <texture
+ local_texture="eyes_iris" />
+ </layer>
+
+ <layer
+ name="eyes alpha"
+ visibility_mask="TRUE">
+ <texture
+ local_texture="eyes_alpha" />
+ </layer>
+
+ </layer_set>
+
+ <!-- =========================================================== -->
+ <layer_set
+ body_region="skirt"
+ width="512"
+ height="512"
+ clear_alpha="false">
+ <layer
+ name="skirt_fabric"
+ write_all_channels="true">
+ <texture
+ local_texture="skirt" />
+
+ <param
+ id="921"
+ group="0"
+ wearable="skirt"
+ edit_group="colorpicker"
+ name="skirt_red"
+ value_min="0"
+ value_max="1"
+ value_default="1">
+ <param_color>
+ <value
+ color="0, 0, 0, 255" />
+
+ <value
+ color="255, 0, 0, 255" />
+ </param_color>
+ </param>
+
+ <param
+ id="922"
+ group="0"
+ wearable="skirt"
+ edit_group="colorpicker"
+ name="skirt_green"
+ value_min="0"
+ value_max="1"
+ value_default="1">
+ <param_color>
+ <value
+ color="0, 0, 0, 255" />
+
+ <value
+ color="0, 255, 0, 255" />
+ </param_color>
+ </param>
+
+ <param
+ id="923"
+ group="0"
+ wearable="skirt"
+ edit_group="colorpicker"
+ name="skirt_blue"
+ value_min="0"
+ value_max="1"
+ value_default="1">
+ <param_color>
+ <value
+ color="0, 0, 0, 255" />
+
+ <value
+ color="0, 0, 255, 255" />
+ </param_color>
+ </param>
+ </layer>
+
+ <layer
+ name="skirt_fabric_alpha">
+ <param
+ id="858"
+ group="0"
+ wearable="skirt"
+ edit_group="skirt"
+ edit_group_order="1"
+ name="Skirt Length"
+ show_simple="true"
+ label_min="Short"
+ label_max="Long"
+ value_min=".01"
+ value_max="1"
+ value_default=".4"
+ simple_percent_min="40"
+ simple_percent_max="100"
+ camera_distance="1.3"
+ camera_elevation="-.5"
+ camera_angle="30">
+ <param_alpha
+ tga_file="skirt_length_alpha.tga"
+ domain="0"
+ multiply_blend="true" />
+ </param>
+
+ <param
+ id="859"
+ group="0"
+ wearable="skirt"
+ edit_group="skirt"
+ edit_group_order="4"
+ name="Slit Front"
+ label_min="Open Front"
+ label_max="Closed Front"
+ value_min="0"
+ value_max="1"
+ value_default="1"
+ camera_distance="1.3"
+ camera_elevation="-.5"
+ camera_angle="30">
+ <param_alpha
+ tga_file="skirt_slit_front_alpha.tga"
+ multiply_blend="true"
+ domain="0" />
+ </param>
+
+ <param
+ id="860"
+ group="0"
+ wearable="skirt"
+ edit_group="skirt"
+ edit_group_order="5"
+ name="Slit Back"
+ label_min="Open Back"
+ label_max="Closed Back"
+ value_min="0"
+ value_max="1"
+ value_default="1"
+ camera_distance="1.3"
+ camera_elevation="-.5"
+ camera_angle="160">
+ <param_alpha
+ tga_file="skirt_slit_back_alpha.tga"
+ multiply_blend="true"
+ domain="0" />
+ </param>
+
+ <param
+ id="861"
+ group="0"
+ wearable="skirt"
+ edit_group="skirt"
+ edit_group_order="6"
+ name="Slit Left"
+ label_min="Open Left"
+ label_max="Closed Left"
+ value_min="0"
+ value_max="1"
+ value_default="1"
+ camera_distance="1.3"
+ camera_elevation="-.5"
+ camera_angle="30">
+ <param_alpha
+ tga_file="skirt_slit_left_alpha.tga"
+ multiply_blend="true"
+ domain="0" />
+ </param>
+
+ <param
+ id="862"
+ group="0"
+ wearable="skirt"
+ edit_group="skirt"
+ edit_group_order="7"
+ name="Slit Right"
+ label_min="Open Right"
+ label_max="Closed Right"
+ value_min="0"
+ value_max="1"
+ value_default="1"
+ camera_distance="1.3"
+ camera_elevation="-.5"
+ camera_angle="-30">
+ <param_alpha
+ tga_file="skirt_slit_right_alpha.tga"
+ multiply_blend="true"
+ domain="0" />
+ </param>
+ </layer>
+
+ </layer_set>
+
+ <!-- =========================================================== -->
+ <driver_parameters>
+
+ <param
+ id="828"
+ group="0"
+ name="Loose Upper Clothing"
+ label="Shirt Fit"
+ show_simple="true"
+ wearable="shirt"
+ edit_group="shirt"
+ edit_group_order="4"
+ label_min="Tight Shirt"
+ label_max="Loose Shirt"
+ value_min="0"
+ value_max="1"
+ camera_distance="1.2"
+ camera_angle="30"
+ camera_elevation=".2">
+ <param_driver>
+ <driven
+ id="628" />
+
+ <driven
+ id="899"
+ min1="0.1"
+ max1="0.5"
+ max2="1"
+ min2="1" />
+ </param_driver>
+ </param>
+
+ <param
+ id="816"
+ group="0"
+ name="Loose Lower Clothing"
+ label="Pants Fit"
+ show_simple="true"
+ wearable="pants"
+ edit_group="pants"
+ edit_group_order="2.5"
+ label_min="Tight Pants"
+ label_max="Loose Pants"
+ value_min="0"
+ value_max="1"
+ camera_distance="1.8"
+ camera_angle="30"
+ camera_elevation="-.3">
+ <param_driver>
+ <driven
+ id="516" />
+
+ <driven
+ id="913"
+ min1="0.1"
+ max1="0.5"
+ max2="1"
+ min2="1" />
+ </param_driver>
+ </param>
+
+ <param
+ id="814"
+ group="0"
+ wearable="pants"
+ edit_group="pants"
+ edit_group_order="2"
+ name="Waist Height"
+ label_min="Low"
+ label_max="High"
+ value_min="0"
+ value_max="1"
+ value_default="1"
+ camera_distance="1.2"
+ camera_angle="30"
+ camera_elevation="-.3">
+ <param_driver>
+ <driven
+ id="614" />
+
+ <driven
+ id="1017" />
+
+ <driven
+ id="1035" />
+
+ <driven
+ id="914"
+ min1="0"
+ max1=".98"
+ max2="1"
+ min2="1" />
+ </param_driver>
+ </param>
+
+ <param
+ id="815"
+ group="0"
+ wearable="pants"
+ edit_group="pants"
+ edit_group_order="1"
+ name="Pants Length"
+ show_simple="true"
+ label_min="Short"
+ label_max="Long"
+ value_min="0"
+ value_max="1"
+ value_default=".8"
+ simple_percent_min="20"
+ simple_percent_max="100"
+ camera_distance="1.8"
+ camera_angle="30"
+ camera_elevation="-.3">
+ <param_driver>
+ <driven
+ id="615"
+ min1="0"
+ max1=".9"
+ max2="1"
+ min2="1" />
+
+ <driven
+ id="1018"
+ min1="0"
+ max1=".9"
+ max2="1"
+ min2="1" />
+
+ <driven
+ id="1036"
+ min1="0"
+ max1=".9"
+ max2="1"
+ min2="1" />
+
+ <driven
+ id="793"
+ min1=".9"
+ max1="1"
+ max2="1"
+ min2="1" />
+
+ <driven
+ id="915"
+ min1="0"
+ max1=".882"
+ max2="1"
+ min2="1" />
+ </param_driver>
+ </param>
+
+ <param
+ id="800"
+ group="0"
+ wearable="shirt"
+ edit_group="shirt"
+ edit_group_order="1"
+ name="Sleeve Length"
+ show_simple="true"
+ label_min="Short"
+ label_max="Long"
+ value_min="0"
+ value_max="1"
+ value_default=".89"
+ simple_percent_min="15"
+ simple_percent_max="100"
+ camera_distance="1.2"
+ camera_angle="30"
+ camera_elevation=".2">
+ <param_driver>
+ <driven
+ id="600" />
+
+ <driven
+ id="1013" />
+
+ <driven
+ id="1029" />
+
+ <driven
+ id="900"
+ min1="0"
+ max1="1"
+ max2="1"
+ min2="1" />
+ </param_driver>
+ </param>
+
+ <param
+ id="801"
+ group="0"
+ wearable="shirt"
+ edit_group="shirt"
+ edit_group_order="2"
+ name="Shirt Bottom"
+ label_min="Short"
+ label_max="Long"
+ value_min="0"
+ value_max="1"
+ value_default="1"
+ camera_distance="1.2"
+ camera_angle="30"
+ camera_elevation=".2">
+ <param_driver>
+ <driven
+ id="601" />
+
+ <driven
+ id="1014" />
+
+ <driven
+ id="1030" />
+
+ <driven
+ id="901"
+ min1="0"
+ max1=".98"
+ max2="1"
+ min2="1" />
+ </param_driver>
+ </param>
+
+ <param
+ id="802"
+ group="0"
+ wearable="shirt"
+ edit_group="shirt"
+ edit_group_order="3"
+ name="Collar Front"
+ show_simple="true"
+ label_min="Low"
+ label_max="High"
+ value_min="0"
+ value_max="1"
+ value_default=".78"
+ simple_percent_min="40"
+ simple_percent_max="100"
+ camera_distance="1.2"
+ camera_angle="15"
+ camera_elevation=".2">
+ <param_driver>
+ <driven
+ id="602" />
+
+ <driven
+ id="1015" />
+
+ <driven
+ id="1031" />
+
+ <driven
+ id="902"
+ min1="0"
+ max1=".98"
+ max2="1"
+ min2="1" />
+ </param_driver>
+ </param>
+
+ <param
+ id="781"
+ group="0"
+ wearable="shirt"
+ edit_group="shirt"
+ edit_group_order="3.1"
+ name="Collar Back"
+ label_min="Low"
+ label_max="High"
+ value_min="0"
+ value_max="1"
+ value_default=".78"
+ camera_distance="1.2"
+ camera_angle="195"
+ camera_elevation=".2">
+ <param_driver>
+ <driven
+ id="778" />
+
+ <driven
+ id="1016" />
+
+ <driven
+ id="1032" />
+
+ <driven
+ id="903"
+ min1="0"
+ max1=".98"
+ max2="1"
+ min2="1" />
+ </param_driver>
+ </param>
+
+ <param
+ id="150"
+ group="0"
+ wearable="skin"
+ edit_group="skin_bodydetail"
+ name="Body Definition"
+ label_min="Less"
+ label_max="More"
+ value_min="0"
+ value_max="1"
+ value_default="0"
+ camera_distance="1.4"
+ camera_elevation="-.2">
+ <param_driver>
+ <driven
+ id="125" />
+
+ <driven
+ id="126" />
+
+ <driven
+ id="160" />
+
+ <driven
+ id="161" />
+
+ <driven
+ id="874" />
+
+ <driven
+ id="878" />
+
+ </param_driver>
+ </param>
+
+ <param
+ id="775"
+ group="0"
+ wearable="skin"
+ edit_group="skin_bodydetail"
+ name="Body Freckles"
+ label_min="Less Freckles"
+ label_max="More Freckles"
+ value_min="0"
+ value_max="1"
+ value_default="0"
+ camera_distance="1.4"
+ camera_elevation="-.2">
+ <param_driver>
+ <driven
+ id="776" />
+
+ <driven
+ id="777" />
+ </param_driver>
+ </param>
+
+ <param
+ id="162"
+ group="0"
+ wearable="skin"
+ edit_group="skin_facedetail"
+ edit_group_order="1"
+ name="Facial Definition"
+ label_min="Less"
+ label_max="More"
+ value_min="0"
+ value_max="1"
+ camera_distance=".3"
+ camera_elevation=".07"
+ value_default="0">
+ <param_driver>
+ <driven
+ id="158" />
+
+ <driven
+ id="159" />
+
+ <driven
+ id="873" />
+ </param_driver>
+ </param>
+
+ <param
+ id="163"
+ group="3"
+ wearable="skin"
+ edit_group="skin_facedetail"
+ edit_group_order="3"
+ name="Wrinkles"
+ label_min="Less"
+ label_max="More"
+ value_min="0"
+ value_max="1"
+ camera_distance=".3"
+ camera_elevation=".07"
+ value_default="0">
+ <param_driver>
+ <!--<driven
+ id="128" />-->
+ <driven
+ id="118" />
+ </param_driver>
+ </param>
+
+ <param
+ id="505"
+ group="0"
+ wearable="shape"
+ edit_group="shape_mouth"
+ edit_group_order="3"
+ name="Lip Thickness"
+ label_min="Thin Lips"
+ label_max="Fat Lips"
+ value_min="0"
+ value_max="1"
+ value_default=".5"
+ camera_distance=".3"
+ camera_elevation=".04"
+ camera_angle="20">
+ <param_driver>
+ <driven
+ id="26"
+ min1="0"
+ max1="0"
+ max2="0"
+ min2=".5" />
+
+ <driven
+ id="28"
+ min1=".5"
+ max1="1"
+ max2="1"
+ min2="1" />
+ </param_driver>
+ </param>
+
+ <param
+ id="799"
+ group="0"
+ wearable="shape"
+ edit_group="shape_mouth"
+ edit_group_order="3.2"
+ name="Lip Ratio"
+ label="Lip Ratio"
+ show_simple="true"
+ label_min="More Upper Lip"
+ label_max="More Lower Lip"
+ value_min="0"
+ value_max="1"
+ value_default=".5"
+ camera_distance=".3"
+ camera_elevation=".04"
+ camera_angle="20">
+ <param_driver>
+ <driven
+ id="797"
+ min1="0"
+ max1="0"
+ max2="0"
+ min2=".5" />
+
+ <driven
+ id="798"
+ min1=".5"
+ max1="1"
+ max2="1"
+ min2="1" />
+ </param_driver>
+ </param>
+
+ <param
+ id="155"
+ group="0"
+ wearable="shape"
+ edit_group="shape_mouth"
+ edit_group_order="1"
+ name="Lip Width"
+ label="Lip Width"
+ label_min="Narrow Lips"
+ label_max="Wide Lips"
+ show_simple="true"
+ value_min="-0.9"
+ value_max="1.3"
+ camera_distance=".3"
+ camera_elevation=".04"
+ value_default="0">
+ <param_driver>
+ <driven
+ id="29" />
+
+ <driven
+ id="30" />
+ </param_driver>
+ </param>
+
+ <param
+ id="196"
+ group="0"
+ wearable="shape"
+ edit_group="shape_eyes"
+ edit_group_order="2"
+ name="Eye Spacing"
+ label="Eye Spacing"
+ label_min="Close Set Eyes"
+ label_max="Far Set Eyes"
+ show_simple="true"
+ value_min="-2"
+ value_max="1"
+ value_default="0"
+ camera_elevation=".1"
+ camera_distance=".35"
+ camera_angle="5">
+ <param_driver>
+ <driven
+ id="194" />
+
+ <driven
+ id="195" />
+ </param_driver>
+ </param>
+
+ <param
+ id="769"
+ group="0"
+ wearable="shape"
+ edit_group="shape_eyes"
+ edit_group_order="4.5"
+ name="Eye Depth"
+ label_min="Sunken Eyes"
+ label_max="Bugged Eyes"
+ value_min="0"
+ value_max="1"
+ value_default=".5"
+ camera_elevation=".1"
+ camera_distance=".3"
+ camera_angle="75">
+ <param_driver>
+ <driven
+ id="767" />
+
+ <driven
+ id="768" />
+ </param_driver>
+ </param>
+
+ <param
+ id="198"
+ group="0"
+ wearable="shoes"
+ edit_group="shoes"
+ edit_group_order="2"
+ name="Heel Height"
+ label_min="Low Heels"
+ label_max="High Heels"
+ value_min="0"
+ value_max="1"
+ value_default="0"
+ camera_angle="45"
+ camera_distance=".8"
+ camera_elevation="-1">
+ <param_driver>
+ <driven
+ id="197" />
+
+ <driven
+ id="500" />
+ </param_driver>
+ </param>
+
+ <param
+ id="513"
+ group="0"
+ wearable="shoes"
+ edit_group="shoes"
+ edit_group_order="3"
+ name="Heel Shape"
+ label_min="Pointy Heels"
+ label_max="Thick Heels"
+ value_min="0"
+ value_max="1"
+ value_default=".5"
+ camera_angle="45"
+ camera_distance="1.5"
+ camera_elevation="-1">
+ <param_driver>
+ <driven
+ id="509"
+ min1="0"
+ max1="0"
+ max2="0"
+ min2=".5" />
+
+ <driven
+ id="510"
+ min1=".5"
+ max1="1"
+ max2="1"
+ min2="1" />
+ </param_driver>
+ </param>
+
+ <param
+ id="514"
+ group="0"
+ wearable="shoes"
+ edit_group="shoes"
+ edit_group_order="4"
+ name="Toe Shape"
+ label_min="Pointy"
+ label_max="Square"
+ value_min="0"
+ value_max="1"
+ value_default=".5"
+ camera_angle="5"
+ camera_distance=".8"
+ camera_elevation="-.8">
+ <param_driver>
+ <driven
+ id="511"
+ min1="0"
+ max1="0"
+ max2="0"
+ min2=".5" />
+
+ <driven
+ id="512"
+ min1=".5"
+ max1="1"
+ max2="1"
+ min2="1" />
+ </param_driver>
+ </param>
+
+ <param
+ id="503"
+ group="0"
+ wearable="shoes"
+ edit_group="shoes"
+ edit_group_order="6"
+ name="Platform Height"
+ label_min="Low Platforms"
+ label_max="High Platforms"
+ value_min="0"
+ value_max="1"
+ value_default="0"
+ camera_angle="45"
+ camera_distance=".5"
+ camera_elevation="-1">
+ <param_driver>
+ <driven
+ id="501" />
+
+ <driven
+ id="502" />
+ </param_driver>
+ </param>
+
+ <param
+ id="193"
+ group="0"
+ wearable="shape"
+ edit_group="shape_head"
+ edit_group_order="3"
+ name="Head Shape"
+ label="Head Shape"
+ label_min="More Square"
+ label_max="More Round"
+ show_simple="true"
+ value_min="0"
+ value_max="1"
+ value_default=".5"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="20">
+ <param_driver>
+ <driven
+ id="188"
+ min1="0"
+ max1="0"
+ max2="0"
+ min2=".5" />
+
+ <driven
+ id="642"
+ min1="0"
+ max1="0"
+ max2="0"
+ min2=".5" />
+
+ <driven
+ id="189"
+ min1=".5"
+ max1="1"
+ max2="1"
+ min2="1" />
+
+ <driven
+ id="643"
+ min1=".5"
+ max1="1"
+ max2="1"
+ min2="1" />
+ </param_driver>
+ </param>
+
+ <param
+ id="157"
+ group="0"
+ wearable="shape"
+ edit_group="shape_torso"
+ edit_group_order="13"
+ name="Belly Size"
+ label_min="Small"
+ label_max="Big"
+ value_min="0"
+ value_max="1"
+ value_default="0"
+ camera_distance="1.4"
+ camera_angle="30"
+ camera_elevation=".2">
+ <param_driver>
+ <driven
+ id="104" />
+
+ <driven
+ id="156" />
+
+ <driven
+ id="849" />
+ </param_driver>
+ </param>
+
+ <param
+ id="637"
+ group="0"
+ wearable="shape"
+ edit_group="shape_body"
+ edit_group_order="3"
+ name="Body Fat"
+ label_min="Less Body Fat"
+ label_max="More Body Fat"
+ value_min="0"
+ value_max="1"
+ value_default="0"
+ camera_distance="1.8">
+ <param_driver>
+ <driven
+ id="633" />
+
+ <driven
+ id="634" />
+
+ <driven
+ id="635" />
+
+ <driven
+ id="851" />
+ </param_driver>
+ </param>
+
+ <param
+ id="130"
+ group="0"
+ wearable="hair"
+ edit_group="hair_style"
+ edit_group_order="8"
+ name="Front Fringe"
+ label_min="Short"
+ label_max="Long"
+ value_min="0"
+ value_max="1"
+ value_default=".45"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="20">
+ <param_driver>
+ <driven
+ id="144"
+ min1="0"
+ max1="0"
+ max2="0"
+ min2=".5" />
+
+ <driven
+ id="145"
+ min1=".5"
+ max1="1"
+ max2="1"
+ min2="1" />
+ </param_driver>
+ </param>
+
+ <param
+ id="131"
+ group="0"
+ wearable="hair"
+ edit_group="hair_style"
+ edit_group_order="9"
+ name="Side Fringe"
+ label_min="Short"
+ label_max="Long"
+ value_min="0"
+ value_max="1"
+ value_default=".5"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="90">
+ <param_driver>
+ <driven
+ id="146"
+ min1="0"
+ max1="0"
+ max2="0"
+ min2=".5" />
+
+ <driven
+ id="147"
+ min1=".5"
+ max1="1"
+ max2="1"
+ min2="1" />
+ </param_driver>
+ </param>
+
+ <param
+ id="132"
+ group="0"
+ wearable="hair"
+ edit_group="hair_style"
+ edit_group_order="10"
+ name="Back Fringe"
+ label_min="Short"
+ label_max="Long"
+ value_min="0"
+ value_max="1"
+ value_default=".39"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="160">
+ <param_driver>
+ <driven
+ id="148"
+ min1="0"
+ max1="0"
+ max2="0"
+ min2=".5" />
+
+ <driven
+ id="149"
+ min1=".5"
+ max1="1"
+ max2="1"
+ min2="1" />
+ </param_driver>
+ </param>
+
+ <param
+ id="133"
+ group="0"
+ wearable="hair"
+ edit_group="hair_style"
+ edit_group_order="2"
+ name="Hair Front"
+ label_min="Short"
+ label_max="Long"
+ value_min="0"
+ value_max="1"
+ value_default=".25"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="20">
+ <param_driver>
+ <driven
+ id="172"
+ min1="0"
+ max1="0"
+ max2="0"
+ min2=".5" />
+
+ <driven
+ id="171"
+ min1=".5"
+ max1="1"
+ max2="1"
+ min2="1" />
+ </param_driver>
+ </param>
+
+ <param
+ id="134"
+ group="0"
+ wearable="hair"
+ edit_group="hair_style"
+ edit_group_order="3"
+ name="Hair Sides"
+ label_min="Short"
+ label_max="Long"
+ value_min="0"
+ value_max="1"
+ value_default=".5"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="90">
+ <param_driver>
+ <driven
+ id="174"
+ min1="0"
+ max1="0"
+ max2="0"
+ min2=".5" />
+
+ <driven
+ id="173"
+ min1=".5"
+ max1="1"
+ max2="1"
+ min2="1" />
+ </param_driver>
+ </param>
+
+ <param
+ id="135"
+ group="0"
+ wearable="hair"
+ edit_group="hair_style"
+ edit_group_order="4"
+ name="Hair Back"
+ show_simple="true"
+ label_min="Short"
+ label_max="Long"
+ value_min="0"
+ value_max="1"
+ value_default=".55"
+ camera_elevation="-.1"
+ camera_distance=".8"
+ camera_angle="160">
+ <param_driver>
+ <driven
+ id="176"
+ min1="0"
+ max1="0"
+ max2="0"
+ min2=".5" />
+
+ <driven
+ id="175"
+ min1=".5"
+ max1="1"
+ max2="1"
+ min2="1" />
+ </param_driver>
+ </param>
+
+ <param
+ id="136"
+ group="0"
+ wearable="hair"
+ edit_group="hair_style"
+ edit_group_order="11.5"
+ name="Hair Sweep"
+ label_min="Sweep Forward"
+ label_max="Sweep Back"
+ value_min="0"
+ value_max="1"
+ value_default=".5"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="90">
+ <param_driver>
+ <driven
+ id="179"
+ min1="0"
+ max1="0"
+ max2="0"
+ min2=".5" />
+
+ <driven
+ id="178"
+ min1=".5"
+ max1="1"
+ max2="1"
+ min2="1" />
+ </param_driver>
+ </param>
+
+ <param
+ id="137"
+ group="0"
+ wearable="hair"
+ edit_group="hair_style"
+ edit_group_order="16"
+ name="Hair Tilt"
+ label_min="Left"
+ label_max="Right"
+ value_min="0"
+ value_max="1"
+ value_default=".5"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="0">
+ <param_driver>
+ <driven
+ id="190"
+ min1="0"
+ max1="0"
+ max2="0"
+ min2=".5" />
+
+ <driven
+ id="191"
+ min1=".5"
+ max1="1"
+ max2="1"
+ min2="1" />
+ </param_driver>
+ </param>
+
+ <param
+ id="608"
+ group="0"
+ wearable="jacket"
+ edit_group="jacket"
+ edit_group_order="2"
+ name="bottom length lower"
+ label="Jacket Length"
+ label_min="Short"
+ label_max="Long"
+ value_min="0"
+ value_max="1"
+ value_default=".8"
+ camera_distance="1.4"
+ camera_angle="30"
+ camera_elevation=".2">
+ <param_driver>
+ <driven
+ id="620" />
+
+ <driven
+ id="1025" />
+
+ <driven
+ id="1037" />
+
+ <driven
+ id="621" />
+
+ <driven
+ id="1027" />
+
+ <driven
+ id="1033" />
+ </param_driver>
+ </param>
+
+ <param
+ id="609"
+ group="0"
+ wearable="jacket"
+ edit_group="jacket"
+ edit_group_order="4"
+ name="open jacket"
+ label="Open Front"
+ label_min="Open"
+ label_max="Closed"
+ value_min="0"
+ value_max="1"
+ value_default=".2"
+ camera_distance="1.4"
+ camera_angle="30"
+ camera_elevation=".2">
+ <param_driver>
+ <driven
+ id="622" />
+
+ <driven
+ id="1026" />
+
+ <driven
+ id="1038" />
+
+ <driven
+ id="623" />
+
+ <driven
+ id="1028" />
+
+ <driven
+ id="1034" />
+ </param_driver>
+ </param>
+
+ <param
+ id="105"
+ group="0"
+ sex="female"
+ wearable="shape"
+ edit_group="shape_torso"
+ edit_group_order="6"
+ name="Breast Size"
+ label_min="Small"
+ label_max="Large"
+ value_min="0"
+ value_max="1"
+ value_default=".5"
+ camera_elevation=".3"
+ camera_distance="1.2"
+ camera_angle="30">
+ <param_driver>
+ <driven
+ id="843"
+ min1="0"
+ max1="0"
+ max2="0"
+ min2=".01" />
+
+ <driven
+ id="627"
+ min1="0"
+ max1="0.01"
+ max2="0.01"
+ min2=".5" />
+
+ <driven
+ id="626"
+ min1=".5"
+ max1="1"
+ max2="1"
+ min2="1" />
+ </param_driver>
+ </param>
+
+ <param
+ id="629"
+ group="0"
+ wearable="shape"
+ edit_group="shape_head"
+ edit_group_order="6"
+ name="Forehead Angle"
+ label_min="More Vertical"
+ label_max="More Sloped"
+ value_min="0"
+ value_max="1"
+ value_default=".5"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="70">
+ <param_driver>
+ <driven
+ id="630"
+ min1="0"
+ max1="0"
+ max2="0"
+ min2=".5" />
+
+ <driven
+ id="644"
+ min1="0"
+ max1="0"
+ max2="0"
+ min2=".5" />
+
+ <driven
+ id="631"
+ min1=".5"
+ max1="1"
+ max2="1"
+ min2="1" />
+
+ <driven
+ id="645"
+ min1=".5"
+ max1="1"
+ max2="1"
+ min2="1" />
+ </param_driver>
+ </param>
+
+ <param
+ id="646"
+ group="0"
+ name="Egg_Head"
+ label="Egg Head"
+ wearable="shape"
+ edit_group="shape_head"
+ edit_group_order="4"
+ label_min="Chin Heavy"
+ label_max="Forehead Heavy"
+ show_simple="true"
+ value_min="-1.3"
+ value_max="1"
+ value_default="0"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="20">
+ <param_driver>
+ <driven
+ id="640" />
+
+ <driven
+ id="186" />
+ </param_driver>
+ </param>
+
+ <param
+ id="647"
+ group="0"
+ name="Squash_Stretch_Head"
+ label="Head Stretch"
+ wearable="shape"
+ edit_group="shape_head"
+ edit_group_order="2"
+ show_simple="true"
+ label_min="Squash Head"
+ label_max="Stretch Head"
+ value_min="-0.5"
+ value_max="1"
+ value_default="0"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="20">
+ <param_driver>
+ <driven
+ id="641" />
+
+ <driven
+ id="187" />
+ </param_driver>
+ </param>
+
+ <param
+ id="649"
+ group="0"
+ sex="female"
+ wearable="shape"
+ edit_group="shape_torso"
+ edit_group_order="1.1"
+ name="Torso Muscles"
+ label="Torso Muscles"
+ show_simple="true"
+ label_min="Less Muscular"
+ label_max="More Muscular"
+ value_min="0"
+ value_max="1"
+ value_default=".5"
+ camera_elevation=".1"
+ camera_distance="1"
+ camera_angle="15">
+ <param_driver>
+ <driven
+ id="648"
+ min1="0"
+ max1="0"
+ max2="0"
+ min2=".5" />
+
+ <driven
+ id="106"
+ min1=".5"
+ max1="1"
+ max2="1"
+ min2="1" />
+ </param_driver>
+ </param>
+
+ <param
+ id="678"
+ group="0"
+ sex="male"
+ wearable="shape"
+ edit_group="shape_torso"
+ edit_group_order="1"
+ name="Torso Muscles"
+ show_simple="true"
+ label_min="Less Muscular"
+ label_max="More Muscular"
+ value_min="0"
+ value_max="1"
+ value_default=".5"
+ camera_elevation=".1"
+ camera_distance="1.2"
+ camera_angle="0">
+ <param_driver>
+ <driven
+ id="677"
+ min1="0"
+ max1="0"
+ max2="0"
+ min2=".5" />
+
+ <driven
+ id="106"
+ min1=".5"
+ max1="1"
+ max2="1"
+ min2="1" />
+ </param_driver>
+ </param>
+
+ <param
+ id="652"
+ group="0"
+ wearable="shape"
+ edit_group="shape_legs"
+ edit_group_order="1"
+ name="Leg Muscles"
+ label_min="Less Muscular"
+ label_max="More Muscular"
+ show_simple="true"
+ value_min="0"
+ value_max="1"
+ value_default=".5"
+ camera_distance="1.3"
+ camera_elevation="-.5"
+ camera_angle="15">
+ <param_driver>
+ <driven
+ id="651"
+ min1="0"
+ max1="0"
+ max2="0"
+ min2=".5" />
+
+ <driven
+ id="152"
+ min1=".5"
+ max1="1"
+ max2="1"
+ min2="1" />
+ </param_driver>
+ </param>
+
+ <param
+ id="80"
+ name="male"
+ group="0"
+ edit_group="dummy"
+ wearable="shape"
+ value_min="0"
+ value_max="1">
+ <param_driver>
+ <driven
+ id="32" />
+
+ <driven
+ id="153" />
+
+ <driven
+ id="40" />
+
+ <driven
+ id="100" />
+
+ <driven
+ id="857" />
+ </param_driver>
+ </param>
+
+ <param
+ id="659"
+ group="0"
+ wearable="shape"
+ edit_group="shape_mouth"
+ edit_group_order="5"
+ name="Mouth Corner"
+ label_min="Corner Down"
+ label_max="Corner Up"
+ value_min="0"
+ value_max="1"
+ value_default=".5"
+ camera_elevation="0"
+ camera_distance=".28">
+ <param_driver>
+ <driven
+ id="658"
+ min1="0"
+ max1="0"
+ max2="0"
+ min2=".5" />
+
+ <driven
+ id="657"
+ min1=".5"
+ max1="1"
+ max2="1"
+ min2="1" />
+ </param_driver>
+ </param>
+
+ <param
+ id="662"
+ group="0"
+ wearable="shape"
+ edit_group="shape_head"
+ edit_group_order="5"
+ name="Face Shear"
+ label_min="Shear Right Up"
+ label_max="Shear Left Up"
+ value_min="0"
+ value_max="1"
+ value_default=".5"
+ camera_elevation=".1"
+ camera_distance=".5">
+ <param_driver>
+ <driven
+ id="660" />
+
+ <driven
+ id="661" />
+
+ <driven
+ id="774" />
+ </param_driver>
+ </param>
+
+ <param
+ id="773"
+ group="0"
+ wearable="shape"
+ edit_group="shape_head"
+ edit_group_order="4.5"
+ name="Head Length"
+ label_min="Flat Head"
+ label_max="Long Head"
+ value_min="0"
+ value_max="1"
+ value_default=".5"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="75">
+ <param_driver>
+ <driven
+ id="770" />
+
+ <driven
+ id="771" />
+
+ <driven
+ id="772" />
+ </param_driver>
+ </param>
+
+ <param
+ id="682"
+ group="0"
+ wearable="shape"
+ edit_group="shape_head"
+ edit_group_order="1"
+ name="Head Size"
+ label="Head Size"
+ label_min="Small Head"
+ label_max="Big Head"
+ show_simple="true"
+ value_min="0"
+ value_max="1"
+ value_default=".5"
+ camera_elevation=".1"
+ camera_distance=".5">
+ <param_driver>
+ <driven
+ id="679" />
+
+ <driven
+ id="694" />
+
+ <driven
+ id="680" />
+
+ <driven
+ id="681" />
+
+ <driven
+ id="655" />
+ </param_driver>
+ </param>
+
+ <param
+ id="690"
+ group="0"
+ wearable="shape"
+ edit_group="shape_eyes"
+ edit_group_order="1"
+ name="Eye Size"
+ label="Eye Size"
+ label_min="Beady Eyes"
+ label_max="Anime Eyes"
+ value_min="0"
+ value_max="1"
+ value_default=".5"
+ show_simple="true"
+ camera_elevation=".1"
+ camera_distance=".35">
+ <param_driver>
+ <driven
+ id="686" />
+
+ <driven
+ id="687" />
+
+ <driven
+ id="695" />
+
+ <driven
+ id="688" />
+
+ <driven
+ id="691" />
+
+ <driven
+ id="689" />
+ </param_driver>
+ </param>
+
+ <param
+ id="752"
+ group="0"
+ sex="male"
+ wearable="hair"
+ edit_group="hair_facial"
+ edit_group_order="1"
+ name="Hair Thickness"
+ label_min="5 O'Clock Shadow"
+ label_max="Bushy Hair"
+ value_min="0"
+ value_max="1"
+ value_default=".5"
+ camera_elevation="0"
+ camera_distance=".28">
+ <param_driver>
+ <driven
+ id="751"
+ min1="0"
+ max1="0"
+ max2="0"
+ min2=".2" />
+
+ <driven
+ id="1012"
+ min1="0"
+ max1="0"
+ max2=".2"
+ min2=".6" />
+
+ <driven
+ id="400"
+ min1=".2"
+ max1="1"
+ max2="1"
+ min2="1" />
+ </param_driver>
+ </param>
+
+ <param
+ id="763"
+ group="0"
+ wearable="hair"
+ edit_group="hair_style"
+ edit_group_order="1"
+ name="Hair Volume"
+ show_simple="true"
+ label_min="Less Volume"
+ label_max="More Volume"
+ value_min="0"
+ value_max="1"
+ value_default=".55"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="20">
+ <param_driver>
+ <driven
+ id="761"
+ min1="0"
+ max1="0"
+ max2="0"
+ min2=".5" />
+
+ <driven
+ id="180"
+ min1=".5"
+ max1="1"
+ max2="1"
+ min2="1" />
+ </param_driver>
+ </param>
+
+ <param
+ id="834"
+ group="0"
+ wearable="jacket"
+ edit_group="colorpicker"
+ name="jacket_red"
+ value_min="0"
+ value_max="1"
+ value_default="1">
+ <param_driver>
+ <driven
+ id="809"
+ min1="0"
+ max1="1"
+ max2="1"
+ min2="1" />
+
+ <driven
+ id="831"
+ min1="0"
+ max1="1"
+ max2="1"
+ min2="1" />
+ </param_driver>
+ </param>
+
+ <param
+ id="835"
+ group="0"
+ wearable="jacket"
+ edit_group="colorpicker"
+ name="jacket_green"
+ value_min="0"
+ value_max="1"
+ value_default="1">
+ <param_driver>
+ <driven
+ id="810"
+ min1="0"
+ max1="1"
+ max2="1"
+ min2="1" />
+
+ <driven
+ id="832"
+ min1="0"
+ max1="1"
+ max2="1"
+ min2="1" />
+ </param_driver>
+ </param>
+
+ <param
+ id="836"
+ group="0"
+ wearable="jacket"
+ edit_group="colorpicker"
+ name="jacket_blue"
+ value_min="0"
+ value_max="1"
+ value_default="1">
+ <param_driver>
+ <driven
+ id="811"
+ min1="0"
+ max1="1"
+ max2="1"
+ min2="1" />
+
+ <driven
+ id="833"
+ min1="0"
+ max1="1"
+ max2="1"
+ min2="1" />
+ </param_driver>
+ </param>
+
+ <param
+ id="785"
+ group="0"
+ wearable="hair"
+ edit_group="hair_style"
+ edit_group_order="14.6"
+ name="Pigtails"
+ show_simple="true"
+ label_min="Short Pigtails"
+ label_max="Long Pigtails"
+ value_min="0"
+ value_max="1"
+ value_default="0"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="15">
+ <param_driver>
+ <driven
+ id="782"
+ min1="0"
+ max1=".10"
+ max2=".10"
+ min2=".5" />
+
+ <driven
+ id="783"
+ min1=".10"
+ max1=".5"
+ max2=".5"
+ min2=".75" />
+
+ <driven
+ id="790"
+ min1=".5"
+ max1=".75"
+ max2=".75"
+ min2="1" />
+
+ <driven
+ id="784"
+ min1=".75"
+ max1="1"
+ max2="1"
+ min2="1" />
+ </param_driver>
+ </param>
+
+ <param
+ id="789"
+ group="0"
+ wearable="hair"
+ edit_group="hair_style"
+ edit_group_order="14.7"
+ name="Ponytail"
+ label_min="Short Ponytail"
+ label_max="Long Ponytail"
+ value_min="0"
+ value_max="1"
+ value_default="0"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="180">
+ <param_driver>
+ <driven
+ id="786"
+ min1="0"
+ max1=".10"
+ max2=".10"
+ min2=".66" />
+
+ <driven
+ id="787"
+ min1=".10"
+ max1=".66"
+ max2=".66"
+ min2="1" />
+
+ <driven
+ id="788"
+ min1=".66"
+ max1="1"
+ max2="1"
+ min2="1" />
+ </param_driver>
+ </param>
+
+ <param
+ id="795"
+ group="0"
+ name="Butt Size"
+ label="Butt Size"
+ wearable="shape"
+ edit_group="shape_legs"
+ edit_group_order="4"
+ label_min="Flat Butt"
+ label_max="Big Butt"
+ value_min="0"
+ value_max="1"
+ value_default=".25"
+ camera_angle="180"
+ camera_distance=".6">
+ <param_driver>
+ <driven
+ id="867"
+ min1="0"
+ max1="0"
+ max2="0"
+ min2=".3" />
+
+ <driven
+ id="794"
+ min1="0"
+ max1="0"
+ max2="0"
+ min2=".3" />
+
+ <driven
+ id="151"
+ min1=".3"
+ max1="1"
+ max2="1"
+ min2="1" />
+
+ <driven
+ id="852"
+ min1=".3"
+ max1="1"
+ max2="1"
+ min2="1" />
+ </param_driver>
+ </param>
+
+ <param
+ id="841"
+ group="0"
+ name="Bowed_Legs"
+ label="Knee Angle"
+ wearable="shape"
+ edit_group_order="5.5"
+ edit_group="shape_legs"
+ label_min="Knock Kneed"
+ label_max="Bow Legged"
+ value_min="-1"
+ value_max="1"
+ value_default="0"
+ camera_distance="1.3"
+ camera_elevation="-.5">
+ <param_driver>
+ <driven
+ id="853" />
+
+ <driven
+ id="847" />
+ </param_driver>
+ </param>
+
+ <param
+ id="753"
+ group="0"
+ name="Saddlebags"
+ label="Saddle Bags"
+ wearable="shape"
+ edit_group="shape_legs"
+ edit_group_order="5"
+ label_min="Less Saddle"
+ label_max="More Saddle"
+ value_min="-0.5"
+ value_max="3"
+ value_default="0"
+ camera_angle="0"
+ camera_distance="1.2">
+ <param_driver>
+ <driven
+ id="850" />
+
+ <driven
+ id="854" />
+ </param_driver>
+ </param>
+
+ <param
+ id="676"
+ group="0"
+ name="Love_Handles"
+ label="Love Handles"
+ wearable="shape"
+ edit_group="shape_torso"
+ edit_group_order="12"
+ label_min="Less Love"
+ label_max="More Love"
+ value_min="-1"
+ value_max="2"
+ value_default="0"
+ camera_elevation=".3"
+ camera_distance=".9">
+ <param_driver>
+ <driven
+ id="855" />
+
+ <driven
+ id="856" />
+ </param_driver>
+ </param>
+
+ <param
+ id="863"
+ group="0"
+ name="skirt_looseness"
+ label="Skirt Fit"
+ show_simple="true"
+ clothing_morph="true"
+ wearable="skirt"
+ edit_group_order="2"
+ edit_group="skirt"
+ label_min="Tight Skirt"
+ label_max="Poofy Skirt"
+ value_min="0"
+ value_max="1"
+ value_default=".333"
+ camera_distance="1.3"
+ camera_elevation="-.5">
+ <param_driver>
+ <driven
+ id="866"
+ min1="0"
+ max1="0"
+ max2="0"
+ min2=".2" />
+
+ <driven
+ id="846"
+ min1="0"
+ max1=".5"
+ max2=".5"
+ min2="1" />
+
+ <driven
+ id="845"
+ min1=".5"
+ max1="1"
+ max2="1"
+ min2="1" />
+ </param_driver>
+ </param>
+
+ <param
+ id="119"
+ group="0"
+ wearable="hair"
+ edit_group="hair_eyebrows"
+ edit_group_order="1"
+ name="Eyebrow Size"
+ show_simple="true"
+ label_min="Thin Eyebrows"
+ label_max="Bushy Eyebrows"
+ value_min="0"
+ value_max="1"
+ value_default="0.5"
+ camera_elevation=".1"
+ camera_distance=".3">
+ <param_driver>
+ <driven
+ id="1000" />
+
+ <driven
+ id="1001" />
+ </param_driver>
+ </param>
+
+ <param
+ id="750"
+ group="0"
+ wearable="hair"
+ edit_group="hair_eyebrows"
+ edit_group_order="2"
+ name="Eyebrow Density"
+ label_min="Sparse"
+ label_max="Dense"
+ value_min="0"
+ value_max="1"
+ value_default="0.7"
+ camera_elevation=".1"
+ camera_distance=".3">
+ <param_driver>
+ <driven
+ id="1002" />
+
+ <driven
+ id="1003" />
+ </param_driver>
+ </param>
+
+ <param
+ id="166"
+ sex="male"
+ group="0"
+ wearable="hair"
+ edit_group="hair_facial"
+ edit_group_order="2"
+ name="Sideburns"
+ show_simple="true"
+ label_min="Short Sideburns"
+ label_max="Mutton Chops"
+ value_min="0"
+ value_max="1"
+ value_default="0.0"
+ camera_elevation=".1"
+ camera_distance=".3"
+ camera_angle="30">
+ <param_driver>
+ <driven
+ id="1004" />
+
+ <driven
+ id="1005" />
+ </param_driver>
+ </param>
+
+ <param
+ id="167"
+ sex="male"
+ group="0"
+ wearable="hair"
+ edit_group="hair_facial"
+ edit_group_order="3"
+ name="Moustache"
+ show_simple="true"
+ label_min="Chaplin"
+ label_max="Handlebars"
+ value_min="0"
+ value_max="1"
+ value_default="0.0"
+ camera_elevation=".1"
+ camera_distance=".3"
+ camera_angle="30">
+ <param_driver>
+ <driven
+ id="1006" />
+
+ <driven
+ id="1007" />
+ </param_driver>
+ </param>
+
+ <param
+ id="168"
+ sex="male"
+ group="0"
+ wearable="hair"
+ edit_group="hair_facial"
+ edit_group_order="5"
+ name="Soulpatch"
+ show_simple="true"
+ label_min="Less soul"
+ label_max="More soul"
+ value_min="0"
+ value_max="1"
+ value_default="0.0"
+ camera_elevation="-.1"
+ camera_distance=".3"
+ camera_angle="0">
+ <param_driver>
+ <driven
+ id="1008" />
+
+ <driven
+ id="1009" />
+ </param_driver>
+ </param>
+
+ <param
+ id="169"
+ sex="male"
+ group="0"
+ wearable="hair"
+ edit_group="hair_facial"
+ edit_group_order="4"
+ name="Chin Curtains"
+ show_simple="true"
+ label_min="Less Curtains"
+ label_max="More Curtains"
+ value_min="0"
+ value_max="1"
+ value_default="0.0"
+ camera_elevation="-.1"
+ camera_distance=".3"
+ camera_angle="45">
+ <param_driver>
+ <driven
+ id="1010" />
+
+ <driven
+ id="1011" />
+ </param_driver>
+ </param>
+
+ <param
+ id="606"
+ group="0"
+ wearable="jacket"
+ edit_group="jacket"
+ edit_group_order="1"
+ name="Sleeve Length"
+ label_min="Short"
+ label_max="Long"
+ value_min="0"
+ value_max="1"
+ value_default=".8"
+ camera_distance="1.2"
+ camera_angle="30"
+ camera_elevation=".2">
+ <param_driver>
+ <driven
+ id="1019" />
+
+ <driven
+ id="1039" />
+
+ <driven
+ id="1020" />
+ </param_driver>
+ </param>
+
+ <param
+ id="607"
+ group="0"
+ wearable="jacket"
+ edit_group="jacket"
+ edit_group_order="3"
+ name="Collar Front"
+ label_min="Low"
+ label_max="High"
+ value_min="0"
+ value_max="1"
+ value_default=".8"
+ camera_distance="1.2"
+ camera_angle="15"
+ camera_elevation=".2">
+ <param_driver>
+ <driven
+ id="1021" />
+
+ <driven
+ id="1040" />
+
+ <driven
+ id="1022" />
+ </param_driver>
+ </param>
+
+ <param
+ id="780"
+ group="0"
+ wearable="jacket"
+ edit_group="jacket"
+ edit_group_order="3.5"
+ name="Collar Back"
+ label_min="Low"
+ label_max="High"
+ value_min="0"
+ value_max="1"
+ value_default=".8"
+ camera_distance="1.2"
+ camera_angle="195"
+ camera_elevation=".2">
+ <param_driver>
+ <driven
+ id="1023" />
+
+ <driven
+ id="1041" />
+
+ <driven
+ id="1024" />
+ </param_driver>
+ </param>
+
+ <param
+ id="603"
+ group="0"
+ wearable="undershirt"
+ edit_group="undershirt"
+ edit_group_order="1"
+ name="Sleeve Length"
+ label_min="Short"
+ label_max="Long"
+ value_min=".01"
+ value_max="1"
+ value_default=".4"
+ camera_distance="1.2"
+ camera_angle="30"
+ camera_elevation=".2">
+ <param_driver>
+ <driven
+ id="1042" />
+
+ <driven
+ id="1043" />
+ </param_driver>
+ </param>
+
+ <param
+ id="604"
+ group="0"
+ wearable="undershirt"
+ edit_group="undershirt"
+ edit_group_order="2"
+ name="Bottom"
+ label_min="Short"
+ label_max="Long"
+ value_min="0"
+ value_max="1"
+ value_default=".85"
+ camera_distance="1.2"
+ camera_angle="30"
+ camera_elevation=".2">
+ <param_driver>
+ <driven
+ id="1044" />
+
+ <driven
+ id="1045" />
+ </param_driver>
+ </param>
+
+ <param
+ id="605"
+ group="0"
+ wearable="undershirt"
+ edit_group="undershirt"
+ edit_group_order="3"
+ name="Collar Front"
+ label_min="Low"
+ label_max="High"
+ value_min="0"
+ value_max="1"
+ value_default=".84"
+ camera_distance=".8"
+ camera_angle="15"
+ camera_elevation=".2">
+ <param_driver>
+ <driven
+ id="1046" />
+
+ <driven
+ id="1047" />
+ </param_driver>
+ </param>
+
+ <param
+ id="779"
+ group="0"
+ wearable="undershirt"
+ edit_group="undershirt"
+ edit_group_order="4"
+ name="Collar Back"
+ label_min="Low"
+ label_max="High"
+ value_min="0"
+ value_max="1"
+ value_default=".84"
+ camera_distance=".8"
+ camera_angle="195"
+ camera_elevation=".2">
+ <param_driver>
+ <driven
+ id="1048" />
+
+ <driven
+ id="1049" />
+ </param_driver>
+ </param>
+
+ <param
+ id="617"
+ group="0"
+ wearable="socks"
+ edit_group="socks"
+ name="Socks Length"
+ label_min="Short"
+ label_max="Long"
+ value_min="0"
+ value_max="1"
+ value_default="0.35"
+ camera_distance=".95"
+ camera_angle="30"
+ camera_elevation="-.75">
+ <param_driver>
+ <driven
+ id="1050" />
+
+ <driven
+ id="1051" />
+ </param_driver>
+ </param>
+
+ <param
+ id="616"
+ group="0"
+ wearable="shoes"
+ edit_group="shoes"
+ edit_group_order="1"
+ name="Shoe Height"
+ label_min="Short"
+ label_max="Tall"
+ value_min="0"
+ value_max="1"
+ value_default="0.1"
+ camera_distance="1.2"
+ camera_angle="30"
+ camera_elevation="-.75">
+ <param_driver>
+ <driven
+ id="1052" />
+
+ <driven
+ id="1053" />
+ </param_driver>
+ </param>
+
+ <param
+ id="619"
+ group="0"
+ wearable="underpants"
+ edit_group="underpants"
+ name="Pants Length"
+ label_min="Short"
+ label_max="Long"
+ value_min="0"
+ value_max="1"
+ value_default=".3"
+ camera_distance="1.2"
+ camera_angle="30"
+ camera_elevation="-.3">
+ <param_driver>
+ <driven
+ id="1054" />
+
+ <driven
+ id="1055" />
+ </param_driver>
+ </param>
+
+ <param
+ id="624"
+ group="0"
+ wearable="underpants"
+ edit_group="underpants"
+ name="Pants Waist"
+ label_min="Low"
+ label_max="High"
+ value_min="0"
+ value_max="1"
+ value_default=".8"
+ camera_distance="1.2"
+ camera_angle="30"
+ camera_elevation="-.3">
+ <param_driver>
+ <driven
+ id="1056" />
+
+ <driven
+ id="1057" />
+ </param_driver>
+ </param>
+
+ <param
+ id="93"
+ group="0"
+ wearable="gloves"
+ edit_group="gloves"
+ name="Glove Length"
+ label_min="Short"
+ label_max="Long"
+ value_min=".01"
+ value_max="1"
+ value_default=".8"
+ camera_distance="1.2"
+ camera_angle="30"
+ camera_elevation=".2">
+ <param_driver>
+ <driven
+ id="1058" />
+
+ <driven
+ id="1059" />
+ </param_driver>
+ </param>
+
+ <param
+ id="844"
+ group="0"
+ wearable="gloves"
+ edit_group="gloves"
+ name="Glove Fingers"
+ label_min="Fingerless"
+ label_max="Fingers"
+ value_min=".01"
+ value_max="1"
+ value_default="1"
+ camera_distance="1.2"
+ camera_angle="30"
+ camera_elevation=".2">
+ <param_driver>
+ <driven
+ id="1060" />
+
+ <driven
+ id="1061" />
+ </param_driver>
+ </param>
+
+ <!--Pointy eyebrows became a driver/driven param with new max value for backwards compatibility between 1.0 and 1.1-->
+ <param
+ id="16"
+ group="0"
+ name="Pointy_Eyebrows"
+ label="Eyebrow Points"
+ wearable="hair"
+ edit_group="hair_eyebrows"
+ edit_group_order="4"
+ label_min="Smooth"
+ label_max="Pointy"
+ value_min="-.5"
+ value_max="3"
+ camera_elevation=".1"
+ camera_distance=".3">
+ <param_driver>
+ <driven
+ id="870" />
+ </param_driver>
+ </param>
+
+ <!--Lower eyebrows became a driver/driven param with new min value for backwards compatibility between 1.0 and 1.1-->
+ <param
+ id="757"
+ group="0"
+ name="Lower_Eyebrows"
+ label="Eyebrow Height"
+ show_simple="true"
+ wearable="hair"
+ edit_group="hair_eyebrows"
+ edit_group_order="2.5"
+ label_min="Higher"
+ label_max="Lower"
+ value_min="-4"
+ value_max="2"
+ value_default="-1"
+ camera_elevation=".1"
+ camera_distance=".3">
+ <param_driver>
+ <driven
+ id="871" />
+ </param_driver>
+ </param>
+
+ <!--Arced eyebrows became a driver/driven param with new max value for backwards compatibility between 1.0 and 1.1-->
+ <param
+ id="31"
+ group="0"
+ name="Arced_Eyebrows"
+ label="Eyebrow Arc"
+ wearable="hair"
+ edit_group="hair_eyebrows"
+ edit_group_order="3"
+ label_min="Flat"
+ label_max="Arced"
+ value_min="0"
+ value_max="2"
+ value_default=".5"
+ camera_elevation=".1"
+ camera_distance=".3">
+ <param_driver>
+ <driven
+ id="872" />
+ </param_driver>
+ </param>
+
+
+ <param
+ id="877"
+ group="3"
+ name="Jacket Wrinkles"
+ label="Jacket Wrinkles"
+ wearable="jacket"
+ edit_group="jacket"
+ edit_group_order="20"
+ label_min="No Wrinkles"
+ label_max="Wrinkles"
+ value_min="0"
+ value_max="1"
+ value_default="0"
+ camera_elevation=".1"
+ camera_distance=".3">
+ <param_driver>
+ <driven
+ id="875" />
+
+
+ <driven
+ id="876" />
+ </param_driver>
+ </param>
+
+ <param
+ id="1071"
+ group="2"
+ wearable="tattoo"
+ edit_group="colorpicker"
+ name="tattoo_red"
+ value_min="0"
+ value_max="1"
+ value_default="1">
+ <param_driver>
+ <driven
+ id="1062"
+ min1="0"
+ max1="1"
+ max2="1"
+ min2="1" />
+
+ <driven
+ id="1065"
+ min1="0"
+ max1="1"
+ max2="1"
+ min2="1" />
+
+ <driven
+ id="1068"
+ min1="0"
+ max1="1"
+ max2="1"
+ min2="1" />
+ </param_driver>
+ </param>
+
+ <param
+ id="1072"
+ group="2"
+ wearable="tattoo"
+ edit_group="colorpicker"
+ name="tattoo_green"
+ value_min="0"
+ value_max="1"
+ value_default="1">
+ <param_driver>
+ <driven
+ id="1063"
+ min1="0"
+ max1="1"
+ max2="1"
+ min2="1" />
+
+ <driven
+ id="1066"
+ min1="0"
+ max1="1"
+ max2="1"
+ min2="1" />
+
+ <driven
+ id="1069"
+ min1="0"
+ max1="1"
+ max2="1"
+ min2="1" />
+ </param_driver>
+ </param>
+
+ <param
+ id="1073"
+ group="2"
+ wearable="tattoo"
+ edit_group="colorpicker"
+ name="tattoo_blue"
+ value_min="0"
+ value_max="1"
+ value_default="1">
+ <param_driver>
+ <driven
+ id="1064"
+ min1="0"
+ max1="1"
+ max2="1"
+ min2="1" />
+
+ <driven
+ id="1067"
+ min1="0"
+ max1="1"
+ max2="1"
+ min2="1" />
+
+ <driven
+ id="1070"
+ min1="0"
+ max1="1"
+ max2="1"
+ min2="1" />
+
+ </param_driver>
+ </param>
+
+ <!-- ==PHYSICS PARAMETERS======================================= -->
+
+ <param
+ id="1100"
+ group="1"
+ sex="female"
+ wearable="physics"
+ name="Breast_Physics_UpDown_Controller"
+ label="Breast Physics UpDown Controller"
+ value_min="-1"
+ value_max="1"
+ value_default="0">
+ <param_driver>
+ <driven
+ id="1200" />
+ </param_driver>
+ </param>
+
+ <param
+ id="1101"
+ group="1"
+ sex="female"
+ wearable="physics"
+ name="Breast_Physics_InOut_Controller"
+ label="Breast Physics InOut Controller"
+ value_min="-1"
+ value_max="1"
+ value_default="0">
+ <param_driver>
+ <driven
+ id="1201" />
+ </param_driver>
+ </param>
+
+ <param
+ id="1102"
+ group="1"
+ wearable="physics"
+ name="Belly_Physics_UpDown_Controller"
+ label="Belly Physics UpDown Controller"
+ value_min="-1"
+ value_max="1"
+ value_default="0">
+ <param_driver>
+ <driven
+ id="1202" />
+ <driven
+ id="1203" />
+ <driven
+ id="1204" />
+ </param_driver>
+ </param>
+
+ <param
+ id="1103"
+ group="1"
+ wearable="shape"
+ name="Butt_Physics_UpDown_Controller"
+ label="Butt Physics UpDown Controller"
+ value_min="-1"
+ value_max="1"
+ value_default="0">
+ <param_driver>
+ <driven
+ id="1205" />
+ </param_driver>
+ </param>
+
+ <param
+ id="1104"
+ group="1"
+ wearable="shape"
+ name="Butt_Physics_LeftRight_Controller"
+ label="Butt Physics LeftRight Controller"
+ value_min="-1"
+ value_max="1"
+ value_default="0">
+ <param_driver>
+ <driven
+ id="1206" />
+ </param_driver>
+ </param>
+
+ <param
+ id="1105"
+ group="1"
+ wearable="shape"
+ name="Breast_Physics_LeftRight_Controller"
+ label="Breast Physics LeftRight Controller"
+ value_min="-1"
+ value_max="1"
+ value_default="0">
+ <param_driver>
+ <driven
+ id="1207" />
+ </param_driver>
+ </param>
+
+ <param
+ id="10000"
+ group="0"
+ sex="female"
+ name="Breast_Physics_Mass"
+ label="Breast Physics Mass"
+ wearable="physics"
+ edit_group="physics_advanced"
+ value_default=".1"
+ value_min=".1"
+ value_max="1">
+ <param_driver />
+ </param>
+ <param
+ id="10001"
+ group="0"
+ sex="female"
+ name="Breast_Physics_Gravity"
+ label="Breast Physics Gravity"
+ wearable="physics"
+ edit_group="physics_advanced"
+ value_default="0"
+ value_min="0"
+ value_max="30">
+ <param_driver />
+ </param>
+
+ <param
+ id="10002"
+ group="0"
+ sex="female"
+ name="Breast_Physics_Drag"
+ label="Breast Physics Drag"
+ wearable="physics"
+ edit_group="physics_advanced"
+ value_default="1"
+ value_min="0"
+ value_max="10">
+ <param_driver />
+ </param>
+
+ <param
+ id="10003"
+ group="0"
+ sex="female"
+ name="Breast_Physics_UpDown_Max_Effect"
+ label="Breast Physics UpDown Max Effect"
+ wearable="physics"
+ edit_group="physics_breasts_updown"
+ value_default="0"
+ value_min="0"
+ value_max="3">
+ <param_driver />
+ </param>
+ <param
+ id="10004"
+ group="0"
+ sex="female"
+ name="Breast_Physics_UpDown_Spring"
+ label="Breast Physics UpDown Spring"
+ wearable="physics"
+ edit_group="physics_breasts_updown"
+ value_default="10"
+ value_min="0"
+ value_max="100">
+ <param_driver />
+ </param>
+ <param
+ id="10005"
+ group="0"
+ sex="female"
+ name="Breast_Physics_UpDown_Gain"
+ label="Breast Physics UpDown Gain"
+ wearable="physics"
+ edit_group="physics_breasts_updown"
+ value_default="10"
+ value_min="1"
+ value_max="100">
+ <param_driver />
+ </param>
+ <param
+ id="10006"
+ group="0"
+ sex="female"
+ name="Breast_Physics_UpDown_Damping"
+ label="Breast Physics UpDown Damping"
+ wearable="physics"
+ edit_group="physics_breasts_updown"
+ value_default=".2"
+ value_min="0"
+ value_max="1">
+ <param_driver />
+ </param>
+
+ <param
+ id="10007"
+ group="0"
+ sex="female"
+ name="Breast_Physics_InOut_Max_Effect"
+ label="Breast Physics InOut Max Effect"
+ wearable="physics"
+ edit_group="physics_breasts_inout"
+ value_default="0"
+ value_min="0"
+ value_max="3">
+ <param_driver />
+ </param>
+ <param
+ id="10008"
+ group="0"
+ sex="female"
+ name="Breast_Physics_InOut_Spring"
+ label="Breast Physics InOut Spring"
+ wearable="physics"
+ edit_group="physics_breasts_inout"
+ value_default="10"
+ value_min="0"
+ value_max="100">
+ <param_driver />
+ </param>
+ <param
+ id="10009"
+ group="0"
+ sex="female"
+ name="Breast_Physics_InOut_Gain"
+ label="Breast Physics InOut Gain"
+ wearable="physics"
+ edit_group="physics_breasts_inout"
+ value_default="10"
+ value_min="1"
+ value_max="100">
+ <param_driver />
+ </param>
+ <param
+ id="10010"
+ group="0"
+ sex="female"
+ name="Breast_Physics_InOut_Damping"
+ label="Breast Physics InOut Damping"
+ wearable="physics"
+ edit_group="physics_breasts_inout"
+ value_default=".2"
+ value_min="0"
+ value_max="1">
+ <param_driver />
+ </param>
+
+ <param
+ id="10011"
+ group="0"
+ name="Belly_Physics_Mass"
+ label="Belly Physics Mass"
+ wearable="physics"
+ edit_group="physics_advanced"
+ value_default=".1"
+ value_min=".1"
+ value_max="1">
+ <param_driver />
+ </param>
+ <param
+ id="10012"
+ group="0"
+ name="Belly_Physics_Gravity"
+ label="Belly Physics Gravity"
+ wearable="physics"
+ edit_group="physics_advanced"
+ value_default="0"
+ value_min="0"
+ value_max="30">
+ <param_driver />
+ </param>
+ <param
+ id="10013"
+ group="0"
+ name="Belly_Physics_Drag"
+ label="Belly Physics Drag"
+ wearable="physics"
+ edit_group="physics_advanced"
+ value_default="1"
+ value_min="0"
+ value_max="10">
+ <param_driver />
+ </param>
+ <param
+ id="10014"
+ group="0"
+ name="Belly_Physics_UpDown_Max_Effect"
+ label="Belly Physics UpDown Max Effect"
+ wearable="physics"
+ edit_group="physics_belly_updown"
+ value_default="0"
+ value_min="0"
+ value_max="3">
+ <param_driver />
+ </param>
+ <param
+ id="10015"
+ group="0"
+ name="Belly_Physics_UpDown_Spring"
+ label="Belly Physics UpDown Spring"
+ wearable="physics"
+ edit_group="physics_belly_updown"
+ value_default="10"
+ value_min="0"
+ value_max="100">
+ <param_driver />
+ </param>
+ <param
+ id="10016"
+ group="0"
+ name="Belly_Physics_UpDown_Gain"
+ label="Belly Physics UpDown Gain"
+ wearable="physics"
+ edit_group="physics_belly_updown"
+ value_default="10"
+ value_min="1"
+ value_max="100">
+ <param_driver />
+ </param>
+ <param
+ id="10017"
+ group="0"
+ name="Belly_Physics_UpDown_Damping"
+ label="Belly Physics UpDown Damping"
+ wearable="physics"
+ edit_group="physics_belly_updown"
+ value_default=".2"
+ value_min="0"
+ value_max="1">
+ <param_driver />
+ </param>
+
+ <param
+ id="10018"
+ group="0"
+ name="Butt_Physics_Mass"
+ label="Butt Physics Mass"
+ wearable="physics"
+ edit_group="physics_advanced"
+ value_default=".1"
+ value_min=".1"
+ value_max="1">
+ <param_driver />
+ </param>
+ <param
+ id="10019"
+ group="0"
+ name="Butt_Physics_Gravity"
+ label="Butt Physics Gravity"
+ wearable="physics"
+ edit_group="physics_advanced"
+ value_default="0"
+ value_min="0"
+ value_max="30">
+ <param_driver />
+ </param>
+ <param
+ id="10020"
+ group="0"
+ name="Butt_Physics_Drag"
+ label="Butt Physics Drag"
+ wearable="physics"
+ edit_group="physics_advanced"
+ value_default="1"
+ value_min="0"
+ value_max="10">
+ <param_driver />
+ </param>
+
+ <param
+ id="10021"
+ group="0"
+ name="Butt_Physics_UpDown_Max_Effect"
+ label="Butt Physics UpDown Max Effect"
+ wearable="physics"
+ edit_group="physics_butt_updown"
+ value_default="0"
+ value_min="0"
+ value_max="3">
+ <param_driver />
+ </param>
+ <param
+ id="10022"
+ group="0"
+ name="Butt_Physics_UpDown_Spring"
+ label="Butt Physics UpDown Spring"
+ wearable="physics"
+ edit_group="physics_butt_updown"
+ value_default="10"
+ value_min="0"
+ value_max="100">
+ <param_driver />
+ </param>
+ <param
+ id="10023"
+ group="0"
+ name="Butt_Physics_UpDown_Gain"
+ label="Butt Physics UpDown Gain"
+ wearable="physics"
+ edit_group="physics_butt_updown"
+ value_default="10"
+ value_min="1"
+ value_max="100">
+ <param_driver />
+ </param>
+ <param
+ id="10024"
+ group="0"
+ name="Butt_Physics_UpDown_Damping"
+ label="Butt Physics UpDown Damping"
+ wearable="physics"
+ edit_group="physics_butt_updown"
+ value_default=".2"
+ value_min="0"
+ value_max="1">
+ <param_driver />
+ </param>
+
+ <param
+ id="10025"
+ group="0"
+ name="Butt_Physics_LeftRight_Max_Effect"
+ label="Butt Physics LeftRight Max Effect"
+ wearable="physics"
+ edit_group="physics_butt_leftright"
+ value_default="0"
+ value_min="0"
+ value_max="3">
+ <param_driver />
+ </param>
+ <param
+ id="10026"
+ group="0"
+ name="Butt_Physics_LeftRight_Spring"
+ label="Butt Physics LeftRight Spring"
+ wearable="physics"
+ edit_group="physics_butt_leftright"
+ value_default="10"
+ value_min="0"
+ value_max="100">
+ <param_driver />
+ </param>
+ <param
+ id="10027"
+ group="0"
+ name="Butt_Physics_LeftRight_Gain"
+ label="Butt Physics LeftRight Gain"
+ wearable="physics"
+ edit_group="physics_butt_leftright"
+ value_default="10"
+ value_min="1"
+ value_max="100">
+ <param_driver />
+ </param>
+ <param
+ id="10028"
+ group="0"
+ name="Butt_Physics_LeftRight_Damping"
+ label="Butt Physics LeftRight Damping"
+ wearable="physics"
+ edit_group="physics_butt_leftright"
+ value_default=".2"
+ value_min="0"
+ value_max="1">
+ <param_driver />
+ </param>
+
+ <param
+ id="10029"
+ group="0"
+ sex="female"
+ name="Breast_Physics_LeftRight_Max_Effect"
+ label="Breast Physics LeftRight Max Effect"
+ wearable="physics"
+ edit_group="physics_breasts_leftright"
+ value_default="0"
+ value_min="0"
+ value_max="3">
+ <param_driver />
+ </param>
+ <param
+ id="10030"
+ group="0"
+ sex="female"
+ name="Breast_Physics_LeftRight_Spring"
+ label="Breast Physics LeftRight Spring"
+ wearable="physics"
+ edit_group="physics_breasts_leftright"
+ value_default="10"
+ value_min="0"
+ value_max="100">
+ <param_driver />
+ </param>
+ <param
+ id="10031"
+ group="0"
+ sex="female"
+ name="Breast_Physics_LeftRight_Gain"
+ label="Breast Physics LeftRight Gain"
+ wearable="physics"
+ edit_group="physics_breasts_leftright"
+ value_default="10"
+ value_min="1"
+ value_max="100">
+ <param_driver />
+ </param>
+ <param
+ id="10032"
+ group="0"
+ sex="female"
+ name="Breast_Physics_LeftRight_Damping"
+ label="Breast Physics LeftRight Damping"
+ wearable="physics"
+ edit_group="physics_breasts_leftright"
+ value_default=".2"
+ value_min="0"
+ value_max="1">
+ <param_driver />
+ </param>
+
+ <param
+ id="11000"
+ group="0"
+ name="AppearanceMessage_Version"
+ label="AppearanceMessage Version"
+ value_default="0"
+ value_min="0"
+ value_max="255">
+ <param_driver />
+ </param>
+
+ </driver_parameters>
+
+ <morph_masks>
+ <mask
+ morph_name="Displace_Hair_Facial"
+ body_region="head"
+ layer="facialhair" />
+ <mask
+ morph_name="Displace_Loose_Upperbody"
+ body_region="upper_body"
+ layer="upper_clothes" />
+ <mask
+ morph_name="Shirtsleeve_flair"
+ body_region="upper_body"
+ layer="upper_clothes" />
+ <mask
+ morph_name="Displace_Loose_Lowerbody"
+ body_region="lower_body"
+ layer="lower_pants" />
+ <mask
+ morph_name="Leg_Pantflair"
+ body_region="lower_body"
+ layer="lower_pants" />
+ <mask
+ morph_name="Low_Crotch"
+ body_region="lower_body"
+ layer="lower_pants" />
+ <mask
+ morph_name="Leg_Longcuffs"
+ body_region="lower_body"
+ layer="lower_pants" />
+ </morph_masks>
+</linden_avatar>
+
diff --git a/indra/newview/character/avatar_lad_tentacles.xml b/indra/newview/character/avatar_lad_tentacles.xml
new file mode 100644
index 0000000000..9ec6428ee6
--- /dev/null
+++ b/indra/newview/character/avatar_lad_tentacles.xml
@@ -0,0 +1,12505 @@
+<?xml version="1.0" encoding="US-ASCII" standalone="yes"?>
+<linden_avatar
+ version="1.0" wearable_definition_version="22">
+ <!-- The wearable_definition_version is checked during asset upload. -->
+ <!-- If you increment it, check indra/lib/python/indra/assetutil.py. -->
+ <skeleton
+ file_name="avatar_skeleton.xml">
+ <attachment_point
+ id="1"
+ group="6"
+ pie_slice="2"
+ name="Chest"
+ joint="mChest"
+ position="0.15 0 -0.1"
+ rotation="0 90 90"
+ visible_in_first_person="true" />
+
+ <attachment_point
+ id="2"
+ group="2"
+ pie_slice="2"
+ name="Skull"
+ joint="mHead"
+ position="0 0 0.15"
+ rotation="0 0 90"
+ visible_in_first_person="false" />
+
+ <attachment_point
+ id="3"
+ group="3"
+ pie_slice="3"
+ name="Left Shoulder"
+ joint="mCollarLeft"
+ position="0 0 0.08"
+ rotation="0 0 0"
+ visible_in_first_person="true" />
+
+ <attachment_point
+ id="4"
+ group="1"
+ pie_slice="1"
+ name="Right Shoulder"
+ joint="mCollarRight"
+ position="0 0 0.08"
+ rotation="0 0 0"
+ visible_in_first_person="true"/>
+
+ <attachment_point
+ id="5"
+ group="4"
+ name="Left Hand"
+ joint="mWristLeft"
+ position="0 0.08 -0.02"
+ rotation="0 0 0"
+ visible_in_first_person="true"
+ max_attachment_offset="1.5" />
+
+ <attachment_point
+ id="6"
+ group="0"
+ name="Right Hand"
+ joint="mWristRight"
+ position="0 -0.08 -0.02"
+ rotation="0 0 0"
+ visible_in_first_person="true"
+ max_attachment_offset="1.5" />
+
+ <attachment_point
+ id="7"
+ group="5"
+ pie_slice="6"
+ name="Left Foot"
+ joint="mFootLeft"
+ position="0 0.0 0.0"
+ rotation="0 0 0"
+ visible_in_first_person="true"/>
+
+ <attachment_point
+ id="8"
+ group="7"
+ pie_slice="6"
+ name="Right Foot"
+ joint="mFootRight"
+ position="0 0.0 0.0"
+ rotation="0 0 0"
+ visible_in_first_person="true"/>
+
+ <attachment_point
+ id="9"
+ group="6"
+ pie_slice="7"
+ name="Spine"
+ joint="mChest"
+ position="-0.15 0 -0.1"
+ rotation="0 -90 90"
+ visible_in_first_person="true" />
+
+ <attachment_point
+ id="10"
+ group="6"
+ pie_slice="6"
+ name="Pelvis"
+ joint="mPelvis"
+ position="0 0 -0.15"
+ rotation="0 0 0"
+ visible_in_first_person="true" />
+
+ <attachment_point
+ id="11"
+ group="2"
+ pie_slice="6"
+ name="Mouth"
+ joint="mHead"
+ position="0.12 0 0.001"
+ rotation="0 0 0"
+ visible_in_first_person="false"/>
+
+ <attachment_point
+ id="12"
+ group="2"
+ pie_slice="7"
+ name="Chin"
+ joint="mHead"
+ position="0.12 0 -0.04"
+ rotation="0 0 0"
+ visible_in_first_person="false" />
+
+ <attachment_point
+ id="13"
+ group="2"
+ pie_slice="4"
+ name="Left Ear"
+ joint="mHead"
+ position="0.015 0.08 0.017"
+ rotation="0 0 0"
+ visible_in_first_person="false" />
+
+ <attachment_point
+ id="14"
+ group="2"
+ pie_slice="0"
+ name="Right Ear"
+ joint="mHead"
+ position="0.015 -0.08 0.017"
+ rotation="0 0 0"
+ visible_in_first_person="false" />
+
+ <attachment_point
+ id="15"
+ group="2"
+ pie_slice="3"
+ name="Left Eyeball"
+ joint="mEyeLeft"
+ position="0 0 0"
+ rotation="0 0 0"
+ visible_in_first_person="false"/>
+
+ <attachment_point
+ id="16"
+ group="2"
+ pie_slice="1"
+ name="Right Eyeball"
+ joint="mEyeRight"
+ position="0 0 0"
+ rotation="0 0 0"
+ visible_in_first_person="false" />
+
+ <attachment_point
+ id="17"
+ group="2"
+ pie_slice="5"
+ name="Nose"
+ joint="mHead"
+ position="0.1 0 0.05"
+ rotation="0 0 0"
+ visible_in_first_person="false"/>
+
+ <attachment_point
+ id="18"
+ group="1"
+ pie_slice="0"
+ name="R Upper Arm"
+ joint="mShoulderRight"
+ position="0.01 -0.13 0.01"
+ rotation="0 0 0"
+ visible_in_first_person="true" />
+
+ <attachment_point
+ id="19"
+ group="1"
+ pie_slice="7"
+ name="R Forearm"
+ joint="mElbowRight"
+ position="0 -0.12 0"
+ rotation="0 0 0"
+ visible_in_first_person="true"/>
+
+ <attachment_point
+ id="20"
+ group="3"
+ pie_slice="4"
+ name="L Upper Arm"
+ joint="mShoulderLeft"
+ position="0.01 0.15 -0.01"
+ rotation="0 0 0"
+ visible_in_first_person="true" />
+
+ <attachment_point
+ id="21"
+ group="3"
+ pie_slice="5"
+ name="L Forearm"
+ joint="mElbowLeft"
+ position="0 0.113 0"
+ rotation="0 0 0"
+ visible_in_first_person="true" />
+
+ <attachment_point
+ id="22"
+ group="7"
+ pie_slice="1"
+ name="Right Hip"
+ joint="mHipRight"
+ position="0 0 0"
+ rotation="0 0 0"
+ visible_in_first_person="true" />
+
+ <attachment_point
+ id="23"
+ group="7"
+ pie_slice="0"
+ name="R Upper Leg"
+ joint="mHipRight"
+ position="-0.017 0.041 -0.310"
+ rotation="0 0 0"
+ visible_in_first_person="true" />
+
+ <attachment_point
+ id="24"
+ group="7"
+ pie_slice="7"
+ name="R Lower Leg"
+ joint="mKneeRight"
+ position="-0.044 -0.007 -0.262"
+ rotation="0 0 0"
+ visible_in_first_person="true" />
+
+ <attachment_point
+ id="25"
+ group="5"
+ pie_slice="3"
+ name="Left Hip"
+ joint="mHipLeft"
+ position="0 0 0"
+ rotation="0 0 0"
+ visible_in_first_person="true" />
+
+ <attachment_point
+ id="26"
+ group="5"
+ pie_slice="4"
+ name="L Upper Leg"
+ joint="mHipLeft"
+ position="-0.019 -0.034 -0.310"
+ rotation="0 0 0"
+ visible_in_first_person="true"/>
+
+ <attachment_point
+ id="27"
+ group="5"
+ pie_slice="5"
+ name="L Lower Leg"
+ joint="mKneeLeft"
+ position="-0.044 -0.007 -0.261"
+ rotation="0 0 0"
+ visible_in_first_person="true" />
+
+ <attachment_point
+ id="28"
+ group="6"
+ pie_slice="5"
+ name="Stomach"
+ joint="mPelvis"
+ position="0.092 0.0 0.088"
+ rotation="0 0 0"
+ visible_in_first_person="true" />
+
+ <attachment_point
+ id="29"
+ group="6"
+ pie_slice="3"
+ name="Left Pec"
+ joint="mTorso"
+ position="0.104 0.082 0.247"
+ rotation="0 0 0"
+ visible_in_first_person="true" />
+
+ <attachment_point
+ id="30"
+ group="6"
+ pie_slice="1"
+ name="Right Pec"
+ joint="mTorso"
+ position="0.104 -0.082 0.247"
+ rotation="0 0 0"
+ visible_in_first_person="true" />
+
+ <attachment_point
+ id="31"
+ group="8"
+ name="Center 2"
+ joint="mScreen"
+ position="0 0 0"
+ rotation="0 0 0"
+ hud="true"
+ max_attachment_offset="2.0"
+ visible_in_first_person="true" />
+
+ <attachment_point
+ id="32"
+ group="8"
+ name="Top Right"
+ joint="mScreen"
+ position="0 -0.5 0.5"
+ rotation="0 0 0"
+ hud="true"
+ max_attachment_offset="2.0"
+ visible_in_first_person="true" />
+
+ <attachment_point
+ id="33"
+ group="8"
+ name="Top"
+ joint="mScreen"
+ position="0 0 0.5"
+ rotation="0 0 0"
+ hud="true"
+ max_attachment_offset="2.0"
+ visible_in_first_person="true" />
+
+ <attachment_point
+ id="34"
+ group="8"
+ name="Top Left"
+ joint="mScreen"
+ position="0 0.5 0.5"
+ rotation="0 0 0"
+ hud="true"
+ max_attachment_offset="2.0"
+ visible_in_first_person="true" />
+
+ <attachment_point
+ id="35"
+ group="8"
+ name="Center"
+ joint="mScreen"
+ position="0 0 0"
+ rotation="0 0 0"
+ hud="true"
+ max_attachment_offset="2.0"
+ visible_in_first_person="true" />
+
+ <attachment_point
+ id="36"
+ group="8"
+ name="Bottom Left"
+ joint="mScreen"
+ position="0 0.5 -0.5"
+ rotation="0 0 0"
+ hud="true"
+ max_attachment_offset="2.0"
+ visible_in_first_person="true" />
+
+ <attachment_point
+ id="37"
+ group="8"
+ name="Bottom"
+ joint="mScreen"
+ position="0 0 -0.5"
+ rotation="0 0 0"
+ hud="true"
+ max_attachment_offset="2.0"
+ visible_in_first_person="true" />
+
+ <attachment_point
+ id="38"
+ group="8"
+ name="Bottom Right"
+ joint="mScreen"
+ position="0 -0.5 -0.5"
+ rotation="0 0 0"
+ hud="true"
+ max_attachment_offset="2.0"
+ visible_in_first_person="true" />
+
+ <attachment_point
+ id="39"
+ group="6"
+ pie_slice="1"
+ name="Neck"
+ joint="mNeck"
+ position="0 0 0"
+ rotation="0 0 0"
+ visible_in_first_person="true" />
+
+ <attachment_point
+ id="40"
+ group="6"
+ pie_slice="2"
+ name="Avatar Center"
+ joint="mRoot"
+ position="0 0 0"
+ rotation="0 0 0"
+ visible_in_first_person="true" />
+
+ <param
+ id="32"
+ group="1"
+ wearable="shape"
+ name="Male_Skeleton"
+ label_min="Female"
+ label_max="Male"
+ value_min="0"
+ value_max="1">
+ <param_skeleton>
+ <bone
+ name="mNeck"
+ scale="0 0 .2" />
+
+ <bone
+ name="mCollarLeft"
+ scale="0 .4 0" />
+
+ <bone
+ name="mCollarRight"
+ scale="0 .4 0" />
+
+ <bone
+ name="mShoulderLeft"
+ scale="0 .35 0" />
+
+ <bone
+ name="mShoulderRight"
+ scale="0 .35 0" />
+
+ <bone
+ name="mElbowLeft"
+ scale="0 .1 0" />
+
+ <bone
+ name="mElbowRight"
+ scale="0 .1 0" />
+
+ <bone
+ name="mChest"
+ scale=".05 .05 .05" />
+
+ <bone
+ name="mTorso"
+ scale="0 0 .05" />
+
+ <bone
+ name="mPelvis"
+ scale="0 0 0" />
+
+ <bone
+ name="mHipLeft"
+ scale=".05 .05 0" />
+
+ <bone
+ name="mHipRight"
+ scale=".05 .05 0" />
+
+ <bone
+ name="mKneeLeft"
+ scale=".05 .05 .1" />
+
+ <bone
+ name="mKneeRight"
+ scale=".05 .05 .1" />
+ </param_skeleton>
+ </param>
+
+ <param
+ id="33"
+ group="0"
+ name="Height"
+ label="Height"
+ wearable="shape"
+ edit_group="shape_body"
+ edit_group_order="1"
+ label_min="Short"
+ label_max="Tall"
+ show_simple="true"
+ value_min="-2.3"
+ value_max="2"
+ camera_distance="2.2">
+ <param_skeleton>
+ <bone
+ name="mNeck"
+ scale="0 0 .02" />
+
+ <bone
+ name="mCollarLeft"
+ scale="0 0 0" />
+
+ <bone
+ name="mCollarRight"
+ scale="0 0 0" />
+
+ <bone
+ name="mShoulderLeft"
+ scale="0 0.08 0" />
+
+ <bone
+ name="mShoulderRight"
+ scale="0 0.08 0" />
+
+ <bone
+ name="mElbowLeft"
+ scale="0 0.06 0" />
+
+ <bone
+ name="mElbowRight"
+ scale="0 0.06 0" />
+
+ <bone
+ name="mChest"
+ scale="0 0 0.05" />
+
+ <bone
+ name="mTorso"
+ scale="0 0 0.05" />
+
+ <bone
+ name="mPelvis"
+ scale="0 0 0" />
+
+ <bone
+ name="mHipLeft"
+ scale="0 0 0.1" />
+
+ <bone
+ name="mHipRight"
+ scale="0 0 0.1" />
+
+ <bone
+ name="mKneeLeft"
+ scale="0 0 0.1" />
+
+ <bone
+ name="mKneeRight"
+ scale="0 0 0.1" />
+ </param_skeleton>
+ </param>
+
+ <param
+ id="34"
+ group="0"
+ name="Thickness"
+ label="Body Thickness"
+ wearable="shape"
+ edit_group="shape_body"
+ edit_group_order="2"
+ label_min="Body Thin"
+ label_max="Body Thick"
+ show_simple="true"
+ value_min="-0.7"
+ value_max="1.5"
+ camera_distance="1.8">
+ <param_skeleton>
+ <bone
+ name="mNeck"
+ scale="0.1 0.1 0" />
+
+ <bone
+ name="mCollarLeft"
+ scale="0 0.2 0" />
+
+ <bone
+ name="mCollarRight"
+ scale="0 0.2 0" />
+
+ <bone
+ name="mShoulderLeft"
+ scale="0.1 0 0.1" />
+
+ <bone
+ name="mShoulderRight"
+ scale="0.1 0 0.1" />
+
+ <bone
+ name="mElbowLeft"
+ scale="0.1 0 0.1" />
+
+ <bone
+ name="mElbowRight"
+ scale="0.1 0 0.1" />
+
+ <bone
+ name="mChest"
+ scale="0.1 0.1 0" />
+
+ <bone
+ name="mTorso"
+ scale="0.1 0.1 0" />
+
+ <bone
+ name="mPelvis"
+ scale="0.1 0.1 0" />
+
+ <bone
+ name="mHipLeft"
+ scale="0.13 0.13 0" />
+
+ <bone
+ name="mHipRight"
+ scale="0.13 0.13 0" />
+
+ <bone
+ name="mKneeLeft"
+ scale="0.12 0.12 0" />
+
+ <bone
+ name="mKneeRight"
+ scale="0.12 0.12 0" />
+ </param_skeleton>
+ </param>
+
+ <param
+ id="36"
+ group="0"
+ name="Shoulders"
+ label="Shoulders"
+ wearable="shape"
+ edit_group="shape_torso"
+ edit_group_order="4"
+ label_min="Narrow"
+ label_max="Broad"
+ show_simple="true"
+ value_min="-1.8"
+ value_max="1.4"
+ value_default="-0.5"
+ camera_elevation=".1"
+ camera_distance="1.2"
+ camera_angle="0">
+ <param_skeleton>
+ <bone
+ name="mNeck"
+ scale="0.01 0.03 0" />
+
+ <bone
+ name="mCollarLeft"
+ scale="0 0 0"
+ offset="0 .02 0" />
+
+ <bone
+ name="mCollarRight"
+ scale="0 0 0"
+ offset="0 -.02 0" />
+
+ <bone
+ name="mChest"
+ scale="0.02 0.08 0" />
+ </param_skeleton>
+ </param>
+
+ <param
+ id="37"
+ group="0"
+ name="Hip Width"
+ label="Hip Width"
+ wearable="shape"
+ edit_group="shape_legs"
+ edit_group_order="3"
+ label_min="Narrow"
+ label_max="Wide"
+ show_simple="true"
+ value_min="-3.2"
+ value_max="2.8"
+ camera_distance="1.8">
+ <param_skeleton>
+ <bone
+ name="mPelvis"
+ scale="0 0.1 0" />
+
+ <bone
+ name="mHipLeft"
+ scale="0 0 0"
+ offset="0 .004 0" />
+
+ <bone
+ name="mHipRight"
+ scale="0 0 0"
+ offset="0 -.004 0" />
+ </param_skeleton>
+ </param>
+
+ <param
+ id="842"
+ group="0"
+ name="Hip Length"
+ wearable="shape"
+ edit_group="shape_legs"
+ edit_group_order="3.2"
+ label_min="Short hips"
+ label_max="Long Hips"
+ value_min="-1"
+ value_max="1"
+ camera_distance="1.8">
+ <param_skeleton>
+ <bone
+ name="mPelvis"
+ scale="0 0 0.3" />
+ </param_skeleton>
+ </param>
+
+ <param
+ id="38"
+ group="0"
+ name="Torso Length"
+ wearable="shape"
+ edit_group="shape_torso"
+ edit_group_order="11"
+ label_min="Short Torso"
+ label_max="Long Torso"
+ value_min="-1"
+ value_max="1"
+ camera_distance="1.8">
+ <param_skeleton>
+ <bone
+ name="mTorso"
+ scale="0 0 .3" />
+
+ <bone
+ name="mPelvis"
+ scale="0 0 .1" />
+
+ <bone
+ name="mHipLeft"
+ scale="0 0 -.1" />
+
+ <bone
+ name="mHipRight"
+ scale="0 0 -.1" />
+
+ <bone
+ name="mKneeRight"
+ scale="0 0 -.05" />
+
+ <bone
+ name="mKneeLeft"
+ scale="0 0 -.05" />
+ </param_skeleton>
+ </param>
+
+ <param
+ id="195"
+ group="1"
+ name="EyeBone_Spread"
+ wearable="shape"
+ edit_group="shape_eyes"
+ label_min="Eyes Together"
+ label_max="Eyes Spread"
+ value_min="-1"
+ value_max="1">
+ <param_skeleton>
+ <bone
+ name="mEyeLeft"
+ scale="0 0 0"
+ offset="0 .009 0" />
+
+ <bone
+ name="mEyeRight"
+ scale="0 0 0"
+ offset="0 -.009 0" />
+ </param_skeleton>
+ </param>
+
+ <param
+ id="661"
+ group="1"
+ name="EyeBone_Head_Shear"
+ wearable="shape"
+ edit_group="shape_eyes"
+ label_min="Eyes Shear Left Up"
+ label_max="Eyes Shear Right Up"
+ value_min="-2"
+ value_max="2">
+ <param_skeleton>
+ <bone
+ name="mEyeLeft"
+ scale="0 0 0"
+ offset="0 0 .004" />
+
+ <bone
+ name="mEyeRight"
+ scale="0 0 0"
+ offset="0 0 -.004" />
+ </param_skeleton>
+ </param>
+
+ <param
+ id="772"
+ group="1"
+ name="EyeBone_Head_Elongate"
+ wearable="shape"
+ edit_group="shape_eyes"
+ label_min="Eyes Short Head"
+ label_max="Eyes Long Head"
+ value_min="-1"
+ value_max="1">
+ <param_skeleton>
+ <bone
+ name="mEyeLeft"
+ scale="0 0 0"
+ offset=".016 0 0" />
+
+ <bone
+ name="mEyeRight"
+ scale="0 0 0"
+ offset=".016 0 0" />
+ </param_skeleton>
+ </param>
+
+ <param
+ id="768"
+ group="1"
+ name="EyeBone_Bug"
+ wearable="shape"
+ edit_group="shape_eyes"
+ label_min="Eyes Sunken"
+ label_max="Eyes Bugged"
+ value_min="-2"
+ value_max="2">
+ <param_skeleton>
+ <bone
+ name="mEyeLeft"
+ scale="0 0 0"
+ offset=".005 0 0" />
+
+ <bone
+ name="mEyeRight"
+ scale="0 0 0"
+ offset=".005 0 0" />
+ </param_skeleton>
+ </param>
+
+ <param
+ id="655"
+ group="1"
+ name="Head Size"
+ label="Head Size"
+ wearable="shape"
+ edit_group="shape_head"
+ label_min="Small Head"
+ label_max="Big Head"
+ show_simple="true"
+ value_min="-.25"
+ value_max=".10">
+ <param_skeleton>
+ <bone
+ name="mSkull"
+ scale="1 1 1"
+ offset="0 0 0.1" />
+
+ <bone
+ name="mHead"
+ scale="1 1 1"
+ offset="0 0 0" />
+
+ <bone
+ name="mEyeLeft"
+ scale="1 1 1"
+ offset="0 0 0" />
+
+ <bone
+ name="mEyeRight"
+ scale="1 1 1"
+ offset="0 0 0" />
+ </param_skeleton>
+ </param>
+
+ <param
+ id="197"
+ group="1"
+ wearable="shoes"
+ name="Shoe_Heels"
+ edit_group="shoes"
+ label_min="No Heels"
+ label_max="High Heels"
+ value_min="0"
+ value_max="1">
+ <param_skeleton>
+ <bone
+ name="mFootRight"
+ scale="0 0 0"
+ offset="0 0 -.08" />
+
+ <bone
+ name="mFootLeft"
+ scale="0 0 0"
+ offset="0 0 -.08" />
+ </param_skeleton>
+ </param>
+
+ <param
+ id="502"
+ group="1"
+ wearable="shoes"
+ name="Shoe_Platform"
+ edit_group="shoes"
+ label_min="No Heels"
+ label_max="High Heels"
+ value_min="0"
+ value_max="1">
+ <param_skeleton>
+ <bone
+ name="mFootRight"
+ scale="0 0 0"
+ offset="0 0 -.07" />
+
+ <bone
+ name="mFootLeft"
+ scale="0 0 0"
+ offset="0 0 -.07" />
+ </param_skeleton>
+ </param>
+
+ <param
+ id="675"
+ group="0"
+ name="Hand Size"
+ wearable="shape"
+ edit_group="shape_torso"
+ edit_group_order="10"
+ label_min="Small Hands"
+ label_max="Large Hands"
+ value_min="-.3"
+ value_max=".3"
+ camera_elevation=".1"
+ camera_distance="1.4"
+ camera_angle="0">
+ <param_skeleton>
+ <bone
+ name="mWristRight"
+ scale="1 1 1"
+ offset="0 0 0" />
+
+ <bone
+ name="mWristLeft"
+ scale="1 1 1"
+ offset="0 0 0" />
+ </param_skeleton>
+ </param>
+
+ <param
+ id="683"
+ group="0"
+ name="Neck Thickness"
+ wearable="shape"
+ edit_group="shape_torso"
+ edit_group_order="2"
+ label_min="Skinny Neck"
+ label_max="Thick Neck"
+ value_min="-.4"
+ value_max=".2"
+ value_default="-.15"
+ camera_elevation=".3"
+ camera_distance=".8"
+ camera_angle="15">
+ <param_skeleton>
+ <bone
+ name="mNeck"
+ scale="1 1 0"
+ offset="0 0 0" />
+ </param_skeleton>
+ </param>
+
+ <param
+ id="689"
+ group="1"
+ wearable="shape"
+ name="EyeBone_Big_Eyes"
+ edit_group="shape_eyes"
+ label_min="Eyes Back"
+ label_max="Eyes Forward"
+ value_min="-1"
+ value_max="1">
+ <param_skeleton>
+ <bone
+ name="mEyeLeft"
+ scale="0 0 0"
+ offset="-.005 0 0" />
+
+ <bone
+ name="mEyeRight"
+ scale="0 0 0"
+ offset="-.005 0 0" />
+ </param_skeleton>
+ </param>
+
+ <param
+ id="692"
+ group="0"
+ name="Leg Length"
+ wearable="shape"
+ edit_group="shape_legs"
+ edit_group_order="2"
+ label_min="Short Legs"
+ label_max="Long Legs"
+ value_min="-1"
+ value_max="1"
+ camera_distance="2.5">
+ <param_skeleton>
+ <bone
+ name="mHipLeft"
+ scale="0 0 .2" />
+
+ <bone
+ name="mHipRight"
+ scale="0 0 .2" />
+
+ <bone
+ name="mKneeRight"
+ scale="0 0 .2" />
+
+ <bone
+ name="mKneeLeft"
+ scale="0 0 .2" />
+ </param_skeleton>
+ </param>
+
+ <param
+ id="693"
+ group="0"
+ name="Arm Length"
+ wearable="shape"
+ edit_group="shape_torso"
+ edit_group_order="9"
+ label_min="Short Arms"
+ label_max="Long arms"
+ value_min="-1"
+ value_max="1"
+ value_default=".6"
+ camera_distance="1.5">
+ <param_skeleton>
+ <bone
+ name="mShoulderLeft"
+ scale="0 .2 0" />
+
+ <bone
+ name="mShoulderRight"
+ scale="0 .2 0" />
+
+ <bone
+ name="mElbowRight"
+ scale="0 .3 0" />
+
+ <bone
+ name="mElbowLeft"
+ scale="0 .3 0" />
+ </param_skeleton>
+ </param>
+
+ <param
+ id="756"
+ group="0"
+ name="Neck Length"
+ wearable="shape"
+ edit_group="shape_torso"
+ edit_group_order="3"
+ label_min="Short Neck"
+ label_max="Long Neck"
+ value_min="-1"
+ value_max="1"
+ value_default="0"
+ camera_elevation=".3"
+ camera_distance=".8"
+ camera_angle="15">
+ <param_skeleton>
+ <bone
+ name="mNeck"
+ scale="0 0 .5" />
+ </param_skeleton>
+ </param>
+ <param
+ id="11001"
+ group="0"
+ name="Hover"
+ wearable="shape"
+ edit_group="shape_body"
+ edit_group_order="4"
+ label_min="Lower"
+ label_max="Higher"
+ value_min="-2"
+ value_max="2"
+ value_default="0"
+ camera_distance="2.5">
+ <param_skeleton />
+ </param>
+
+ </skeleton>
+
+ <mesh
+ type="hairMesh"
+ lod="0"
+ file_name="avatar_hair.llm"
+ min_pixel_width="320">
+ <!-- begin morph targets -->
+ <param
+ id="180"
+ group="1"
+ name="Hair_Volume"
+ label="Hair Volume"
+ show_simple="true"
+ wearable="hair"
+ clothing_morph="true"
+ edit_group="hair_style"
+ label_min="Less"
+ label_max="More"
+ value_min="0"
+ value_max="1.3"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="20">
+ <param_morph />
+ </param>
+
+ <param
+ id="761"
+ group="1"
+ name="Hair_Volume_Small"
+ label="Hair Volume"
+ show_simple="true"
+ wearable="hair"
+ edit_group="hair_style"
+ label_min="Less"
+ label_max="More"
+ value_min="0"
+ value_max="1.3"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="20">
+ <param_morph />
+ </param>
+
+ <param
+ id="181"
+ group="0"
+ name="Hair_Big_Front"
+ label="Big Hair Front"
+ wearable="hair"
+ edit_group="hair_style"
+ edit_group_order="5"
+ label_min="Less"
+ label_max="More"
+ value_min="-1"
+ value_max="1"
+ value_default="0.14"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="90">
+ <param_morph />
+ </param>
+
+ <param
+ id="182"
+ group="0"
+ name="Hair_Big_Top"
+ label="Big Hair Top"
+ wearable="hair"
+ edit_group="hair_style"
+ edit_group_order="6"
+ label_min="Less"
+ label_max="More"
+ value_min="-1"
+ value_max="1"
+ value_default=".7"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="90">
+ <param_morph />
+ </param>
+
+ <param
+ id="183"
+ group="0"
+ name="Hair_Big_Back"
+ clothing_morph="true"
+ label="Big Hair Back"
+ wearable="hair"
+ edit_group="hair_style"
+ edit_group_order="7"
+ label_min="Less"
+ label_max="More"
+ value_min="-1"
+ value_max="1"
+ value_default="0.05"
+ camera_elevation=".1"
+ camera_distance=".7"
+ camera_angle="90">
+ <param_morph />
+ </param>
+
+ <param
+ id="184"
+ group="0"
+ name="Hair_Spiked"
+ label="Spiked Hair"
+ show_simple="true"
+ wearable="hair"
+ clothing_morph="true"
+ edit_group="hair_style"
+ edit_group_order="15"
+ label_min="No Spikes"
+ label_max="Big Spikes"
+ value_min="0"
+ value_max="1"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="20">
+ <param_morph />
+ </param>
+
+ <param
+ id="140"
+ group="0"
+ name="Hair_Part_Middle"
+ label="Middle Part"
+ wearable="hair"
+ edit_group="hair_style"
+ edit_group_order="17"
+ label_min="No Part"
+ label_max="Part"
+ value_min="0"
+ value_max="2"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="0">
+ <param_morph />
+ </param>
+
+ <param
+ id="141"
+ group="0"
+ name="Hair_Part_Right"
+ label="Right Part"
+ wearable="hair"
+ edit_group="hair_style"
+ edit_group_order="18"
+ label_min="No Part"
+ label_max="Part"
+ value_min="0"
+ value_max="2"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="0">
+ <param_morph />
+ </param>
+
+ <param
+ id="142"
+ group="0"
+ name="Hair_Part_Left"
+ label="Left Part"
+ wearable="hair"
+ edit_group="hair_style"
+ edit_group_order="19"
+ label_min="No Part"
+ label_max="Part"
+ value_min="0"
+ value_max="2"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="0">
+ <param_morph />
+ </param>
+
+ <param
+ id="143"
+ group="0"
+ name="Hair_Sides_Full"
+ label="Full Hair Sides"
+ show_simple="true"
+ wearable="hair"
+ edit_group="hair_style"
+ edit_group_order="11"
+ label_min="Mowhawk"
+ label_max="Full Sides"
+ value_min="-4"
+ value_max="1.5"
+ value_default="0.125"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="20">
+ <param_morph />
+ </param>
+
+ <param
+ id="144"
+ group="1"
+ name="Bangs_Front_Up"
+ label="Front Bangs Up"
+ wearable="hair"
+ edit_group="hair_style"
+ label_min="Bangs"
+ label_max="Bangs Up"
+ value_min="0"
+ value_max="1"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="20">
+ <param_morph />
+ </param>
+
+ <param
+ id="145"
+ group="1"
+ clothing_morph="true"
+ name="Bangs_Front_Down"
+ label="Front Bangs Down"
+ wearable="hair"
+ edit_group="hair_style"
+ label_min="Bangs"
+ label_max="Bangs Down"
+ value_min="0"
+ value_max="5"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="20">
+ <param_morph />
+ </param>
+
+ <param
+ id="146"
+ group="1"
+ name="Bangs_Sides_Up"
+ label="Side Bangs Up"
+ wearable="hair"
+ edit_group="hair_style"
+ label_min="Side Bangs"
+ label_max="Side Bangs Up"
+ value_min="0"
+ value_max="1"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="20">
+ <param_morph />
+ </param>
+
+ <param
+ id="147"
+ group="1"
+ clothing_morph="true"
+ name="Bangs_Sides_Down"
+ label="Side Bangs Down"
+ wearable="hair"
+ edit_group="hair_style"
+ label_min="Side Bangs"
+ label_max="Side Bangs Down"
+ value_min="0"
+ value_max="2"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="20">
+ <param_morph />
+ </param>
+
+ <param
+ id="148"
+ group="1"
+ name="Bangs_Back_Up"
+ label="Back Bangs Up"
+ wearable="hair"
+ edit_group="hair_style"
+ label_min="Back Bangs"
+ label_max="Back Bangs Up"
+ value_min="0"
+ value_max="1"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="150">
+ <param_morph />
+ </param>
+
+ <param
+ id="149"
+ group="1"
+ name="Bangs_Back_Down"
+ label="Back Bangs Down"
+ clothing_morph="true"
+ wearable="hair"
+ edit_group="hair_style"
+ label_min="Back Bangs"
+ label_max="Back Bangs Down"
+ value_min="0"
+ value_max="2"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="150">
+ <param_morph />
+ </param>
+
+ <param
+ id="171"
+ group="1"
+ name="Hair_Front_Down"
+ label="Front Hair Down"
+ wearable="hair"
+ edit_group="hair_style"
+ label_min="Front Hair"
+ label_max="Front Hair Down"
+ value_min="0"
+ value_max="1"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="20">
+ <param_morph />
+ </param>
+
+ <param
+ id="172"
+ group="1"
+ name="Hair_Front_Up"
+ label="Front Hair Up"
+ wearable="hair"
+ edit_group="hair_style"
+ label_min="Front Hair"
+ label_max="Front Hair Up"
+ value_min="0"
+ value_max="1"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="20">
+ <param_morph />
+ </param>
+
+ <param
+ id="173"
+ group="1"
+ name="Hair_Sides_Down"
+ label="Sides Hair Down"
+ wearable="hair"
+ edit_group="hair_style"
+ label_min="Sides Hair"
+ label_max="Sides Hair Down"
+ value_min="0"
+ value_max="1"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="20">
+ <param_morph />
+ </param>
+
+ <param
+ id="174"
+ group="1"
+ name="Hair_Sides_Up"
+ label="Sides Hair Up"
+ wearable="hair"
+ edit_group="hair_style"
+ label_min="Sides Hair"
+ label_max="Sides Hair Up"
+ value_min="0"
+ value_max="1"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="20">
+ <param_morph />
+ </param>
+
+ <param
+ id="175"
+ group="1"
+ name="Hair_Back_Down"
+ label="Back Hair Down"
+ clothing_morph="true"
+ wearable="hair"
+ edit_group="hair_style"
+ label_min="Back Hair"
+ label_max="Back Hair Down"
+ value_min="0"
+ value_max="3"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="150">
+ <param_morph />
+ </param>
+
+ <param
+ id="176"
+ group="1"
+ name="Hair_Back_Up"
+ label="Back Hair Up"
+ wearable="hair"
+ edit_group="hair_style"
+ label_min="Back Hair"
+ label_max="Back Hair Up"
+ value_min="0"
+ value_max="1"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="150">
+ <param_morph />
+ </param>
+
+ <param
+ id="177"
+ group="0"
+ name="Hair_Rumpled"
+ label="Rumpled Hair"
+ show_simple="true"
+ wearable="hair"
+ clothing_morph="true"
+ edit_group="hair_style"
+ edit_group_order="14.5"
+ label_min="Smooth Hair"
+ label_max="Rumpled Hair"
+ value_min="0"
+ value_max="1"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="20">
+ <param_morph />
+ </param>
+
+ <param
+ id="178"
+ group="1"
+ name="Hair_Swept_Back"
+ label="Swept Back Hair"
+ wearable="hair"
+ edit_group="hair_style"
+ label_min="NotHair"
+ label_max="Swept Back"
+ value_min="0"
+ value_max="1"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="90">
+ <param_morph />
+ </param>
+
+ <param
+ id="179"
+ group="1"
+ name="Hair_Swept_Forward"
+ label="Swept Forward Hair"
+ wearable="hair"
+ edit_group="hair_style"
+ label_min="Hair"
+ label_max="Swept Forward"
+ value_min="0"
+ value_max="1"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="90">
+ <param_morph />
+ </param>
+
+ <param
+ id="190"
+ group="1"
+ name="Hair_Tilt_Right"
+ label="Hair Tilted Right"
+ wearable="hair"
+ edit_group="hair_style"
+ label_min="Hair"
+ label_max="Tilt Right"
+ value_min="0"
+ value_max="1"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="0">
+ <param_morph />
+ </param>
+
+ <param
+ id="191"
+ group="1"
+ name="Hair_Tilt_Left"
+ label="Hair Tilted Left"
+ wearable="hair"
+ edit_group="hair_style"
+ label_min="Hair"
+ label_max="Tilt Left"
+ value_min="0"
+ value_max="1"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="0">
+ <param_morph />
+ </param>
+
+ <param
+ id="192"
+ group="0"
+ name="Bangs_Part_Middle"
+ label="Part Bangs"
+ wearable="hair"
+ edit_group="hair_style"
+ edit_group_order="20"
+ label_min="No Part"
+ label_max="Part Bangs"
+ value_min="0"
+ value_max="1"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="0">
+ <param_morph />
+ </param>
+
+ <param
+ id="640"
+ group="1"
+ name="Hair_Egg_Head"
+ wearable="hair"
+ edit_group="hair_style"
+ cross_wearable="true"
+ value_min="-1.3"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="641"
+ group="1"
+ name="Hair_Squash_Stretch_Head"
+ wearable="hair"
+ edit_group="hair_style"
+ cross_wearable="true"
+ value_min="-.5"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="642"
+ group="1"
+ name="Hair_Square_Head"
+ wearable="hair"
+ edit_group="hair_style"
+ cross_wearable="true"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="643"
+ group="1"
+ name="Hair_Round_Head"
+ wearable="hair"
+ edit_group="hair_style"
+ cross_wearable="true"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="644"
+ group="1"
+ name="Hair_Forehead_Round"
+ wearable="hair"
+ edit_group="hair_style"
+ cross_wearable="true"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="645"
+ group="1"
+ name="Hair_Forehead_Slant"
+ wearable="hair"
+ edit_group="hair_style"
+ cross_wearable="true"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="774"
+ group="1"
+ name="Shear_Head_Hair"
+ wearable="hair"
+ edit_group="hair_style"
+ cross_wearable="true"
+ value_min="-2"
+ value_max="2">
+ <param_morph />
+ </param>
+
+ <param
+ id="771"
+ group="1"
+ name="Elongate_Head_Hair"
+ wearable="hair"
+ edit_group="hair_style"
+ cross_wearable="true"
+ value_min="-1"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="674"
+ group="0"
+ name="Hair_Shear_Back"
+ wearable="hair"
+ edit_group="hair_style"
+ edit_group_order="12"
+ label="Shear Back"
+ label_min="Full Back"
+ label_max="Sheared Back"
+ value_min="-1"
+ value_max="2"
+ value_default="-0.3"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="100">
+ <param_morph />
+ </param>
+
+ <param
+ id="762"
+ group="0"
+ name="Hair_Shear_Front"
+ wearable="hair"
+ edit_group="hair_style"
+ edit_group_order="11.8"
+ label="Shear Front"
+ show_simple="true"
+ label_min="Full Front"
+ label_max="Sheared Front"
+ value_min="0"
+ value_max="3"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="30">
+ <param_morph />
+ </param>
+
+ <param
+ id="754"
+ group="0"
+ name="Hair_Taper_Back"
+ wearable="hair"
+ edit_group="hair_style"
+ edit_group_order="14"
+ label="Taper Back"
+ label_min="Wide Back"
+ label_max="Narrow Back"
+ value_min="-1"
+ value_max="2"
+ value_default="0"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="160">
+ <param_morph />
+ </param>
+
+ <param
+ id="755"
+ group="0"
+ name="Hair_Taper_Front"
+ wearable="hair"
+ edit_group="hair_style"
+ edit_group_order="13"
+ label="Taper Front"
+ label_min="Wide Front"
+ label_max="Narrow Front"
+ value_min="-1.5"
+ value_max="1.5"
+ value_default="0.05"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="20">
+ <param_morph />
+ </param>
+
+ <param
+ id="782"
+ group="1"
+ clothing_morph="true"
+ name="Hair_Pigtails_Short"
+ wearable="hair"
+ edit_group="hair_style"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="783"
+ group="1"
+ clothing_morph="true"
+ name="Hair_Pigtails_Med"
+ wearable="hair"
+ edit_group="hair_style"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="790"
+ group="1"
+ clothing_morph="true"
+ name="Hair_Pigtails_Medlong"
+ wearable="hair"
+ edit_group="hair_style"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="784"
+ group="1"
+ clothing_morph="true"
+ name="Hair_Pigtails_Long"
+ wearable="hair"
+ edit_group="hair_style"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="786"
+ group="1"
+ name="Hair_Ponytail_Short"
+ wearable="hair"
+ edit_group="hair_style"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="787"
+ group="1"
+ name="Hair_Ponytail_Med"
+ wearable="hair"
+ edit_group="hair_style"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="788"
+ group="1"
+ name="Hair_Ponytail_Long"
+ clothing_morph="true"
+ wearable="hair"
+ edit_group="hair_style"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <!-- #end morph targets -->
+ </mesh>
+
+ <mesh
+ type="hairMesh"
+ lod="1"
+ file_name="avatar_hair_1.llm"
+ min_pixel_width="160"
+ reference="avatar_hair.llm">
+ </mesh>
+
+ <mesh
+ type="hairMesh"
+ lod="2"
+ file_name="avatar_hair_2.llm"
+ min_pixel_width="80"
+ reference="avatar_hair.llm">
+ </mesh>
+
+ <mesh
+ type="hairMesh"
+ lod="3"
+ file_name="avatar_hair_3.llm"
+ min_pixel_width="40"
+ reference="avatar_hair.llm">
+ </mesh>
+
+ <mesh
+ type="hairMesh"
+ lod="4"
+ file_name="avatar_hair_4.llm"
+ min_pixel_width="20"
+ reference="avatar_hair.llm">
+ </mesh>
+
+ <mesh
+ type="hairMesh"
+ lod="5"
+ file_name="avatar_hair_5.llm"
+ min_pixel_width="0"
+ reference="avatar_hair.llm">
+ </mesh>
+
+ <mesh
+ type="headMesh"
+ lod="0"
+ file_name="avatar_head.llm"
+ min_pixel_width="320">
+ <!--
+ begin morph targets
+ #############
+ tweakable morphs
+ #############
+ -->
+ <param
+ id="1"
+ group="0"
+ name="Big_Brow"
+ label="Brow Size"
+ wearable="shape"
+ edit_group="shape_head"
+ edit_group_order="7"
+ label_min="Small"
+ label_max="Large"
+ value_min="-.3"
+ value_max="2"
+ camera_elevation=".1"
+ camera_distance=".4"
+ camera_angle="45">
+ <param_morph />
+ </param>
+
+ <param
+ id="2"
+ group="0"
+ name="Nose_Big_Out"
+ label="Nose Size"
+ wearable="shape"
+ edit_group="shape_nose"
+ edit_group_order="1"
+ label_min="Small"
+ label_max="Large"
+ show_simple="true"
+ value_min="-0.8"
+ value_max="2.5"
+ camera_elevation=".1"
+ camera_distance=".35"
+ camera_angle="50">
+ <param_morph />
+ </param>
+
+ <param
+ id="4"
+ group="0"
+ name="Broad_Nostrils"
+ label="Nostril Width"
+ wearable="shape"
+ edit_group="shape_nose"
+ edit_group_order="3"
+ label_min="Narrow"
+ label_max="Broad"
+ value_min="-.5"
+ value_max="1"
+ camera_elevation=".1"
+ camera_distance=".3"
+ camera_angle="-20">
+ <param_morph />
+ </param>
+
+ <param
+ id="759"
+ group="0"
+ name="Low_Septum_Nose"
+ label="Nostril Division"
+ wearable="shape"
+ edit_group="shape_nose"
+ edit_group_order="3.5"
+ label_min="High"
+ label_max="Low"
+ value_min="-1"
+ value_max="1.5"
+ value_default="0.5"
+ camera_elevation=".1"
+ camera_distance=".3"
+ camera_angle="-20">
+ <param_morph />
+ </param>
+
+ <param
+ id="517"
+ group="0"
+ name="Wide_Nose"
+ label="Nose Width"
+ wearable="shape"
+ edit_group="shape_nose"
+ edit_group_order="2"
+ label_min="Narrow"
+ label_max="Wide"
+ show_simple="true"
+ value_min="-.5"
+ value_max="1"
+ camera_elevation=".1"
+ camera_distance=".3"
+ camera_angle="-20">
+ <param_morph />
+ </param>
+
+ <param
+ id="5"
+ group="0"
+ name="Cleft_Chin"
+ label="Chin Cleft"
+ wearable="shape"
+ edit_group="shape_chin"
+ edit_group_order="6"
+ label_min="Round"
+ label_max="Cleft"
+ value_min="-.1"
+ value_max="1"
+ camera_elevation="0"
+ camera_distance=".28"
+ camera_angle="-20">
+ <param_morph />
+ </param>
+
+ <param
+ id="6"
+ group="0"
+ name="Bulbous_Nose_Tip"
+ label="Nose Tip Shape"
+ wearable="shape"
+ edit_group="shape_nose"
+ edit_group_order="8"
+ label_min="Pointy"
+ label_max="Bulbous"
+ value_min="-.3"
+ value_max="1"
+ camera_elevation=".1"
+ camera_distance=".35"
+ camera_angle="15">
+ <param_morph />
+ </param>
+
+ <param
+ id="7"
+ group="0"
+ name="Weak_Chin"
+ label="Chin Angle"
+ wearable="shape"
+ edit_group="shape_chin"
+ edit_group_order="1"
+ label_min="Chin Out"
+ label_max="Chin In"
+ value_min="-.5"
+ value_max=".5"
+ camera_elevation=".1"
+ camera_distance=".4"
+ camera_angle="45">
+ <param_morph />
+ </param>
+
+ <param
+ id="8"
+ group="0"
+ name="Double_Chin"
+ label="Chin-Neck"
+ wearable="shape"
+ edit_group="shape_chin"
+ edit_group_order="8"
+ label_min="Tight Chin"
+ label_max="Double Chin"
+ value_min="-.5"
+ value_max="1.5"
+ camera_elevation="-.1"
+ camera_distance=".3"
+ camera_angle="60">
+ <param_morph />
+ </param>
+
+ <param
+ id="10"
+ group="0"
+ name="Sunken_Cheeks"
+ label="Lower Cheeks"
+ wearable="shape"
+ edit_group="shape_head"
+ edit_group_order="9"
+ label_min="Well-Fed"
+ label_max="Sunken"
+ show_simple="true"
+ value_min="-1.5"
+ value_max="3"
+ camera_elevation=".1"
+ camera_distance=".4"
+ camera_angle="5">
+ <param_morph />
+ </param>
+
+ <param
+ id="11"
+ group="0"
+ name="Noble_Nose_Bridge"
+ label="Upper Bridge"
+ wearable="shape"
+ edit_group="shape_nose"
+ edit_group_order="5"
+ label_min="Low"
+ label_max="High"
+ value_min="-.5"
+ value_max="1.5"
+ camera_elevation=".1"
+ camera_distance=".35"
+ camera_angle="70">
+ <param_morph />
+ </param>
+
+ <param
+ id="758"
+ group="0"
+ name="Lower_Bridge_Nose"
+ label="Lower Bridge"
+ wearable="shape"
+ edit_group="shape_nose"
+ edit_group_order="5.5"
+ label_min="Low"
+ label_max="High"
+ value_min="-1.5"
+ value_max="1.5"
+ camera_elevation=".1"
+ camera_distance=".35"
+ camera_angle="70">
+ <param_morph />
+ </param>
+
+ <param
+ id="12"
+ group="0"
+ name="Jowls"
+ wearable="shape"
+ edit_group="shape_chin"
+ edit_group_order="5"
+ label_min="Less"
+ label_max="More"
+ value_min="-.5"
+ value_max="2.5"
+ camera_elevation=".1"
+ camera_distance=".4"
+ camera_angle="0">
+ <param_morph />
+ </param>
+
+ <param
+ id="13"
+ group="0"
+ name="Cleft_Chin_Upper"
+ label="Upper Chin Cleft"
+ wearable="shape"
+ edit_group="shape_chin"
+ edit_group_order="7"
+ label_min="Round"
+ label_max="Cleft"
+ value_min="0"
+ value_max="1.5"
+ camera_elevation="0"
+ camera_distance=".28"
+ camera_angle="-20">
+ <param_morph />
+ </param>
+
+ <param
+ id="14"
+ group="0"
+ name="High_Cheek_Bones"
+ label="Cheek Bones"
+ wearable="shape"
+ edit_group="shape_head"
+ edit_group_order="10"
+ label_min="Low"
+ label_max="High"
+ value_min="-.5"
+ value_max="1"
+ camera_elevation=".1"
+ camera_distance=".3"
+ camera_angle="-20">
+ <param_morph />
+ </param>
+
+ <param
+ id="15"
+ group="0"
+ name="Ears_Out"
+ label="Ear Angle"
+ wearable="shape"
+ edit_group="shape_ears"
+ edit_group_order="2"
+ label_min="In"
+ label_max="Out"
+ value_min="-.5"
+ value_max="1.5"
+ camera_elevation=".1"
+ camera_distance=".3"
+ camera_angle="-20">
+ <param_morph />
+ </param>
+
+ <!--Pointy eyebrows became a driver/driven param with new max value for backwards compatibility between 1.0 and 1.1-->
+ <param
+ id="870"
+ group="1"
+ name="Pointy_Eyebrows"
+ label="Eyebrow Points"
+ wearable="hair"
+ edit_group="hair_eyebrows"
+ edit_group_order="4"
+ label_min="Smooth"
+ label_max="Pointy"
+ value_min="-.5"
+ value_max="1"
+ camera_elevation=".1"
+ camera_distance=".3">
+ <param_morph />
+ </param>
+
+ <param
+ id="17"
+ group="0"
+ name="Square_Jaw"
+ label="Jaw Shape"
+ wearable="shape"
+ edit_group="shape_chin"
+ edit_group_order="2"
+ label_min="Pointy"
+ label_max="Square"
+ value_min="-.5"
+ value_max="1"
+ camera_distance=".3"
+ camera_elevation=".04"
+ camera_angle="-20">
+ <param_morph />
+ </param>
+
+ <param
+ id="18"
+ group="0"
+ name="Puffy_Upper_Cheeks"
+ label="Upper Cheeks"
+ wearable="shape"
+ edit_group="shape_head"
+ edit_group_order="8"
+ label_min="Thin"
+ label_max="Puffy"
+ value_min="-1.5"
+ value_max="2.5"
+ camera_elevation=".1"
+ camera_distance=".3"
+ camera_angle="-20">
+ <param_morph />
+ </param>
+
+ <param
+ id="19"
+ group="0"
+ name="Upturned_Nose_Tip"
+ label="Nose Tip Angle"
+ wearable="shape"
+ edit_group="shape_nose"
+ edit_group_order="7"
+ label_min="Downturned"
+ label_max="Upturned"
+ value_min="-1.5"
+ value_max="1"
+ camera_elevation=".1"
+ camera_distance=".35"
+ camera_angle="15">
+ <param_morph />
+ </param>
+
+ <param
+ id="20"
+ group="0"
+ name="Bulbous_Nose"
+ label="Nose Thickness"
+ wearable="shape"
+ edit_group="shape_nose"
+ edit_group_order="4"
+ label_min="Thin Nose"
+ label_max="Bulbous Nose"
+ show_simple="true"
+ value_min="-.5"
+ value_max="1.5"
+ camera_elevation=".1"
+ camera_distance=".3">
+ <param_morph />
+ </param>
+
+ <param
+ id="21"
+ group="0"
+ name="Upper_Eyelid_Fold"
+ label="Upper Eyelid Fold"
+ wearable="shape"
+ edit_group="shape_eyes"
+ edit_group_order="5"
+ label_min="Uncreased"
+ label_max="Creased"
+ value_min="-0.2"
+ value_max="1.3"
+ camera_elevation=".1"
+ camera_distance=".35">
+ <param_morph />
+ </param>
+
+ <param
+ id="22"
+ group="0"
+ name="Attached_Earlobes"
+ label="Attached Earlobes"
+ wearable="shape"
+ edit_group="shape_ears"
+ edit_group_order="3"
+ label_min="Unattached"
+ label_max="Attached"
+ value_min="0"
+ value_max="1"
+ camera_elevation=".1"
+ camera_distance=".3"
+ camera_angle="45">
+ <param_morph />
+ </param>
+
+ <param
+ id="23"
+ group="0"
+ name="Baggy_Eyes"
+ label="Eye Bags"
+ wearable="shape"
+ edit_group="shape_eyes"
+ edit_group_order="6"
+ label_min="Smooth"
+ label_max="Baggy"
+ value_min="-.5"
+ value_max="1.5"
+ camera_elevation=".1"
+ camera_distance=".35">
+ <param_morph />
+ </param>
+
+ <param
+ id="765"
+ group="0"
+ name="Puffy_Lower_Lids"
+ label="Puffy Eyelids"
+ wearable="shape"
+ edit_group="shape_eyes"
+ edit_group_order="6.1"
+ label_min="Flat"
+ label_max="Puffy"
+ value_min="-.3"
+ value_max="2.5"
+ camera_elevation=".1"
+ camera_distance=".35">
+ <param_morph />
+ </param>
+
+ <param
+ id="24"
+ group="0"
+ name="Wide_Eyes"
+ label="Eye Opening"
+ wearable="shape"
+ edit_group="shape_eyes"
+ edit_group_order="1.1"
+ label_min="Narrow"
+ label_max="Wide"
+ value_min="-1.5"
+ value_max="2"
+ show_simple="true"
+ camera_elevation=".1"
+ camera_distance=".35">
+ <param_morph />
+ </param>
+
+ <param
+ id="25"
+ group="0"
+ name="Wide_Lip_Cleft"
+ label="Lip Cleft"
+ wearable="shape"
+ edit_group="shape_mouth"
+ edit_group_order="6"
+ label_min="Narrow"
+ label_max="Wide"
+ value_min="-.8"
+ value_max="1.5"
+ camera_elevation="0"
+ camera_distance=".28">
+ <param_morph />
+ </param>
+
+ <param
+ id="764"
+ group="0"
+ name="Lip_Cleft_Deep"
+ label="Lip Cleft Depth"
+ wearable="shape"
+ edit_group="shape_mouth"
+ edit_group_order="5.8"
+ label_min="Shallow"
+ label_max="Deep"
+ value_min="-.5"
+ value_max="1.2"
+ camera_elevation="0"
+ camera_distance=".28">
+ <param_morph />
+ </param>
+
+ <param
+ id="26"
+ group="1"
+ wearable="shape"
+ name="Lips_Thin"
+ edit_group="driven"
+ value_min="0"
+ value_max=".7">
+ <param_morph />
+ </param>
+
+ <param
+ id="27"
+ group="0"
+ name="Wide_Nose_Bridge"
+ label="Bridge Width"
+ wearable="shape"
+ edit_group="shape_nose"
+ edit_group_order="6"
+ label_min="Narrow"
+ label_max="Wide"
+ value_min="-1.3"
+ value_max="1.2"
+ camera_elevation=".1"
+ camera_distance=".3"
+ camera_angle="-20">
+ <param_morph />
+ </param>
+
+ <param
+ id="28"
+ group="1"
+ name="Lips_Fat"
+ wearable="shape"
+ edit_group="driven"
+ value_min="0"
+ value_max="2">
+ <param_morph />
+ </param>
+
+ <param
+ id="29"
+ group="1"
+ name="Wide_Upper_Lip"
+ wearable="shape"
+ edit_group="driven"
+ value_min="-.7"
+ value_max="1.3">
+ <param_morph />
+ </param>
+
+ <param
+ id="30"
+ group="1"
+ name="Wide_Lower_Lip"
+ wearable="shape"
+ edit_group="driven"
+ value_min="-.7"
+ value_max="1.3">
+ <param_morph />
+ </param>
+
+ <!--Arced eyebrows became a driver/driven param with new max value for backwards compatibility between 1.0 and 1.1-->
+ <param
+ id="872"
+ group="1"
+ name="Arced_Eyebrows"
+ label="Eyebrow Arc"
+ wearable="hair"
+ edit_group="hair_eyebrows"
+ edit_group_order="3"
+ label_min="Flat"
+ label_max="Arced"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <!--Lower eyebrows became a driver/driven param with new min value for backwards compatibility between 1.0 and 1.1-->
+ <param
+ id="871"
+ group="1"
+ name="Lower_Eyebrows"
+ label="Eyebrow Height"
+ show_simple="true"
+ wearable="hair"
+ edit_group="hair_eyebrows"
+ edit_group_order="2.5"
+ label_min="Higher"
+ label_max="Lower"
+ value_min="-2"
+ value_max="2">
+ <param_morph />
+ </param>
+
+ <param
+ id="35"
+ group="0"
+ name="Big_Ears"
+ label="Ear Size"
+ wearable="shape"
+ edit_group="shape_ears"
+ edit_group_order="1"
+ label_min="Small"
+ label_max="Large"
+ value_min="-1"
+ value_max="2"
+ camera_elevation=".1"
+ camera_distance=".3"
+ camera_angle="45">
+ <param_morph />
+ </param>
+
+ <param
+ id="796"
+ group="0"
+ name="Pointy_Ears"
+ label="Ear Tips"
+ wearable="shape"
+ edit_group="shape_ears"
+ edit_group_order="4"
+ label_min="Flat"
+ label_max="Pointy"
+ value_min="-.4"
+ value_max="3"
+ camera_elevation=".1"
+ camera_distance=".3"
+ camera_angle="45">
+ <param_morph />
+ </param>
+
+ <param
+ id="185"
+ group="0"
+ name="Deep_Chin"
+ label="Chin Depth"
+ wearable="shape"
+ edit_group="shape_chin"
+ edit_group_order="3"
+ label_min="Shallow"
+ label_max="Deep"
+ value_min="-1"
+ value_max="1"
+ camera_elevation=".1"
+ camera_distance=".4"
+ camera_angle="30">
+ <param_morph />
+ </param>
+
+ <param
+ id="186"
+ group="1"
+ name="Egg_Head"
+ label="Egg Head"
+ wearable="shape"
+ edit_group="shape_head"
+ label_min="Chin Heavy"
+ label_max="Forehead Heavy"
+ value_min="-1.3"
+ value_max="1"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="20">
+ <param_morph />
+ </param>
+
+ <param
+ id="187"
+ group="1"
+ name="Squash_Stretch_Head"
+ label="Squash/Stretch Head"
+ wearable="shape"
+ edit_group="shape_head"
+ label_min="Squash Head"
+ label_max="Stretch Head"
+ value_min="-.5"
+ value_max="1"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="20">
+ <param_morph>
+ <volume_morph
+ name="HEAD"
+ scale="-0.008 -0.006 0.015"/>
+ </param_morph>
+ </param>
+
+ <param
+ id="188"
+ group="1"
+ name="Square_Head"
+ wearable="shape"
+ label_min="Less Square"
+ label_max="More Square"
+ value_min="0"
+ value_max=".7"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="20">
+ <param_morph />
+ </param>
+
+ <param
+ id="189"
+ group="1"
+ wearable="shape"
+ name="Round_Head"
+ label_min="Less Round"
+ label_max="More Round"
+ value_min="0"
+ value_max="1"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="20">
+ <param_morph />
+ </param>
+
+ <param
+ id="194"
+ group="1"
+ name="Eye_Spread"
+ wearable="shape"
+ edit_group="shape_eyes"
+ label_min="Eyes Together"
+ label_max="Eyes Spread"
+ value_min="-2"
+ value_max="2">
+ <param_morph />
+ </param>
+
+ <param
+ id="400"
+ sex="male"
+ group="1"
+ name="Displace_Hair_Facial"
+ label="Hair Thickess"
+ wearable="hair"
+ edit_group="hair_facial"
+ label_min="Cropped Hair"
+ label_max="Bushy Hair"
+ value_min="0"
+ value_max="2">
+ <param_morph />
+ </param>
+
+ <param
+ id="506"
+ group="0"
+ name="Mouth_Height"
+ wearable="shape"
+ label="Mouth Position"
+ show_simple="true"
+ edit_group="shape_mouth"
+ edit_group_order="4"
+ label_min="High"
+ label_max="Low"
+ value_min="-2"
+ value_max="2"
+ camera_distance=".3"
+ camera_elevation=".04">
+ <param_morph />
+ </param>
+
+ <param
+ id="633"
+ group="1"
+ name="Fat_Head"
+ label="Fat Head"
+ wearable="shape"
+ edit_group="shape_body"
+ label_min="Skinny"
+ label_max="Fat"
+ value_min="0"
+ value_max="1"
+ camera_elevation=".3">
+ <param_morph/>
+ </param>
+
+ <param
+ id="630"
+ group="1"
+ name="Forehead_Round"
+ label="Round Forehead"
+ wearable="shape"
+ label_min="Less"
+ label_max="More"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="631"
+ group="1"
+ name="Forehead_Slant"
+ label="Slanted Forehead"
+ wearable="shape"
+ label_min="Less"
+ label_max="More"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="650"
+ group="0"
+ name="Eyelid_Corner_Up"
+ label="Outer Eye Corner"
+ wearable="shape"
+ edit_group="shape_eyes"
+ edit_group_order="4"
+ label_min="Corner Down"
+ label_max="Corner Up"
+ value_min="-1.3"
+ value_max="1.2"
+ camera_elevation=".1"
+ camera_distance=".30">
+ <param_morph />
+ </param>
+
+ <param
+ id="880"
+ group="0"
+ name="Eyelid_Inner_Corner_Up"
+ label="Inner Eye Corner"
+ wearable="shape"
+ edit_group="shape_eyes"
+ edit_group_order="4.2"
+ label_min="Corner Down"
+ label_max="Corner Up"
+ value_min="-1.3"
+ value_max="1.2"
+ camera_elevation=".1"
+ camera_distance=".30">
+ <param_morph />
+ </param>
+
+
+ <param
+ id="653"
+ group="0"
+ name="Tall_Lips"
+ wearable="shape"
+ label="Lip Fullness"
+ show_simple="true"
+ edit_group="shape_mouth"
+ edit_group_order="2"
+ label_min="Less Full"
+ label_max="More Full"
+ value_min="-1"
+ value_max="2"
+ camera_distance=".3"
+ camera_elevation=".04">
+ <param_morph />
+ </param>
+
+ <param
+ id="656"
+ group="0"
+ name="Crooked_Nose"
+ wearable="shape"
+ label="Crooked Nose"
+ edit_group="shape_nose"
+ edit_group_order="9"
+ label_min="Nose Left"
+ label_max="Nose Right"
+ value_min="-2"
+ value_max="2"
+ camera_distance=".3"
+ camera_elevation=".04"
+ camera_angle="-20">
+ <param_morph />
+ </param>
+
+ <param
+ id="657"
+ group="1"
+ name="Smile_Mouth"
+ wearable="shape"
+ label="Mouth Corner"
+ edit_group="shape_mouth"
+ label_min="Corner Normal"
+ label_max="Corner Up"
+ value_min="0"
+ value_max="1.4"
+ camera_distance=".3"
+ camera_elevation=".04">
+ <param_morph />
+ </param>
+
+ <param
+ id="658"
+ group="1"
+ name="Frown_Mouth"
+ wearable="shape"
+ label="Mouth Corner"
+ edit_group="shape_mouth"
+ label_min="Corner Normal"
+ label_max="Corner Down"
+ value_min="0"
+ value_max="1.2"
+ camera_distance=".3"
+ camera_elevation=".04">
+ <param_morph />
+ </param>
+
+ <param
+ id="797"
+ group="1"
+ name="Fat_Upper_Lip"
+ wearable="shape"
+ label="Fat Upper Lip"
+ edit_group="shape_mouth"
+ label_min="Normal Upper"
+ label_max="Fat Upper"
+ value_min="0"
+ value_max="1.5"
+ camera_distance=".3"
+ camera_elevation=".04">
+ <param_morph />
+ </param>
+
+ <param
+ id="798"
+ group="1"
+ name="Fat_Lower_Lip"
+ wearable="shape"
+ label="Fat Lower Lip"
+ edit_group="shape_mouth"
+ label_min="Normal Lower"
+ label_max="Fat Lower"
+ value_min="0"
+ value_max="1.5"
+ camera_distance=".3"
+ camera_elevation=".04">
+ <param_morph />
+ </param>
+
+ <param
+ id="660"
+ group="1"
+ name="Shear_Head"
+ wearable="shape"
+ label="Shear Face"
+ edit_group="shape_head"
+ label_min="Shear Left"
+ label_max="Shear Right"
+ value_min="-2"
+ value_max="2"
+ value_default="0"
+ camera_distance=".5"
+ camera_elevation=".04">
+ <param_morph />
+ </param>
+
+ <param
+ id="770"
+ group="1"
+ name="Elongate_Head"
+ wearable="shape"
+ label="Shear Face"
+ edit_group="shape_head"
+ label_min="Flat Head"
+ label_max="Long Head"
+ value_min="-1"
+ value_max="1"
+ value_default="0"
+ camera_distance=".5"
+ camera_elevation=".04">
+ <param_morph>
+ <volume_morph
+ name="HEAD"
+ scale="0.02 0.0 0.0"/>
+ </param_morph>
+ </param>
+
+ <param
+ id="663"
+ group="0"
+ name="Shift_Mouth"
+ wearable="shape"
+ label="Shift Mouth"
+ edit_group="shape_mouth"
+ edit_group_order="7"
+ label_min="Shift Left"
+ label_max="Shift Right"
+ value_min="-2"
+ value_max="2"
+ value_default="0"
+ camera_distance=".35"
+ camera_elevation=".04"
+ camera_angle="-20">
+ <param_morph />
+ </param>
+
+ <param
+ id="664"
+ group="0"
+ name="Pop_Eye"
+ wearable="shape"
+ label="Eye Pop"
+ edit_group="shape_eyes"
+ edit_group_order="8"
+ label_min="Pop Right Eye"
+ label_max="Pop Left Eye"
+ value_min="-1.3"
+ value_max="1.3"
+ value_default="0"
+ camera_elevation=".1"
+ camera_distance=".35">
+ <param_morph />
+ </param>
+
+ <param
+ id="760"
+ group="0"
+ name="Jaw_Angle"
+ wearable="shape"
+ label="Jaw Angle"
+ edit_group="shape_chin"
+ edit_group_order="3.5"
+ label_min="Low Jaw"
+ label_max="High Jaw"
+ value_min="-1.2"
+ value_max="2"
+ value_default="0"
+ camera_distance=".5"
+ camera_elevation=".04"
+ camera_angle="70">
+ <param_morph />
+ </param>
+
+ <param
+ id="665"
+ group="0"
+ name="Jaw_Jut"
+ wearable="shape"
+ label="Jaw Jut"
+ edit_group="shape_chin"
+ edit_group_order="4"
+ label_min="Overbite"
+ label_max="Underbite"
+ value_min="-2"
+ value_max="2"
+ value_default="0"
+ camera_distance=".5"
+ camera_elevation=".04"
+ camera_angle="70">
+ <param_morph />
+ </param>
+
+ <param
+ id="686"
+ group="1"
+ name="Head_Eyes_Big"
+ wearable="shape"
+ label="Eye Size"
+ edit_group="shape_eyes"
+ label_min="Beady Eyes"
+ label_max="Anime Eyes"
+ show_simple="true"
+ value_min="-2"
+ value_max="2"
+ value_default="0">
+ <param_morph />
+ </param>
+
+ <param
+ id="767"
+ group="1"
+ name="Bug_Eyed_Head"
+ wearable="shape"
+ label="Eye Depth"
+ edit_group="shape_eyes"
+ edit_group_order="4.5"
+ label_min="Sunken Eyes"
+ label_max="Bug Eyes"
+ value_min="-2"
+ value_max="2"
+ value_default="0">
+ <param_morph />
+ </param>
+
+ <!--
+ #Fat_Lips = Fat_Lips 34 1 0 1
+ #Wide_Lips = Wide_Lips 35 1 0 1
+ #Wide_Nose = Wide_Nose 36 1 0 1
+ -->
+ <!--
+ ##############
+ # Facial Expression morphs
+ ##############
+ -->
+ <param
+ id="300"
+ group="1"
+ name="Express_Closed_Mouth"
+ value_default="1"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="301"
+ group="1"
+ name="Express_Tongue_Out"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="302"
+ group="1"
+ name="Express_Surprise_Emote"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="303"
+ group="1"
+ name="Express_Wink_Emote"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="304"
+ group="1"
+ name="Express_Embarrassed_Emote"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="305"
+ group="1"
+ name="Express_Shrug_Emote"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="306"
+ group="1"
+ name="Express_Kiss"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="307"
+ group="1"
+ name="Express_Bored_Emote"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="308"
+ group="1"
+ name="Express_Repulsed_Emote"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="309"
+ group="1"
+ name="Express_Disdain"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="310"
+ group="1"
+ name="Express_Afraid_Emote"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="311"
+ group="1"
+ name="Express_Worry_Emote"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="312"
+ group="1"
+ name="Express_Cry_Emote"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="313"
+ group="1"
+ name="Express_Sad_Emote"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="314"
+ group="1"
+ name="Express_Anger_Emote"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="315"
+ group="1"
+ name="Express_Frown"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="316"
+ group="1"
+ name="Express_Laugh_Emote"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="317"
+ group="1"
+ name="Express_Toothsmile"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="318"
+ group="1"
+ name="Express_Smile"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="632"
+ group="1"
+ name="Express_Open_Mouth"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <!--
+ ##############
+ # Lipsync morphs
+ ##############
+ -->
+
+ <param
+ id="70"
+ group="1"
+ name="Lipsync_Aah"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="71"
+ group="1"
+ name="Lipsync_Ooh"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <!--
+ ##############
+ # other morphs (not user controlled)
+ ##############
+ -->
+ <param
+ id="40"
+ group="1"
+ name="Male_Head"
+ wearable="shape"
+ edit_group="driven"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="41"
+ group="1"
+ name="Old"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <!--
+ ##############
+ # animatable morphs
+ ##############
+ -->
+ <param
+ id="51"
+ group="1"
+ name="Furrowed_Eyebrows"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="53"
+ group="1"
+ name="Surprised_Eyebrows"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="54"
+ group="1"
+ name="Worried_Eyebrows"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="55"
+ group="1"
+ name="Frown_Mouth"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="57"
+ group="1"
+ name="Smile_Mouth"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="58"
+ group="1"
+ name="Blink_Left"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="59"
+ group="1"
+ name="Blink_Right"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <!--
+ #end morph targets
+ -->
+ </mesh>
+
+ <mesh
+ type="headMesh"
+ lod="1"
+ file_name="avatar_head_1.llm"
+ min_pixel_width="160"
+ reference="avatar_head.llm">
+ </mesh>
+
+ <mesh
+ type="headMesh"
+ lod="2"
+ file_name="avatar_head_2.llm"
+ min_pixel_width="80"
+ reference="avatar_head.llm">
+ </mesh>
+
+ <mesh
+ type="headMesh"
+ lod="3"
+ file_name="avatar_head_3.llm"
+ min_pixel_width="40"
+ reference="avatar_head.llm">
+ </mesh>
+
+ <mesh
+ type="headMesh"
+ lod="4"
+ file_name="avatar_head_4.llm"
+ min_pixel_width="0"
+ reference="avatar_head.llm">
+ </mesh>
+
+ <mesh
+ type="eyelashMesh"
+ lod="0"
+ file_name="avatar_eyelashes.llm"
+ min_pixel_width="320">
+ <param
+ shared="1"
+ id="660"
+ group="1"
+ name="Shear_Head"
+ wearable="shape"
+ label="Shear Face"
+ edit_group="shape_head"
+ label_min="Shear Left"
+ label_max="Shear Right"
+ value_min="-2"
+ value_max="2"
+ value_default="0"
+ camera_distance=".5"
+ camera_elevation=".04">
+ <param_morph />
+ </param>
+
+ <param
+ shared="1"
+ id="770"
+ group="1"
+ name="Elongate_Head"
+ wearable="shape"
+ label="Shear Face"
+ edit_group="shape_head"
+ label_min="Flat Head"
+ label_max="Long Head"
+ value_min="-1"
+ value_max="1"
+ value_default="0"
+ camera_distance=".5"
+ camera_elevation=".04">
+ <param_morph />
+ </param>
+
+ <param
+ shared="1"
+ id="664"
+ group="0"
+ name="Pop_Eye"
+ wearable="shape"
+ label="Eye Pop"
+ edit_group="shape_eyes"
+ edit_group_order="8"
+ label_min="Pop Right Eye"
+ label_max="Pop Left Eye"
+ value_min="-2"
+ value_max="2"
+ value_default="0"
+ camera_distance=".5"
+ camera_elevation=".04"
+ camera_angle="-20">
+ <param_morph />
+ </param>
+
+ <param
+ shared="1"
+ id="21"
+ group="0"
+ name="Upper_Eyelid_Fold"
+ label="Upper Eyelid Fold"
+ wearable="shape"
+ edit_group="shape_eyes"
+ label_min="Uncreased"
+ label_max="Creased"
+ value_min="-0.2"
+ value_max="1.3"
+ camera_elevation=".1"
+ camera_distance=".35">
+ <param_morph />
+ </param>
+
+ <param
+ shared="1"
+ id="24"
+ group="0"
+ name="Wide_Eyes"
+ label="Eye Opening"
+ wearable="shape"
+ edit_group="shape_eyes"
+ label_min="Narrow"
+ label_max="Wide"
+ show_simple="true"
+ value_min="-1.5"
+ value_max="2"
+ camera_elevation=".1"
+ camera_distance=".3">
+ <param_morph />
+ </param>
+
+ <param
+ shared="1"
+ id="186"
+ group="1"
+ name="Egg_Head"
+ label="Egg Head"
+ wearable="shape"
+ edit_group="shape_head"
+ label_min="Chin Heavy"
+ label_max="Forehead Heavy"
+ value_min="-1.3"
+ value_max="1"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="20">
+ <param_morph />
+ </param>
+
+ <param
+ shared="1"
+ id="187"
+ group="1"
+ name="Squash_Stretch_Head"
+ label="Squash/Stretch Head"
+ wearable="shape"
+ edit_group="shape_head"
+ label_min="Squash Head"
+ label_max="Stretch Head"
+ value_min="-.5"
+ value_max="1"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="20">
+ <param_morph />
+ </param>
+
+ <param
+ shared="1"
+ id="194"
+ group="1"
+ name="Eye_Spread"
+ edit_group="shape_eyes"
+ label_min="Eyes Together"
+ label_max="Eyes Spread"
+ value_min="-2"
+ value_max="2">
+ <param_morph />
+ </param>
+
+ <param
+ id="518"
+ group="0"
+ name="Eyelashes_Long"
+ wearable="shape"
+ label="Eyelash Length"
+ edit_group="shape_eyes"
+ edit_group_order="7"
+ label_min="Short"
+ label_max="Long"
+ value_min="-.3"
+ value_max="1.5"
+ camera_elevation=".1"
+ camera_distance=".30"
+ camera_angle="-20">
+ <param_morph />
+ </param>
+
+ <param
+ shared="1"
+ id="650"
+ group="0"
+ name="Eyelid_Corner_Up"
+ label="Outer Eye Corner"
+ wearable="shape"
+ edit_group="shape_eyes"
+ label_min="Corner Down"
+ label_max="Corner Up"
+ value_min="-1.3"
+ value_max="1.2"
+ camera_elevation=".1"
+ camera_distance=".3">
+ <param_morph />
+ </param>
+
+
+ <param
+ shared="1"
+ id="880"
+ group="0"
+ name="Eyelid_Inner_Corner_Up"
+ label="Inner Eye Corner"
+ wearable="shape"
+ edit_group="shape_eyes"
+ label_min="Corner Down"
+ label_max="Corner Up"
+ value_min="-1.3"
+ value_max="1.2"
+ camera_elevation=".1"
+ camera_distance=".3">
+ <param_morph />
+ </param>
+
+ <param
+ shared="1"
+ id="686"
+ group="1"
+ name="Head_Eyes_Big"
+ wearable="shape"
+ label="Eye Size"
+ edit_group="shape_eyes"
+ label_min="Beady Eyes"
+ label_max="Anime Eyes"
+ value_min="-2"
+ value_max="2"
+ show_simple="true"
+ value_default="0">
+ <param_morph />
+ </param>
+
+ <param
+ shared="1"
+ id="767"
+ group="1"
+ name="Bug_Eyed_Head"
+ wearable="shape"
+ label="Eye Depth"
+ edit_group="shape_eyes"
+ edit_group_order="4.5"
+ label_min="Sunken Eyes"
+ label_max="Bug Eyes"
+ value_min="-2"
+ value_max="2"
+ value_default="0">
+ <param_morph />
+ </param>
+
+ <!--
+ ##############
+ # Facial Expression morphs
+ ##############
+ -->
+ <param
+ shared="1"
+ id="301"
+ group="1"
+ name="Express_Tongue_Out"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ shared="1"
+ id="302"
+ group="1"
+ name="Express_Surprise_Emote"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ shared="1"
+ id="303"
+ group="1"
+ name="Express_Wink_Emote"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ shared="1"
+ id="304"
+ group="1"
+ name="Express_Embarrassed_Emote"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ shared="1"
+ id="305"
+ group="1"
+ name="Express_Shrug_Emote"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ shared="1"
+ id="306"
+ group="1"
+ name="Express_Kiss"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ shared="1"
+ id="307"
+ group="1"
+ name="Express_Bored_Emote"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ shared="1"
+ id="308"
+ group="1"
+ name="Express_Repulsed_Emote"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ shared="1"
+ id="309"
+ group="1"
+ name="Express_Disdain"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ shared="1"
+ id="310"
+ group="1"
+ name="Express_Afraid_Emote"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ shared="1"
+ id="312"
+ group="1"
+ name="Express_Cry_Emote"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ shared="1"
+ id="313"
+ group="1"
+ name="Express_Sad_Emote"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ shared="1"
+ id="314"
+ group="1"
+ name="Express_Anger_Emote"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ shared="1"
+ id="315"
+ group="1"
+ name="Express_Frown"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ shared="1"
+ id="316"
+ group="1"
+ name="Express_Laugh_Emote"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ shared="1"
+ id="317"
+ group="1"
+ name="Express_Toothsmile"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ shared="1"
+ id="318"
+ group="1"
+ name="Express_Smile"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <!--
+ ##############
+ # other morphs (not user controlled)
+ ##############
+ -->
+ <param
+ shared="1"
+ id="41"
+ group="1"
+ name="Old"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <!--
+ ##############
+ # animatable morphs
+ ##############
+ -->
+ <param
+ shared="1"
+ id="58"
+ group="1"
+ name="Blink_Left"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ shared="1"
+ id="59"
+ group="1"
+ name="Blink_Right"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+ </mesh>
+
+ <!--
+ #headMesh2 =
+ #headMesh3 =
+ -->
+ <mesh
+ type="upperBodyMesh"
+ lod="0"
+ file_name="avatar_upper_body.llm"
+ min_pixel_width="320">
+ <!--
+ #begin morph targets
+ #############
+ # tweakable morphs
+ #############
+ -->
+ <param
+ id="104"
+ group="1"
+ name="Big_Belly_Torso"
+ wearable="shape"
+ edit_group="driven"
+ value_min="0"
+ value_max="1">
+ <param_morph>
+ <volume_morph
+ name="BELLY"
+ scale="0.075 0.04 0.03"
+ pos="0.07 0 -0.07"/>
+ <volume_morph
+ name="PELVIS"
+ scale="0.075 0.04 0.03"
+ pos="0.07 0 -0.02"/>
+ </param_morph>
+ </param>
+
+ <param
+ id="626"
+ sex="female"
+ group="1"
+ name="Big_Chest"
+ label="Chest Size"
+ wearable="shape"
+ edit_group="shape_torso"
+ label_min="Small"
+ label_max="Large"
+ value_min="0"
+ value_max="1"
+ camera_elevation=".1"
+ camera_distance="1"
+ camera_angle="15">
+ <param_morph>
+ <volume_morph
+ name="LEFT_PEC"
+ scale="0.0273 0.0273 0.0273"
+ pos="0.038 0.024 -0.016"/>
+ <volume_morph
+ name="RIGHT_PEC"
+ scale="0.0273 0.0273 0.0273"
+ pos="0.038 -0.024 -0.016"/>
+ </param_morph>
+ </param>
+
+ <param
+ id="627"
+ sex="female"
+ group="1"
+ name="Small_Chest"
+ label="Chest Size"
+ wearable="shape"
+ edit_group="shape_torso"
+ label_min="Large"
+ label_max="Small"
+ value_min="0"
+ value_max="1"
+ camera_elevation="0"
+ camera_distance=".28">
+ <param_morph>
+ <volume_morph
+ name="LEFT_PEC"
+ scale="-0.05 0.0 0.0"
+ pos="-0.01 -0.01 -0.02"/>
+ <volume_morph
+ name="RIGHT_PEC"
+ scale="-0.05 0.0 0.0"
+ pos="-0.01 -0.01 -0.02"/>
+ </param_morph>
+ </param>
+
+ <param
+ id="843"
+ sex="female"
+ group="1"
+ name="No_Chest"
+ label="Chest Size"
+ wearable="shape"
+ edit_group="shape_torso"
+ label_min="Some"
+ label_max="None"
+ value_min="0"
+ value_max="1"
+ camera_elevation="0"
+ camera_distance=".28">
+ <param_morph>
+ <volume_morph
+ name="LEFT_PEC"
+ scale="-0.051 0.0 0.0"
+ pos="-0.02 -0.01 -0.03"/>
+ <volume_morph
+ name="RIGHT_PEC"
+ scale="-0.051 0.0 0.0"
+ pos="-0.02 -0.01 -0.03"/>
+ </param_morph>
+ </param>
+
+ <param
+ id="106"
+ group="1"
+ name="Muscular_Torso"
+ label="Torso Muscles"
+ show_simple="true"
+ wearable="shape"
+ edit_group="shape_torso"
+ label_min="Regular"
+ label_max="Muscular"
+ value_min="0"
+ value_max="1.4"
+ camera_elevation=".3"
+ camera_distance="1.2">
+ <param_morph>
+ <volume_morph
+ name="L_CLAVICLE"
+ scale="0.02 0.0 0.005"
+ pos="0.0 0 0.005"/>
+ <volume_morph
+ name="L_UPPER_ARM"
+ scale="0.015 0.0 0.005"
+ pos="0.015 0 0"/>
+ <volume_morph
+ name="L_LOWER_ARM"
+ scale="0.005 0.0 0.005"
+ pos="0.005 0 0"/>
+ <volume_morph
+ name="R_CLAVICLE"
+ scale="0.02 0.0 0.005"
+ pos="0.0 0 0.005"/>
+ <volume_morph
+ name="R_UPPER_ARM"
+ scale="0.015 0.0 0.005"
+ pos="0.015 0 0"/>
+ <volume_morph
+ name="R_LOWER_ARM"
+ scale="0.005 0.0 0.005"
+ pos="0.005 0 0"/>
+ </param_morph>
+ </param>
+
+ <param
+ id="648"
+ group="1"
+ sex="female"
+ name="Scrawny_Torso"
+ label="Torso Muscles"
+ show_simple="true"
+ wearable="shape"
+ edit_group="shape_torso"
+ label_min="Regular"
+ label_max="Scrawny"
+ value_min="0"
+ value_max="1.3"
+ camera_elevation=".3"
+ camera_distance="1.2">
+ <param_morph>
+ <volume_morph
+ name="BELLY"
+ scale="0.0 -0.01 0.0"
+ pos="0.0 0.0 0"/>
+ <volume_morph
+ name="UPPER_BACK"
+ scale="-0.01 -0.01 0.0"
+ pos="0.0 0.0 0"/>
+ <volume_morph
+ name="CHEST"
+ scale="-0.01 -0.01 0.0"
+ pos="0.01 0.0 0"/>
+ <volume_morph
+ name="L_CLAVICLE"
+ scale="0.0 -0.03 -0.005"
+ pos="0.0 0 -0.005"/>
+ <volume_morph
+ name="L_UPPER_ARM"
+ scale="-0.01 -0.01 -0.02"
+ pos="0 0 0"/>
+ <volume_morph
+ name="L_LOWER_ARM"
+ scale="-0.005 0.0 -0.01"
+ pos="-0.005 0 0"/>
+ <volume_morph
+ name="R_CLAVICLE"
+ scale="0.0 -0.03 -0.005"
+ pos="0.0 0 -0.005"/>
+ <volume_morph
+ name="R_UPPER_ARM"
+ scale="-0.01 -0.01 -0.02"
+ pos="0 0 0"/>
+ <volume_morph
+ name="R_LOWER_ARM"
+ scale="-0.005 0.0 -0.01"
+ pos="-0.005 0 0"/>
+ </param_morph>
+ </param>
+
+ <param
+ id="677"
+ group="1"
+ sex="male"
+ name="Scrawny_Torso_Male"
+ label="Torso Scrawny"
+ wearable="shape"
+ edit_group="shape_torso"
+ label_min="Regular"
+ label_max="Scrawny"
+ value_min="0"
+ value_max="1.3"
+ camera_elevation=".3"
+ camera_distance="1.2">
+ <param_morph>
+ <volume_morph
+ name="BELLY"
+ scale="-0.01 -0.01 0.0"
+ pos="0.01 0.0 0"/>
+ <volume_morph
+ name="UPPER_BACK"
+ scale="-0.01 -0.01 0.0"
+ pos="0.0 0.0 0"/>
+ <volume_morph
+ name="CHEST"
+ scale="-0.02 -0.02 0.0"
+ pos="0.01 0.0 0"/>
+ <volume_morph
+ name="L_CLAVICLE"
+ scale="0.0 -0.03 -0.005"
+ pos="0.0 0 -0.005"/>
+ <volume_morph
+ name="L_UPPER_ARM"
+ scale="-0.01 -0.01 -0.02"
+ pos="0 0 0"/>
+ <volume_morph
+ name="L_LOWER_ARM"
+ scale="-0.005 0.0 -0.01"
+ pos="-0.005 0 0"/>
+ <volume_morph
+ name="R_CLAVICLE"
+ scale="0.0 -0.03 -0.005"
+ pos="0.0 0 -0.005"/>
+ <volume_morph
+ name="R_UPPER_ARM"
+ scale="-0.01 -0.01 -0.02"
+ pos="0 0 0"/>
+ <volume_morph
+ name="R_LOWER_ARM"
+ scale="-0.005 0.0 -0.01"
+ pos="-0.005 0 0"/>
+ </param_morph>
+ </param>
+
+ <param
+ id="634"
+ group="1"
+ name="Fat_Torso"
+ label="Fat Torso"
+ wearable="shape"
+ edit_group="shape_body"
+ label_min="skinny"
+ label_max="fat"
+ value_min="0"
+ value_max="1"
+ camera_elevation=".3">
+ <param_morph>
+ <volume_morph
+ name="CHEST"
+ scale="0.02 0.03 0.03"
+ pos="0 0 -0.03"/>
+ <volume_morph
+ name="PELVIS"
+ scale="0.02 0.03 0.03"
+ pos="0 0 -0.03"/>
+ <volume_morph
+ name="UPPER_BACK"
+ scale="0.01 0.03 0.0"
+ pos="-0.03 0 0"/>
+ <volume_morph
+ name="LOWER_BACK"
+ scale="0.04 0.06 0.0"
+ pos="-0.06 0 0"/>
+ <volume_morph
+ name="LEFT_HANDLE"
+ pos="0.0 0.08 0.0"/>
+ <volume_morph
+ name="RIGHT_HANDLE"
+ pos="0.0 -0.08 0.0"/>
+ <volume_morph
+ name="LEFT_PEC"
+ scale="0.0367 0.0367 0.016"
+ pos="0.00 -0.005 -0.013"/>
+ <volume_morph
+ name="RIGHT_PEC"
+ scale="0.0367 0.0367 0.016"
+ pos="0.00 0.005 -0.013"/>
+ <volume_morph
+ name="BELLY"
+ scale="0.09 0.08 0.07"
+ pos="0 0 -0.05"/>
+ <volume_morph
+ name="L_CLAVICLE"
+ scale="0.0 0.0 0.015"/>
+ <volume_morph
+ name="L_UPPER_ARM"
+ scale="0.02 0.0 0.02"
+ pos="0.0 0.0 -0.02"/>
+ <volume_morph
+ name="L_LOWER_ARM"
+ scale="0.01 0.0 0.01"
+ pos="0.0 0.0 -0.01"/>
+ <volume_morph
+ name="R_CLAVICLE"
+ scale="0.0 0.0 0.015"/>
+ <volume_morph
+ name="R_UPPER_ARM"
+ scale="0.02 0.0 0.02"
+ pos="0.0 0.0 -0.02"/>
+ <volume_morph
+ name="R_LOWER_ARM"
+ scale="0.01 0.0 0.01"
+ pos="0.0 0.0 -0.01"/>
+ <volume_morph
+ name="NECK"
+ scale="0.015 0.01 0.0"/>
+ <volume_morph
+ name="HEAD"
+ scale="0.0 0.0 0.01"
+ pos="0 0 -0.01"/>
+ </param_morph>
+ </param>
+
+ <param
+ id="507"
+ group="0"
+ sex="female"
+ name="Breast_Gravity"
+ label="Breast Buoyancy"
+ wearable="shape"
+ edit_group="shape_torso"
+ edit_group_order="7"
+ label_min="Less Gravity"
+ label_max="More Gravity"
+ value_default="0"
+ value_min="-1.5"
+ value_max="2"
+ camera_elevation=".3"
+ camera_distance=".8">
+ <param_morph>
+ <volume_morph
+ name="LEFT_PEC"
+ scale="0.0 0.0 0.0"
+ pos="0.004 0.0 -0.01"/>
+ <volume_morph
+ name="RIGHT_PEC"
+ scale="0.0 0.0 0.0"
+ pos="0.004 0.0 -0.01"/>
+ </param_morph>
+ </param>
+
+ <param
+ id="628"
+ group="1"
+ name="Displace_Loose_Upperbody"
+ label="Shirt Fit"
+ wearable="shirt"
+ edit_group="driven"
+ clothing_morph="true"
+ value_min="0"
+ value_max="1"
+ value_default="0">
+ <param_morph />
+ </param>
+
+ <param
+ id="840"
+ group="0"
+ name="Shirtsleeve_flair"
+ label="Sleeve Looseness"
+ show_simple="true"
+ wearable="shirt"
+ edit_group="shirt"
+ edit_group_order="6"
+ clothing_morph="true"
+ label_min="Tight Sleeves"
+ label_max="Loose Sleeves"
+ value_min="0"
+ value_max="1.5"
+ camera_distance="1.8"
+ camera_angle="30"
+ camera_elevation="-.3">
+ <param_morph />
+ </param>
+
+ <param
+ id="855"
+ group="1"
+ name="Love_Handles"
+ wearable="shape"
+ edit_group="driven"
+ value_default="0"
+ value_min="-1"
+ value_max="2">
+ <param_morph>
+ <volume_morph
+ name="BELLY"
+ scale="0.0 0.02 0.0"/>
+ <volume_morph
+ name="LOWER_BACK"
+ scale="0.0 0.02 0.0"/>
+ <volume_morph
+ name="LEFT_HANDLE"
+ pos="0.0 0.025 0.0"/>
+ <volume_morph
+ name="RIGHT_HANDLE"
+ pos="0.0 -0.025 0.0"/>
+ </param_morph>
+ </param>
+
+ <param
+ id="684"
+ group="0"
+ sex="female"
+ name="Breast_Female_Cleavage"
+ label="Breast Cleavage"
+ wearable="shape"
+ edit_group="shape_torso"
+ edit_group_order="8"
+ label_min="Separate"
+ label_max="Join"
+ value_default="0"
+ value_min="-.3"
+ value_max="1.3"
+ camera_elevation=".3"
+ camera_distance=".8">
+ <param_morph>
+ <volume_morph
+ name="LEFT_PEC"
+ scale="0.0 0.0 0.0"
+ pos="0.0 -0.026 0.0"/>
+ <volume_morph
+ name="RIGHT_PEC"
+ scale="0.0 0.0 0.0"
+ pos="0.0 0.026 0.0"/>
+ </param_morph>
+ </param>
+
+ <param
+ id="685"
+ group="0"
+ sex="male"
+ name="Chest_Male_No_Pecs"
+ label="Pectorals"
+ wearable="shape"
+ edit_group="shape_torso"
+ edit_group_order="5"
+ label_min="Big Pectorals"
+ label_max="Sunken Chest"
+ value_default="0"
+ value_min="-0.5"
+ value_max="1.1"
+ camera_elevation=".3"
+ camera_distance="1.2">
+ <param_morph>
+ <volume_morph
+ name="LEFT_PEC"
+ scale="0.0 0.0 0.0"
+ pos="-0.03 -0.024 -0.01"/>
+ <volume_morph
+ name="RIGHT_PEC"
+ scale="0.0 0.0 0.0"
+ pos="-0.03 0.024 -0.01"/>
+ </param_morph>
+ </param>
+
+ <!-- ############# #
+ other morphs (not user controlled)
+ ############# -->
+ <param
+ id="100"
+ group="1"
+ name="Male_Torso"
+ wearable="shape"
+ edit_group="driven"
+ label_min="Male_Torso"
+ value_min="0"
+ value_max="1">
+ <param_morph>
+ <volume_morph
+ name="CHEST"
+ scale="0.03 0.04 0.02"
+ pos="-0.03 0 -0.01"/>
+ <volume_morph
+ name="BELLY"
+ scale="0.03 0.03 0.0"
+ pos="-0.03 0 0.02"/>
+ <volume_morph
+ name="LEFT_PEC"
+ scale="0.0 0.0 0.0"
+ pos="0.008 -0.03 0.01"/>
+ <volume_morph
+ name="RIGHT_PEC"
+ scale="0.0 0.0 0.0"
+ pos="0.008 0.03 0.01"/>
+ <volume_morph
+ name="L_CLAVICLE"
+ scale="0.02 0.0 0.01"
+ pos="-0.02 0 0"/>
+ <volume_morph
+ name="L_UPPER_ARM"
+ scale="0.01 0.0 0.01"
+ pos="0.0 0.0 -0.01"/>
+ <volume_morph
+ name="L_LOWER_ARM"
+ scale="0.005 0.0 0.005"
+ pos="0.0 0.0 -0.005"/>
+ <volume_morph
+ name="R_CLAVICLE"
+ scale="0.02 0.0 0.01"
+ pos="-0.02 0 0"/>
+ <volume_morph
+ name="R_UPPER_ARM"
+ scale="0.01 0.0 0.01"
+ pos="0.0 0.0 -0.01"/>
+ <volume_morph
+ name="R_LOWER_ARM"
+ scale="0.005 0.0 0.005"
+ pos="0.0 0.0 -0.005"/>
+ <volume_morph
+ name="NECK"
+ scale="0.015 0.01 0.0"/>
+ <volume_morph
+ name="HEAD"
+ scale="0.0 0.0 0.01"
+ pos="0 0 -0.01"/>
+ </param_morph>
+ </param>
+
+ <!--
+ ##############
+ # animatable morphs
+ ##############
+ -->
+ <param
+ id="101"
+ group="1"
+ name="Hands_Relaxed"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="102"
+ group="1"
+ name="Hands_Point"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="103"
+ group="1"
+ name="Hands_Fist"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="666"
+ group="1"
+ name="Hands_Relaxed_L"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="667"
+ group="1"
+ name="Hands_Point_L"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="668"
+ group="1"
+ name="Hands_Fist_L"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="669"
+ group="1"
+ name="Hands_Relaxed_R"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="670"
+ group="1"
+ name="Hands_Point_R"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="671"
+ group="1"
+ name="Hands_Fist_R"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="672"
+ group="1"
+ name="Hands_Typing"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="766"
+ group="1"
+ name="Hands_Salute_R"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="791"
+ group="1"
+ name="Hands_Peace_R"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="792"
+ group="1"
+ name="Hands_Spread_R"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <!--
+ #############
+ # physics morphs (not user controlled)
+ #############
+ -->
+ <param
+ id="1200"
+ group="1"
+ sex="female"
+ name="Breast_Physics_UpDown_Driven"
+ wearable="physics"
+ edit_group="driven"
+ value_default="0"
+ value_min="-3"
+ value_max="3">
+ <param_morph>
+ <volume_morph
+ name="LEFT_PEC"
+ scale="0.0 0.0 0.0"
+ pos="0.0 0.0 -0.01"/>
+ <volume_morph
+ name="RIGHT_PEC"
+ scale="0.0 0.0 0.0"
+ pos="0.0 0.0 -0.01"/>
+ </param_morph>
+ </param>
+
+ <param
+ id="1201"
+ group="1"
+ sex="female"
+ name="Breast_Physics_InOut_Driven"
+ wearable="physics"
+ edit_group="driven"
+ value_default="0"
+ value_min="-1.25"
+ value_max="1.25">
+ <param_morph>
+ <volume_morph
+ name="LEFT_PEC"
+ scale="0.0 0.0 0.0"
+ pos="0.0 -0.026 0.0"/>
+ <volume_morph
+ name="RIGHT_PEC"
+ scale="0.0 0.0 0.0"
+ pos="0.0 0.026 -0.0"/>
+ </param_morph>
+ </param>
+
+ <param
+ id="1204"
+ group="1"
+ name="Belly_Physics_Torso_UpDown_Driven"
+ wearable="physics"
+ edit_group="driven"
+ value_default="0"
+ value_min="-1"
+ value_max="1">
+ <param_morph>
+ <volume_morph
+ name="BELLY"
+ scale="0.0 0.0 0.0"
+ pos="0.0 0.0 0.05"/>
+ </param_morph>
+ </param>
+
+ <param
+ id="1207"
+ group="1"
+ name="Breast_Physics_LeftRight_Driven"
+ wearable="physics"
+ edit_group="driven"
+ value_default="0"
+ value_min="-2"
+ value_max="2">
+ <param_morph>
+ <volume_morph
+ name="LEFT_PEC"
+ scale="0.0 0.0 0.0"
+ pos="0.0 0.03 0.0"/>
+ <volume_morph
+ name="RIGHT_PEC"
+ scale="0.0 0.0 0.0"
+ pos="0.0 0.03 0.0"/>
+ </param_morph>
+ </param>
+
+ <!--
+ #end morph targets
+ -->
+
+ </mesh>
+
+ <mesh
+ type="upperBodyMesh"
+ lod="1"
+ file_name="avatar_upper_body_1.llm"
+ min_pixel_width="160"
+ reference="avatar_upper_body.llm">
+ </mesh>
+
+ <mesh
+ type="upperBodyMesh"
+ lod="2"
+ file_name="avatar_upper_body_2.llm"
+ min_pixel_width="80"
+ reference="avatar_upper_body.llm">
+ </mesh>
+
+ <mesh
+ type="upperBodyMesh"
+ lod="3"
+ file_name="avatar_upper_body_3.llm"
+ min_pixel_width="40"
+ reference="avatar_upper_body.llm">
+ </mesh>
+
+ <mesh
+ type="upperBodyMesh"
+ lod="4"
+ file_name="avatar_upper_body_4.llm"
+ min_pixel_width="0"
+ reference="avatar_upper_body.llm">
+ </mesh>
+
+ <!--
+ #upperBodyMesh2 =
+ #upperBodyMesh3 =
+ -->
+ <mesh
+ type="lowerBodyMesh"
+ lod="0"
+ file_name="avatar_lower_body.llm"
+ min_pixel_width="320">
+ <!--
+ #begin morph targets
+ #############
+ # tweakable morphs
+ #############
+ -->
+ <param
+ id="156"
+ group="1"
+ name="Big_Belly_Legs"
+ wearable="shape"
+ edit_group="driven"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+
+ <param
+ id="151"
+ group="1"
+ name="Big_Butt_Legs"
+ label="Butt Size"
+ wearable="shape"
+ edit_group="shape_legs"
+ label_min="Regular"
+ label_max="Large"
+ value_min="0"
+ value_max="1">
+ <param_morph>
+ <volume_morph
+ name="PELVIS"
+ scale="0.03 0.0 0.02"
+ pos="-0.03 0 -0.025"/>
+ </param_morph>
+ </param>
+
+ <param
+ id="794"
+ group="1"
+ name="Small_Butt"
+ label="Butt Size"
+ wearable="shape"
+ edit_group="shape_legs"
+ label_min="Regular"
+ label_max="Small"
+ value_min="0"
+ value_max="1">
+ <param_morph>
+ <volume_morph
+ name="PELVIS"
+ scale="-0.01 0.0 0.0"
+ pos="0.01 0 0.0"/>
+ <volume_morph
+ name="BUTT"
+ scale="0.0 0.0886 0.0"
+ pos="0.03 0 0.0"/>
+ </param_morph>
+ </param>
+
+ <param
+ id="152"
+ group="1"
+ name="Muscular_Legs"
+ label="Leg Muscles"
+ show_simple="true"
+ wearable="shape"
+ edit_group="shape_legs"
+ label_min="Regular Muscles"
+ label_max="More Muscles"
+ value_min="0"
+ value_max="1.5"
+ camera_distance="1.3"
+ camera_elevation="-.5">
+ <param_morph>
+ <volume_morph
+ name="L_UPPER_LEG"
+ scale="0.015 0.015 0.0"
+ pos="0.0 0 0.0"/>
+ <volume_morph
+ name="L_LOWER_LEG"
+ scale="0.01 0.01 0.0"
+ pos="0.0 0 0.0"/>
+ <volume_morph
+ name="R_UPPER_LEG"
+ scale="0.015 0.015 0.0"
+ pos="0.0 0 0.0"/>
+ <volume_morph
+ name="R_LOWER_LEG"
+ scale="0.01 0.01 0.0"
+ pos="0.0 0 0.0"/>
+ </param_morph>
+ </param>
+
+ <param
+ id="651"
+ group="1"
+ name="Scrawny_Legs"
+ label="Scrawny Leg"
+ wearable="shape"
+ edit_group="shape_legs"
+ label_min="Regular Muscles"
+ label_max="Less Muscles"
+ value_min="0"
+ value_max="1.5"
+ camera_distance="1.3"
+ camera_elevation="-.5">
+ <param_morph>
+ <volume_morph
+ name="L_UPPER_LEG"
+ scale="-0.03 -0.03 0.0"
+ pos="0.0 0 0.0"/>
+ <volume_morph
+ name="L_LOWER_LEG"
+ scale="-0.015 -0.015 0.0"
+ pos="0.0 0 0.0"/>
+ <volume_morph
+ name="R_UPPER_LEG"
+ scale="-0.03 -0.03 0.0"
+ pos="0.0 0 0.0"/>
+ <volume_morph
+ name="R_LOWER_LEG"
+ scale="-0.015 -0.015 0.0"
+ pos="0.0 0 0.0"/>
+ </param_morph>
+ </param>
+
+ <param
+ id="853"
+ group="1"
+ name="Bowed_Legs"
+ label="Knee Angle"
+ wearable="shape"
+ value_min="-1"
+ value_max="1">
+ <param_morph>
+ <volume_morph
+ name="L_UPPER_LEG"
+ pos="0.0 0.03 0.0"/>
+ <volume_morph
+ name="L_LOWER_LEG"
+ pos="0.0 0.03 0.0"/>
+ <volume_morph
+ name="R_UPPER_LEG"
+ pos="0.0 -0.03 0.0"/>
+ <volume_morph
+ name="R_LOWER_LEG"
+ pos="0.0 -0.03 0.0"/>
+ </param_morph>
+ </param>
+
+ <param
+ id="500"
+ group="1"
+ name="Shoe_Heel_Height"
+ label="Heel Height"
+ wearable="shoes"
+ edit_group="shoes"
+ label_min="Low Heels"
+ label_max="High Heels"
+ value_min="0"
+ value_max="1"
+ camera_distance="1.5"
+ camera_elevation="-.5">
+ <param_morph />
+ </param>
+
+ <param
+ id="501"
+ group="1"
+ name="Shoe_Platform_Height"
+ label="Platform Height"
+ wearable="shoes"
+ edit_group="shoes"
+ label_min="Low Platforms"
+ label_max="High Platforms"
+ value_min="0"
+ value_max="1"
+ camera_distance="1.5"
+ camera_elevation="-.5">
+ <param_morph />
+ </param>
+
+ <param
+ id="508"
+ group="0"
+ name="Shoe_Platform_Width"
+ label="Platform Width"
+ wearable="shoes"
+ edit_group="shoes"
+ edit_group_order="7"
+ label_min="Narrow"
+ label_max="Wide"
+ value_min="-1"
+ value_max="2"
+ camera_angle="15"
+ camera_distance="1.5"
+ camera_elevation="-1">
+ <param_morph />
+ </param>
+
+ <param
+ id="509"
+ group="1"
+ name="Shoe_Heel_Point"
+ label="Heel Shape"
+ wearable="shoes"
+ edit_group="shoes"
+ label_min="Default Heels"
+ label_max="Pointy Heels"
+ value_min="0"
+ value_max="1"
+ camera_distance="1.3"
+ camera_elevation="-.5">
+ <param_morph />
+ </param>
+
+ <param
+ id="510"
+ group="1"
+ name="Shoe_Heel_Thick"
+ label="Heel Shape"
+ wearable="shoes"
+ edit_group="shoes"
+ label_min="default Heels"
+ label_max="Thick Heels"
+ value_min="0"
+ value_max="1"
+ camera_distance="1.3"
+ camera_elevation="-.5">
+ <param_morph />
+ </param>
+
+ <param
+ id="511"
+ group="1"
+ name="Shoe_Toe_Point"
+ label="Toe Shape"
+ wearable="shoes"
+ edit_group="shoes"
+ label_min="Default Toe"
+ label_max="Pointy Toe"
+ value_min="0"
+ value_max="1"
+ camera_distance="1.3"
+ camera_elevation="-.5">
+ <param_morph />
+ </param>
+
+ <param
+ id="512"
+ group="1"
+ name="Shoe_Toe_Square"
+ label="Toe Shape"
+ wearable="shoes"
+ edit_group="shoes"
+ label_min="Default Toe"
+ label_max="Square Toe"
+ value_min="0"
+ value_max="1"
+ camera_distance="1.5"
+ camera_elevation="-.5">
+ <param_morph />
+ </param>
+
+ <param
+ id="654"
+ group="0"
+ name="Shoe_Toe_Thick"
+ label="Toe Thickness"
+ wearable="shoes"
+ edit_group="shoes"
+ edit_group_order="5"
+ label_min="Flat Toe"
+ label_max="Thick Toe"
+ value_min="0"
+ value_max="2"
+ camera_angle="15"
+ camera_distance="1.5"
+ camera_elevation="-1">
+ <param_morph />
+ </param>
+
+ <param
+ id="515"
+ group="0"
+ name="Foot_Size"
+ label="Foot Size"
+ wearable="shape"
+ edit_group="shape_legs"
+ edit_group_order="6"
+ label_min="Small"
+ label_max="Big"
+ value_min="-1"
+ value_max="3"
+ camera_angle="45"
+ camera_distance="1.1"
+ camera_elevation="-1">
+ <param_morph>
+ <volume_morph
+ name="L_FOOT"
+ scale="0.02 0.01 0.0"
+ pos="0.01 0 0"/>
+ <volume_morph
+ name="R_FOOT"
+ scale="0.02 0.01 0.0"
+ pos="0.01 0 0"/>
+ </param_morph>
+ </param>
+
+ <param
+ id="516"
+ group="1"
+ name="Displace_Loose_Lowerbody"
+ label="Pants Fit"
+ wearable="pants"
+ edit_group="driven"
+ clothing_morph="true"
+ value_min="0"
+ value_max="1"
+ value_default="0">
+ <param_morph />
+ </param>
+
+ <param
+ id="625"
+ group="0"
+ name="Leg_Pantflair"
+ label="Cuff Flare"
+ show_simple="true"
+ wearable="pants"
+ edit_group="pants"
+ edit_group_order="3"
+ clothing_morph="true"
+ label_min="Tight Cuffs"
+ label_max="Flared Cuffs"
+ value_min="0"
+ value_max="1.5"
+ camera_distance="1.8"
+ camera_angle="30"
+ camera_elevation="-.3">
+ <param_morph />
+ </param>
+
+ <param
+ id="793"
+ group="1"
+ name="Leg_Longcuffs"
+ label="Longcuffs"
+ wearable="pants"
+ edit_group="driven"
+ clothing_morph="true"
+ value_min="0"
+ value_max="3"
+ value_default="0">
+ <param_morph />
+ </param>
+
+ <param
+ id="638"
+ group="0"
+ name="Low_Crotch"
+ label="Pants Crotch"
+ wearable="pants"
+ clothing_morph="true"
+ edit_group="pants"
+ edit_group_order="4"
+ label_min="High and Tight"
+ label_max="Low and Loose"
+ value_min="0"
+ value_max="1.3"
+ camera_distance="1.2"
+ camera_angle="-20"
+ camera_elevation="-.3">
+ <param_morph />
+ </param>
+
+ <param
+ id="635"
+ group="1"
+ name="Fat_Legs"
+ label="Fat Torso"
+ wearable="shape"
+ edit_group="shape_body"
+ label_min="skinny"
+ label_max="fat"
+ value_min="0"
+ value_max="1">
+ <param_morph>
+ <volume_morph
+ name="PELVIS"
+ scale="0.03 0.06 0.0"/>
+ <volume_morph
+ name="R_UPPER_LEG"
+ scale="0.02 0.02 0.0"
+ pos="0.0 -0.02 0.0"/>
+ <volume_morph
+ name="R_LOWER_LEG"
+ scale="0.01 0.01 0.0"/>
+ <volume_morph
+ name="L_UPPER_LEG"
+ scale="0.02 0.02 0.0"
+ pos="0.0 0.02 0.0"/>
+ <volume_morph
+ name="L_LOWER_LEG"
+ scale="0.01 0.01 0.0"/>
+ </param_morph>
+ </param>
+
+ <param
+ id="854"
+ group="1"
+ name="Saddlebags"
+ wearable="shape"
+ edit_group="driven"
+ value_min="-.5"
+ value_max="3">
+ <param_morph>
+ <volume_morph
+ name="PELVIS"
+ scale="0.0 0.025 0.0"/>
+ </param_morph>
+
+ </param>
+
+ <param
+ id="879"
+ group="0"
+ sex="male"
+ name="Male_Package"
+ label="Package"
+ wearable="shape"
+ edit_group="shape_legs"
+ edit_group_order="4.6"
+ label_min="Coin Purse"
+ label_max="Duffle Bag"
+ value_default="0"
+ value_min="-.5"
+ value_max="2"
+ camera_angle="60"
+ camera_distance=".6">
+ <param_morph />
+ </param>
+
+ <!--
+ #############
+ # other morphs (not user controlled)
+ #############
+ -->
+ <param
+ id="153"
+ group="1"
+ name="Male_Legs"
+ wearable="shape"
+ edit_group="driven"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <!--
+ #############
+ # physics morphs (not user controlled)
+ #############
+ -->
+ <param
+ id="1202"
+ group="1"
+ name="Belly_Physics_Legs_UpDown_Driven"
+ wearable="physics"
+ cross_wearable="true"
+ edit_group="driven"
+ value_min="-1"
+ value_max="1">
+ <param_morph />
+ </param>
+
+
+ <param
+ id="1205"
+ group="1"
+ name="Butt_Physics_UpDown_Driven"
+ wearable="physics"
+ cross_wearable="true"
+ edit_group="driven"
+ value_default="0"
+ value_min="-1"
+ value_max="1">
+ <param_morph>
+ <volume_morph
+ name="BUTT"
+ pos="0.0 0.0 0.05"/>
+ </param_morph>
+ </param>
+
+ <param
+ id="1206"
+ group="1"
+ name="Butt_Physics_LeftRight_Driven"
+ wearable="physics"
+ cross_wearable="true"
+ edit_group="driven"
+ value_default="0"
+ value_min="-1"
+ value_max="1">
+ <param_morph>
+ <volume_morph
+ name="BUTT"
+ pos="0.0 0.05 0.0"/>
+ </param_morph>
+ </param>
+
+ <!--
+ #end morph targets
+ -->
+
+ </mesh>
+
+ <mesh
+ type="lowerBodyMesh"
+ lod="1"
+ file_name="avatar_lower_body_1.llm"
+ min_pixel_width="160"
+ reference="avatar_lower_body.llm">
+ </mesh>
+
+ <mesh
+ type="lowerBodyMesh"
+ lod="2"
+ file_name="avatar_lower_body_2.llm"
+ min_pixel_width="80"
+ reference="avatar_lower_body.llm">
+ </mesh>
+
+ <mesh
+ type="lowerBodyMesh"
+ lod="3"
+ file_name="avatar_lower_body_3.llm"
+ min_pixel_width="40"
+ reference="avatar_lower_body.llm">
+ </mesh>
+
+ <mesh
+ type="lowerBodyMesh"
+ lod="4"
+ file_name="avatar_lower_body_4.llm"
+ min_pixel_width="0"
+ reference="avatar_lower_body.llm">
+ </mesh>
+
+ <!--
+ #lowerBodyMesh2 =
+ #lowerBodyMesh3 =
+ -->
+ <!--
+ #eyeLidLeftMesh =
+ -->
+ <mesh
+ type="eyeBallLeftMesh"
+ lod="0"
+ file_name="avatar_eye.llm"
+ min_pixel_width="320">
+ <!-- begin morph_params -->
+ <param
+ id="679"
+ group="1"
+ name="Eyeball_Size"
+ label="Eyeball Size"
+ wearable="shape"
+ edit_group="shape_eyes"
+ label_min="small eye"
+ label_max="big eye"
+ value_min="-.25"
+ value_max=".10">
+ <param_morph />
+ </param>
+
+ <param
+ id="687"
+ group="1"
+ name="Eyeball_Size"
+ label="Big Eyeball"
+ wearable="shape"
+ edit_group="shape_eyes"
+ label_min="small eye"
+ label_max="big eye"
+ value_min="-.25"
+ value_max=".25">
+ <param_morph />
+ </param>
+ </mesh>
+
+ <mesh
+ type="eyeBallLeftMesh"
+ lod="1"
+ file_name="avatar_eye_1.llm"
+ min_pixel_width="80">
+ <!-- begin morph_params -->
+ <param
+ id="694"
+ group="1"
+ name="Eyeball_Size"
+ label="Eyeball Size"
+ wearable="shape"
+ edit_group="shape_eyes"
+ label_min="small eye"
+ label_max="big eye"
+ value_min="-.25"
+ value_max=".10">
+ <param_morph />
+ </param>
+
+ <param
+ id="695"
+ group="1"
+ name="Eyeball_Size"
+ label="Big Eyeball"
+ wearable="shape"
+ edit_group="shape_eyes"
+ label_min="small eye"
+ label_max="big eye"
+ value_min="-.25"
+ value_max=".25">
+ <param_morph />
+ </param>
+ </mesh>
+
+ <!--
+ #eyeLidRightMesh =
+ -->
+ <mesh
+ type="eyeBallRightMesh"
+ lod="0"
+ file_name="avatar_eye.llm"
+ min_pixel_width="320">
+ <!-- begin morph_params -->
+ <param
+ id="680"
+ group="1"
+ name="Eyeball_Size"
+ label="Eyeball Size"
+ wearable="shape"
+ label_min="small eye"
+ label_max="big eye"
+ value_min="-.25"
+ value_max=".10">
+ <param_morph />
+ </param>
+
+ <param
+ id="688"
+ group="1"
+ name="Eyeball_Size"
+ label="Big Eyeball"
+ wearable="shape"
+ label_min="small eye"
+ label_max="big eye"
+ value_min="-.25"
+ value_max=".25">
+ <param_morph />
+ </param>
+ </mesh>
+
+ <mesh
+ type="eyeBallRightMesh"
+ lod="1"
+ file_name="avatar_eye_1.llm"
+ min_pixel_width="80">
+ <!-- begin morph_params -->
+ <param
+ id="681"
+ group="1"
+ name="Eyeball_Size"
+ label="Eyeball Size"
+ wearable="shape"
+ edit_group="shape_eyes"
+ label_min="small eye"
+ label_max="big eye"
+ value_min="-.25"
+ value_max=".10">
+ <param_morph />
+ </param>
+
+ <param
+ id="691"
+ group="1"
+ name="Eyeball_Size"
+ label="Big Eyeball"
+ wearable="shape"
+ edit_group="shape_eyes"
+ label_min="small eye"
+ label_max="big eye"
+ value_min="-.25"
+ value_max=".25">
+ <param_morph />
+ </param>
+ </mesh>
+
+ <mesh
+ type="skirtMesh"
+ lod="0"
+ file_name="avatar_skirt.llm"
+ min_pixel_width="320">
+ <param
+ id="845"
+ group="1"
+ name="skirt_poofy"
+ label="poofy skirt"
+ clothing_morph="true"
+ wearable="skirt"
+ edit_group="skirt"
+ label_min="less poofy"
+ label_max="more poofy"
+ value_min="0"
+ value_max="1.5">
+ <param_morph />
+ </param>
+
+ <param
+ id="846"
+ group="1"
+ name="skirt_loose"
+ label="loose skirt"
+ clothing_morph="true"
+ wearable="skirt"
+ edit_group="skirt"
+ label_min="form fitting"
+ label_max="loose"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="866"
+ group="1"
+ name="skirt_tight"
+ label="tight skirt"
+ clothing_morph="true"
+ wearable="skirt"
+ edit_group="skirt"
+ label_min="form fitting"
+ label_max="loose"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="867"
+ group="1"
+ name="skirt_smallbutt"
+ label="tight skirt"
+ clothing_morph="false"
+ wearable="skirt"
+ edit_group="skirt"
+ cross_wearable="true"
+ label_min="form fitting"
+ label_max="loose"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="848"
+ group="0"
+ name="skirt_bustle"
+ label="bustle skirt"
+ clothing_morph="true"
+ wearable="skirt"
+ edit_group_order="3"
+ edit_group="skirt"
+ label_min="no bustle"
+ label_max="more bustle"
+ value_min="0"
+ value_max="2"
+ value_default=".2"
+ camera_angle="100"
+ camera_distance="1.3"
+ camera_elevation="-.5">
+ <param_morph />
+ </param>
+
+ <param
+ id="847"
+ group="1"
+ name="skirt_bowlegs"
+ label="legs skirt"
+ wearable="skirt"
+ edit_group="driven"
+ cross_wearable="true"
+ value_min="-1"
+ value_max="1"
+ value_default="0">
+ <param_morph />
+ </param>
+
+ <param
+ id="852"
+ group="1"
+ name="skirt_bigbutt"
+ wearable="skirt"
+ edit_group="driven"
+ cross_wearable="true"
+ label="bigbutt skirt"
+ label_min="less"
+ label_max="more"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="849"
+ group="1"
+ name="skirt_belly"
+ wearable="skirt"
+ edit_group="driven"
+ cross_wearable="true"
+ label="big belly skirt"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="850"
+ group="1"
+ wearable="skirt"
+ edit_group="driven"
+ cross_wearable="true"
+ name="skirt_saddlebags"
+ value_min="-.5"
+ value_max="3">
+ <param_morph />
+ </param>
+
+ <param
+ id="851"
+ group="1"
+ name="skirt_chubby"
+ wearable="skirt"
+ edit_group="driven"
+ cross_wearable="true"
+ label_min="less"
+ label_max="more"
+ value_min="0"
+ value_max="1"
+ value_default="0">
+ <param_morph />
+ </param>
+
+ <param
+ id="856"
+ group="1"
+ name="skirt_lovehandles"
+ wearable="skirt"
+ edit_group="driven"
+ cross_wearable="true"
+ label_min="less"
+ label_max="more"
+ value_min="-1"
+ value_max="2"
+ value_default="0">
+ <param_morph />
+ </param>
+
+ <!--
+ #############
+ # other morphs (not user controlled)
+ #############
+ -->
+ <param
+ id="857"
+ group="1"
+ name="skirt_male"
+ wearable="skirt"
+ edit_group="driven"
+ cross_wearable="true"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <!--
+ #############
+ # physics morphs (not user controlled)
+ #############
+ -->
+ <param
+ id="1203"
+ group="1"
+ name="Belly_Physics_Skirt_UpDown_Driven"
+ wearable="physics"
+ cross_wearable="true"
+ edit_group="driven"
+ value_default="0"
+ value_min="-1"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ </mesh>
+
+ <mesh
+ type="skirtMesh"
+ lod="1"
+ file_name="avatar_skirt_1.llm"
+ min_pixel_width="160"
+ reference="avatar_skirt.llm">
+ </mesh>
+
+ <mesh
+ type="skirtMesh"
+ lod="2"
+ file_name="avatar_skirt_2.llm"
+ min_pixel_width="80"
+ reference="avatar_skirt.llm">
+ </mesh>
+
+ <mesh
+ type="skirtMesh"
+ lod="3"
+ file_name="avatar_skirt_3.llm"
+ min_pixel_width="40"
+ reference="avatar_skirt.llm">
+ </mesh>
+
+ <mesh
+ type="skirtMesh"
+ lod="4"
+ file_name="avatar_skirt_4.llm"
+ min_pixel_width="0"
+ reference="avatar_skirt.llm">
+ </mesh>
+
+ <!-- =========================================================== -->
+ <global_color
+ name="skin_color">
+ <param
+ id="111"
+ group="0"
+ wearable="skin"
+ edit_group="skin_color"
+ edit_group_order="1"
+ name="Pigment"
+ show_simple="true"
+ label_min="Light"
+ label_max="Dark"
+ value_min="0"
+ value_max="1"
+ value_default=".5">
+ <param_color>
+ <value
+ color="252, 215, 200, 255" />
+
+ <value
+ color="240, 177, 112, 255" />
+
+ <value
+ color="90, 40, 16, 255" />
+
+ <value
+ color="29, 9, 6, 255" />
+ </param_color>
+ </param>
+
+ <param
+ id="110"
+ group="0"
+ wearable="skin"
+ edit_group="skin_color"
+ edit_group_order="2"
+ name="Red Skin"
+ label="Ruddiness"
+ label_min="Pale"
+ label_max="Ruddy"
+ value_min="0"
+ value_max="0.1">
+ <param_color
+ operation="blend">
+ <value
+ color="218, 41, 37, 255" />
+ </param_color>
+ </param>
+
+ <param
+ id="108"
+ group="0"
+ wearable="skin"
+ edit_group="skin_color"
+ edit_group_order="3"
+ name="Rainbow Color"
+ show_simple="true"
+ label_min="None"
+ label_max="Wild"
+ value_min="0"
+ value_max="1"
+ camera_elevation=".1"
+ camera_distance=".5">
+ <param_color>
+ <value
+ color=" 0, 0, 0, 255" />
+
+ <value
+ color="255, 0, 255, 255" />
+
+ <value
+ color="255, 0, 0, 255" />
+
+ <value
+ color="255, 255, 0, 255" />
+
+ <value
+ color=" 0, 255, 0, 255" />
+
+ <value
+ color=" 0, 255, 255, 255" />
+
+ <value
+ color=" 0, 0, 255, 255" />
+
+ <value
+ color="255, 0, 255, 255" />
+ </param_color>
+ </param>
+ </global_color>
+
+ <!-- =========================================================== -->
+ <global_color
+ name="hair_color">
+ <param
+ id="114"
+ group="0"
+ wearable="hair"
+ edit_group="hair_color"
+ edit_group_order="3"
+ name="Blonde Hair"
+ show_simple="true"
+ label_min="Black"
+ label_max="Blonde"
+ value_min="0"
+ value_max="1"
+ value_default=".5"
+ camera_elevation=".1"
+ camera_distance=".5">
+ <param_color>
+ <value
+ color="0, 0, 0, 255" />
+
+ <value
+ color="22, 6, 6, 255" />
+
+ <value
+ color="29, 9, 6, 255" />
+
+ <value
+ color="45, 21, 11, 255" />
+
+ <value
+ color="78, 39, 11, 255" />
+
+ <value
+ color="90, 53, 16, 255" />
+
+ <value
+ color="136, 92, 21, 255" />
+
+ <value
+ color="150, 106, 33, 255" />
+
+ <value
+ color="198, 156, 74, 255" />
+
+ <value
+ color="233, 192, 103, 255" />
+
+ <value
+ color="238, 205, 136, 255" />
+ </param_color>
+ </param>
+
+ <param
+ id="113"
+ group="0"
+ wearable="hair"
+ edit_group="hair_color"
+ edit_group_order="4"
+ name="Red Hair"
+ show_simple="true"
+ label_min="No Red"
+ label_max="Very Red"
+ value_min="0"
+ value_max="1"
+ camera_elevation=".1"
+ camera_distance=".5">
+ <param_color>
+ <value
+ color="0, 0, 0, 255" />
+
+ <value
+ color="118, 47, 19, 255" />
+ </param_color>
+ </param>
+
+ <param
+ id="115"
+ group="0"
+ wearable="hair"
+ edit_group="hair_color"
+ edit_group_order="1"
+ name="White Hair"
+ show_simple="true"
+ label_min="No White"
+ label_max="All White"
+ value_min="0"
+ value_max="1"
+ camera_elevation=".1"
+ camera_distance=".5">
+ <param_color>
+ <value
+ color="0, 0, 0, 255" />
+
+ <value
+ color="255, 255, 255, 255" />
+ </param_color>
+ </param>
+
+ <param
+ id="112"
+ group="0"
+ wearable="hair"
+ edit_group="hair_color"
+ edit_group_order="2"
+ name="Rainbow Color"
+ show_simple="true"
+ label_min="None"
+ label_max="Wild"
+ value_min="0"
+ value_max="1"
+ camera_elevation=".1"
+ camera_distance=".5">
+ <param_color>
+ <value
+ color=" 0, 0, 0, 255" />
+
+ <value
+ color="255, 0, 255, 255" />
+
+ <value
+ color="255, 0, 0, 255" />
+
+ <value
+ color="255, 255, 0, 255" />
+
+ <value
+ color=" 0, 255, 0, 255" />
+
+ <value
+ color=" 0, 255, 255, 255" />
+
+ <value
+ color=" 0, 0, 255, 255" />
+
+ <value
+ color="255, 0, 255, 255" />
+ </param_color>
+ </param>
+ </global_color>
+
+ <!-- =========================================================== -->
+ <global_color
+ name="eye_color">
+ <param
+ id="99"
+ group="0"
+ wearable="eyes"
+ edit_group="eyes"
+ edit_group_order="1"
+ name="Eye Color"
+ show_simple="true"
+ label_min="Natural"
+ label_max="Unnatural"
+ value_min="0"
+ value_max="1"
+ value_default="0"
+ camera_elevation=".1"
+ camera_distance=".3">
+ <!-- default to natural brown eyes-->
+ <param_color>
+ <value
+ color="50, 25, 5, 255" />
+
+ <!-- natural dark brown eyes-->
+ <value
+ color="109, 55, 15, 255" />
+
+ <!-- natural brown eyes-->
+ <value
+ color="150, 93, 49, 255" />
+
+ <!-- natural light brown eyes-->
+ <value
+ color="152, 118, 25, 255" />
+
+ <!--natural hazel eyes-->
+ <value
+ color="95, 179, 107, 255" />
+
+ <!--natural green eyes-->
+ <value
+ color="87, 192, 191, 255" />
+
+ <!--natural aqua eyes-->
+ <value
+ color="95, 172, 179, 255" />
+
+ <!--natural blue eyes-->
+ <value
+ color="128, 128, 128, 255" />
+
+ <!--natural grey eyes-->
+ <value
+ color="0, 0, 0, 255" />
+
+ <!--black eyes-->
+ <value
+ color="255, 255, 0, 255" />
+
+ <!--bright yellow eyes-->
+ <value
+ color=" 0, 255, 0, 255" />
+
+ <!-- bright green eyes-->
+ <value
+ color=" 0, 255, 255, 255" />
+
+ <!-- bright cyan eyes-->
+ <value
+ color=" 0, 0, 255, 255" />
+
+ <!--bright blue eyes-->
+ <value
+ color="255, 0, 255, 255" />
+
+ <!-- bright violet eyes-->
+ <value
+ color="255, 0, 0, 255" />
+
+ <!--bright red eyes-->
+ </param_color>
+ </param>
+
+ <param
+ id="98"
+ group="0"
+ wearable="eyes"
+ edit_group="eyes"
+ edit_group_order="2"
+ name="Eye Lightness"
+ show_simple="true"
+ label_min="Darker"
+ label_max="Lighter"
+ value_min="0"
+ value_max="1"
+ camera_elevation=".1"
+ camera_distance=".3">
+ <param_color>
+ <value
+ color="0, 0, 0, 0" />
+
+ <value
+ color="255, 255, 255, 255" />
+ </param_color>
+ </param>
+ </global_color>
+
+ <!-- =========================================================== -->
+ <layer_set
+ body_region="hair"
+ width="512"
+ height="512"
+ clear_alpha="false">
+ <layer
+ name="base"
+ global_color="hair_color"
+ write_all_channels="true">
+ <texture
+ local_texture="hair_grain" />
+ </layer>
+
+ <layer
+ name="hair texture alpha layer"
+ visibility_mask="TRUE">
+ <texture
+ local_texture="hair_grain" />
+ </layer>
+
+ <layer
+ name="hair alpha"
+ visibility_mask="TRUE">
+ <texture
+ local_texture="hair_alpha" />
+ </layer>
+
+ </layer_set>
+ <!-- =========================================================== -->
+
+ <layer_set
+ body_region="head"
+ width="512"
+ height="512">
+ <layer
+ name="head bump base"
+ fixed_color = "128,128,128,255"
+ render_pass="bump">
+ </layer>
+
+ <layer
+ name="head bump definition"
+ render_pass="bump">
+
+
+ <texture
+ tga_file="bump_head_base.tga"
+ file_is_mask="FALSE"/>
+
+ <param
+ id="873"
+ group="1"
+ wearable="skin"
+ edit_group="driven"
+ edit_group_order="12"
+ name="Bump base"
+ value_min="0"
+ value_max="1">
+ <param_alpha
+ domain="0" />
+ </param>
+ </layer>
+
+ <layer
+ name="base"
+ global_color="skin_color">
+ <texture
+ tga_file="head_skingrain.tga" />
+ </layer>
+
+ <layer
+ name="headcolor">
+ <texture
+ tga_file="head_color.tga" />
+ </layer>
+
+ <layer
+ name="shadow">
+ <texture
+ tga_file="head_shading_alpha.tga"
+ file_is_mask="TRUE" />
+
+ <param
+ id="158"
+ group="1"
+ wearable="skin"
+ name="Shading"
+ value_min="0"
+ value_max="1">
+ <param_color>
+ <value
+ color="0, 0, 0, 0" />
+
+ <value
+ color="0, 0, 0, 128" />
+ </param_color>
+ </param>
+ </layer>
+
+ <layer
+ name="highlight">
+ <texture
+ tga_file="head_highlights_alpha.tga"
+file_is_mask="TRUE" />
+
+
+ <param
+ id="159"
+ group="1"
+ name="Shading"
+ wearable="skin"
+ value_min="0"
+ value_max="1">
+ <param_color>
+ <value
+color="255, 255, 255, 0" />
+
+
+ <value
+ color="255, 255, 255, 64" />
+ </param_color>
+ </param>
+ </layer>
+ <layer
+ name="rosyface">
+ <texture
+ tga_file="rosyface_alpha.tga"
+ file_is_mask="true" />
+
+ <param
+ id="116"
+ group="0"
+ wearable="skin"
+ edit_group="skin_facedetail"
+ edit_group_order="4"
+ name="Rosy Complexion"
+ label_min="Less Rosy"
+ label_max="More Rosy"
+ value_min="0"
+ value_max="1"
+ camera_distance=".3"
+ camera_elevation=".07">
+ <param_color>
+ <value
+ color="198, 71, 71, 0" />
+
+ <value
+ color="198, 71, 71, 255" />
+ </param_color>
+ </param>
+ </layer>
+
+ <layer
+ name="lips">
+ <texture
+ tga_file="lips_mask.tga"
+ file_is_mask="true" />
+
+ <param
+ id="117"
+ group="0"
+ wearable="skin"
+ edit_group="skin_facedetail"
+ edit_group_order="5"
+ name="Lip Pinkness"
+ label_min="Darker"
+ label_max="Pinker"
+ value_min="0"
+ value_max="1"
+ camera_distance=".25">
+ <param_color>
+ <value
+ color="220, 115, 115, 0" />
+
+ <value
+ color="220, 115, 115, 128" />
+ </param_color>
+ </param>
+ </layer>
+
+ <layer
+ name="wrinkles_shading"
+ render_pass="bump"
+ fixed_color="0,0,0,100">
+ <param
+ id="118"
+ group="1"
+ wearable="skin"
+ name="Wrinkles"
+ value_min="0"
+ value_max="1">
+ <param_alpha
+ tga_file="bump_face_wrinkles.tga"
+ skip_if_zero="true"
+ domain="0.3" />
+ </param>
+ </layer>
+
+ <!--<layer
+ name="wrinkles_highlights"
+ fixed_color="255,255,255,64">
+ <param
+ id="128"
+ group="1"
+ name="Wrinkles"
+ value_min="0"
+ value_max="1">
+ <param_alpha
+ tga_file="head_wrinkles_highlights_alpha.tga"
+ skip_if_zero="true"
+ domain="0.3" />
+ </param>
+ </layer>-->
+ <layer
+ name="freckles"
+ fixed_color="120,47,20,128">
+ <param
+ id="165"
+ group="0"
+ wearable="skin"
+ edit_group="skin_facedetail"
+ edit_group_order="2"
+ name="Freckles"
+ label_min="Less"
+ label_max="More"
+ value_min="0"
+ value_max="1"
+ camera_distance=".3"
+camera_elevation=".07">
+ <param_alpha
+ tga_file="freckles_alpha.tga"
+ skip_if_zero="true"
+domain="0.5" />
+ </param>
+ </layer>
+ <layer
+name="eyebrowsbump"
+render_pass="bump">
+ <texture
+ tga_file="head_hair.tga"
+ file_is_mask="false" />
+
+ <param
+ id="1000"
+ group="1"
+ wearable="hair"
+ edit_group="driven"
+ name="Eyebrow Size Bump"
+ value_min="0"
+ value_max="1">
+ <param_alpha
+ tga_file="eyebrows_alpha.tga"
+ domain="0.1" />
+ </param>
+
+ <param
+ id="1002"
+ group="1"
+ wearable="hair"
+ edit_group="driven"
+ name="Eyebrow Density Bump"
+ value_min="0"
+ value_max="1">
+ <param_color>
+ <value
+ color="255,255,255,0" />
+
+ <value
+ color="255,255,255,255" />
+ </param_color>
+ </param>
+ </layer>
+
+ <layer
+ name="eyebrows"
+ global_color="hair_color">
+ <texture
+ tga_file="head_hair.tga"
+ file_is_mask="false" />
+
+ <param
+ id="1001"
+ group="1"
+ wearable="hair"
+ edit_group="hair_eyebrows"
+ name="Eyebrow Size"
+ show_simple="true"
+ value_min="0"
+ value_max="1"
+ value_default="0.5">
+ <param_alpha
+ tga_file="eyebrows_alpha.tga"
+ domain="0.1" />
+ </param>
+
+ <param
+ id="1003"
+ group="1"
+ wearable="hair"
+ edit_group="driven"
+ name="Eyebrow Density"
+ value_min="0"
+ value_max="1">
+ <param_color
+ operation="multiply">
+ <value
+ color="255,255,255,0" />
+
+ <value
+ color="255,255,255,255" />
+ </param_color>
+ </param>
+ </layer>
+
+ <layer
+ name="lipstick">
+ <param
+ id="700"
+ group="0"
+ wearable="skin"
+ edit_group="skin_makeup"
+ edit_group_order="2"
+ name="Lipstick Color"
+ label_min="Pink"
+ label_max="Black"
+ value_min="0"
+ value_max="1"
+ value_default=".25"
+ camera_distance=".25">
+ <param_color>
+ <value
+ color="245,161,177,200" />
+
+ <value
+ color="216,37,67,200" />
+
+ <value
+ color="178,48,76,200" />
+
+ <value
+ color="68,0,11,200" />
+
+ <value
+ color="252,207,184,200" />
+
+ <value
+ color="241,136,106,200" />
+
+ <value
+ color="208,110,85,200" />
+
+ <value
+ color="106,28,18,200" />
+
+ <value
+ color="58,26,49,200" />
+
+ <value
+ color="14,14,14,200" />
+ </param_color>
+ </param>
+
+ <param
+ id="701"
+ group="0"
+ wearable="skin"
+ edit_group="skin_makeup"
+ edit_group_order="1"
+ name="Lipstick"
+ label_min="No Lipstick"
+ label_max="More Lipstick"
+ value_min="0"
+ value_max=".9"
+ value_default="0.0"
+ camera_distance=".25">
+ <param_alpha
+ tga_file="lipstick_alpha.tga"
+ skip_if_zero="true"
+ domain="0.05" />
+ </param>
+ </layer>
+
+ <layer
+ name="lipgloss"
+ fixed_color="255,255,255,190">
+ <param
+ id="702"
+ name="Lipgloss"
+ label_min="No Lipgloss"
+ label_max="Glossy"
+ wearable="skin"
+ edit_group="skin_makeup"
+ edit_group_order="3"
+ group="0"
+ value_min="0"
+ value_max="1"
+ camera_distance=".25">
+ <param_alpha
+ tga_file="lipgloss_alpha.tga"
+ skip_if_zero="true"
+ domain="0.2" />
+ </param>
+ </layer>
+
+ <layer
+ name="blush">
+ <param
+ id="704"
+ group="0"
+ wearable="skin"
+ edit_group="skin_makeup"
+ edit_group_order="4"
+ name="Blush"
+ label_min="No Blush"
+ label_max="More Blush"
+ value_min="0"
+ value_max=".9"
+ value_default="0"
+ camera_distance=".3"
+ camera_elevation=".07"
+ camera_angle="20">
+ <param_alpha
+ tga_file="blush_alpha.tga"
+ skip_if_zero="true"
+ domain="0.3" />
+ </param>
+
+ <param
+ id="705"
+ group="0"
+ wearable="skin"
+ edit_group="skin_makeup"
+ edit_group_order="5"
+ name="Blush Color"
+ label_min="Pink"
+ label_max="Orange"
+ value_min="0"
+ value_max="1"
+ value_default=".5"
+ camera_distance=".3"
+ camera_elevation=".07"
+ camera_angle="20">
+ <param_color>
+ <value
+ color="253,162,193,200" />
+
+ <value
+ color="247,131,152,200" />
+
+ <value
+ color="213,122,140,200" />
+
+ <value
+ color="253,152,144,200" />
+
+ <value
+ color="236,138,103,200" />
+
+ <value
+ color="195,128,122,200" />
+
+ <value
+ color="148,103,100,200" />
+
+ <value
+ color="168,95,62,200" />
+ </param_color>
+ </param>
+
+ <param
+ id="711"
+ group="0"
+ wearable="skin"
+ edit_group="skin_makeup"
+ edit_group_order="6"
+ name="Blush Opacity"
+ label_min="Clear"
+ label_max="Opaque"
+ value_min="0"
+ value_max="1"
+ value_default=".5"
+ camera_distance=".3"
+ camera_elevation=".07"
+ camera_angle="20">
+ <param_color
+ operation="multiply">
+ <value
+ color="255,255,255,0" />
+
+ <value
+ color="255,255,255,255" />
+ </param_color>
+ </param>
+ </layer>
+
+ <layer
+ name="Outer Eye Shadow">
+ <param
+ id="708"
+ group="0"
+ wearable="skin"
+ edit_group="skin_makeup"
+ edit_group_order="11"
+ name="Out Shdw Color"
+ label_min="Light"
+ label_max="Dark"
+ value_min="0"
+ value_max="1"
+ camera_distance=".3"
+ camera_elevation=".14">
+ <param_color>
+ <value
+ color="252,247,246,255" />
+
+ <value
+ color="255,206,206,255" />
+
+ <value
+ color="233,135,149,255" />
+
+ <value
+ color="220,168,192,255" />
+
+ <value
+ color="228,203,232,255" />
+
+ <value
+ color="255,234,195,255" />
+
+ <value
+ color="230,157,101,255" />
+
+ <value
+ color="255,147,86,255" />
+
+ <value
+ color="228,110,89,255" />
+
+ <value
+ color="228,150,120,255" />
+
+ <value
+ color="223,227,213,255" />
+
+ <value
+ color="96,116,87,255" />
+
+ <value
+ color="88,143,107,255" />
+
+ <value
+ color="194,231,223,255" />
+
+ <value
+ color="207,227,234,255" />
+
+ <value
+ color="41,171,212,255" />
+
+ <value
+ color="180,137,130,255" />
+
+ <value
+ color="173,125,105,255" />
+
+ <value
+ color="144,95,98,255" />
+
+ <value
+ color="115,70,77,255" />
+
+ <value
+ color="155,78,47,255" />
+
+ <value
+ color="239,239,239,255" />
+
+ <value
+ color="194,194,194,255" />
+
+ <value
+ color="120,120,120,255" />
+
+ <value
+ color="10,10,10,255" />
+ </param_color>
+ </param>
+
+ <param
+ id="706"
+ group="0"
+ wearable="skin"
+ edit_group="skin_makeup"
+ edit_group_order="12"
+ name="Out Shdw Opacity"
+ label_min="Clear"
+ label_max="Opaque"
+ value_min=".2"
+ value_max="1"
+ value_default=".6"
+ camera_distance=".3"
+ camera_elevation=".14">
+ <param_color
+ operation="multiply">
+ <value
+ color="255,255,255,0" />
+
+ <value
+ color="255,255,255,255" />
+ </param_color>
+ </param>
+
+ <param
+ id="707"
+ group="0"
+ wearable="skin"
+ edit_group="skin_makeup"
+ edit_group_order="10"
+ name="Outer Shadow"
+ label_min="No Eyeshadow"
+ label_max="More Eyeshadow"
+ value_min="0"
+ value_max=".7"
+ camera_distance=".3"
+ camera_elevation=".14">
+ <param_alpha
+ tga_file="eyeshadow_outer_alpha.tga"
+ skip_if_zero="true"
+ domain="0.05" />
+ </param>
+ </layer>
+
+ <layer
+ name="Inner Eye Shadow">
+ <param
+ id="712"
+ group="0"
+ wearable="skin"
+ edit_group="skin_makeup"
+ edit_group_order="8"
+ name="In Shdw Color"
+ label_min="Light"
+ label_max="Dark"
+ value_min="0"
+ value_max="1"
+ camera_distance=".3"
+ camera_elevation=".14">
+ <param_color>
+ <value
+ color="252,247,246,255" />
+
+ <value
+ color="255,206,206,255" />
+
+ <value
+ color="233,135,149,255" />
+
+ <value
+ color="220,168,192,255" />
+
+ <value
+ color="228,203,232,255" />
+
+ <value
+ color="255,234,195,255" />
+
+ <value
+ color="230,157,101,255" />
+
+ <value
+ color="255,147,86,255" />
+
+ <value
+ color="228,110,89,255" />
+
+ <value
+ color="228,150,120,255" />
+
+ <value
+ color="223,227,213,255" />
+
+ <value
+ color="96,116,87,255" />
+
+ <value
+ color="88,143,107,255" />
+
+ <value
+ color="194,231,223,255" />
+
+ <value
+ color="207,227,234,255" />
+
+ <value
+ color="41,171,212,255" />
+
+ <value
+ color="180,137,130,255" />
+
+ <value
+ color="173,125,105,255" />
+
+ <value
+ color="144,95,98,255" />
+
+ <value
+ color="115,70,77,255" />
+
+ <value
+ color="155,78,47,255" />
+
+ <value
+ color="239,239,239,255" />
+
+ <value
+ color="194,194,194,255" />
+
+ <value
+ color="120,120,120,255" />
+
+ <value
+ color="10,10,10,255" />
+ </param_color>
+ </param>
+
+ <param
+ id="713"
+ group="0"
+ wearable="skin"
+ edit_group="skin_makeup"
+ edit_group_order="9"
+ name="In Shdw Opacity"
+ label_min="Clear"
+ label_max="Opaque"
+ value_min=".2"
+ value_max="1"
+ value_default=".7"
+ camera_distance=".3"
+ camera_elevation=".14">
+ <param_color
+ operation="multiply">
+ <value
+ color="255,255,255,0" />
+
+ <value
+ color="255,255,255,255" />
+ </param_color>
+ </param>
+
+ <param
+ id="709"
+ group="0"
+ wearable="skin"
+ edit_group="skin_makeup"
+ edit_group_order="7"
+ name="Inner Shadow"
+ label_min="No Eyeshadow"
+ label_max="More Eyeshadow"
+ value_min="0"
+ value_max="1"
+ value_default="0"
+ camera_distance=".3"
+ camera_elevation=".14">
+ <param_alpha
+ tga_file="eyeshadow_inner_alpha.tga"
+ skip_if_zero="true"
+ domain="0.2" />
+ </param>
+ </layer>
+
+ <layer
+ name="eyeliner"
+ fixed_color="0,0,0,200">
+ <param
+ id="703"
+ group="0"
+ wearable="skin"
+ edit_group="skin_makeup"
+ edit_group_order="13"
+ name="Eyeliner"
+ label_min="No Eyeliner"
+ label_max="Full Eyeliner"
+ value_min="0"
+ value_max="1"
+ value_default="0.0"
+ camera_distance=".3"
+ camera_elevation=".14">
+ <param_alpha
+ tga_file="eyeliner_alpha.tga"
+ skip_if_zero="true"
+ domain="0.1" />
+ </param>
+
+ <param
+ id="714"
+ group="0"
+ wearable="skin"
+ edit_group="skin_makeup"
+ edit_group_order="14"
+ name="Eyeliner Color"
+ label_min="Dark Green"
+ label_max="Black"
+ value_min="0"
+ value_max="1"
+ camera_distance=".3"
+ camera_elevation=".14">
+ <param_color>
+ <value
+ color="24,98,40,250" />
+
+ <!-- dark green -->
+ <value
+ color="9,100,127,250" />
+
+ <!-- lt.aqua blue -->
+ <value
+ color="61,93,134,250" />
+
+ <!-- aqua -->
+ <value
+ color="70,29,27,250" />
+
+ <!-- dark brown -->
+ <value
+ color="115,75,65,250" />
+
+ <!-- lt. brown blue -->
+ <value
+ color="100,100,100,250" />
+
+ <!-- grey -->
+ <value
+ color="91,80,74,250" />
+
+ <!-- grey/brown -->
+ <value
+ color="112,42,76,250" />
+
+ <!-- plum -->
+ <value
+ color="14,14,14,250" />
+
+ <!-- black -->
+ </param_color>
+ </param>
+ </layer>
+
+ <layer
+ name="facialhair bump"
+ render_pass="bump">
+ <texture
+ tga_file="head_hair.tga"
+ file_is_mask="false" />
+
+ <param
+ id="1004"
+ sex="male"
+ group="1"
+ wearable="hair"
+ edit_group="driven"
+ name="Sideburns bump"
+ value_min="0"
+ value_max="1">
+ <param_alpha
+ tga_file="facehair_sideburns_alpha.tga"
+ skip_if_zero="true"
+ domain="0.05" />
+ </param>
+
+ <param
+ id="1006"
+ sex="male"
+ group="1"
+ wearable="hair"
+ edit_group="driven"
+ name="Moustache bump"
+ value_min="0"
+ value_max="1">
+ <param_alpha
+ tga_file="facehair_moustache_alpha.tga"
+ skip_if_zero="true"
+ domain="0.05" />
+ </param>
+
+ <param
+ id="1008"
+ sex="male"
+ group="1"
+ wearable="hair"
+ edit_group="driven"
+ name="Soulpatch bump"
+ value_min="0"
+ value_max="1">
+ <param_alpha
+ tga_file="facehair_soulpatch_alpha.tga"
+ skip_if_zero="true"
+ domain="0.1" />
+ </param>
+
+ <param
+ id="1010"
+ sex="male"
+ group="1"
+ edit_group="driven"
+ wearable="hair"
+ name="Chin Curtains bump"
+ value_min="0"
+ value_max="1">
+ <param_alpha
+ tga_file="facehair_chincurtains_alpha.tga"
+ skip_if_zero="true"
+ domain="0.03" />
+ </param>
+
+ <param
+ id="1012"
+ group="1"
+ sex="male"
+ wearable="hair"
+ edit_group="driven"
+ name="5 O'Clock Shadow bump"
+ value_min="0"
+ value_max="1">
+ <param_color>
+ <value
+ color="255,255,255,255" />
+
+ <value
+ color="255,255,255,0" />
+ </param_color>
+ </param>
+ </layer>
+
+ <layer
+ name="facialhair"
+ global_color="hair_color">
+
+ <texture
+ tga_file="head_hair.tga"
+ file_is_mask="false" />
+
+ <param
+ id="1005"
+ sex="male"
+ group="1"
+ wearable="hair"
+ edit_group="driven"
+ name="Sideburns"
+ value_min="0"
+ value_max="1">
+ <param_alpha
+ tga_file="facehair_sideburns_alpha.tga"
+ skip_if_zero="true"
+ domain="0.05" />
+ </param>
+
+ <param
+ id="1007"
+ sex="male"
+ group="1"
+ wearable="hair"
+ edit_group="driven"
+ name="Moustache"
+ value_min="0"
+ value_max="1">
+ <param_alpha
+ tga_file="facehair_moustache_alpha.tga"
+ skip_if_zero="true"
+ domain="0.05" />
+ </param>
+
+ <param
+ id="1009"
+ sex="male"
+ group="1"
+ wearable="hair"
+ edit_group="driven"
+ name="Soulpatch"
+ value_min="0"
+ value_max="1">
+ <param_alpha
+ tga_file="facehair_soulpatch_alpha.tga"
+ skip_if_zero="true"
+ domain="0.1" />
+ </param>
+
+ <param
+ id="1011"
+ sex="male"
+ group="1"
+ wearable="hair"
+ edit_group="driven"
+ name="Chin Curtains"
+ value_min="0"
+ value_max="1">
+ <param_alpha
+ tga_file="facehair_chincurtains_alpha.tga"
+ skip_if_zero="true"
+ domain="0.03" />
+ </param>
+
+ <param
+ id="751"
+ group="1"
+ wearable="hair"
+ sex="male"
+ edit_group="hair_facial"
+ name="5 O'Clock Shadow"
+ label_min="Dense hair"
+ label_max="Shadow hair"
+ value_min="0"
+ value_max="1"
+ value_default="0.7"
+ camera_elevation=".1"
+ camera_distance=".3">
+ <param_color
+ operation="multiply">
+ <value
+ color="255,255,255,255" />
+
+ <value
+ color="255,255,255,30" />
+ </param_color>
+ </param>
+ </layer>
+
+ <layer
+ name="head_bodypaint">
+ <texture
+ local_texture="head_bodypaint" />
+ </layer>
+ <layer
+ name="eyelash alpha"
+ visibility_mask="TRUE">
+ <texture
+ tga_file="head_alpha.tga"
+ file_is_mask="TRUE" />
+ </layer>
+ <layer
+ name="head alpha"
+ visibility_mask="TRUE">
+ <texture
+ local_texture="head_alpha" />
+ </layer>
+ <layer
+ name="head_tattoo">
+ <texture
+ local_texture="head_tattoo" />
+ <param
+ id="1062"
+ group="1"
+ edit_group="colorpicker_driven"
+ wearable="tattoo"
+ name="tattoo_head_red"
+ value_min="0"
+ value_max="1"
+ value_default="1">
+ <param_color>
+ <value
+ color="0, 0, 0, 255" />
+
+ <value
+ color="255, 0, 0, 255" />
+ </param_color>
+ </param>
+
+ <param
+ id="1063"
+ group="1"
+ edit_group="colorpicker_driven"
+ wearable="tattoo"
+ name="tattoo_head_green"
+ value_min="0"
+ value_max="1"
+ value_default="1">
+ <param_color>
+ <value
+ color="0, 0, 0, 255" />
+
+ <value
+ color="0, 255, 0, 255" />
+ </param_color>
+ </param>
+
+ <param
+ id="1064"
+ group="1"
+ edit_group="colorpicker_driven"
+ wearable="tattoo"
+ name="tattoo_head_blue"
+ value_min="0"
+ value_max="1"
+ value_default="1">
+ <param_color>
+ <value
+ color="0, 0, 0, 255" />
+
+ <value
+ color="0, 0, 255, 255" />
+ </param_color>
+ </param>
+
+ </layer>
+
+
+ </layer_set>
+
+ <!-- =========================================================== -->
+ <layer_set
+ body_region="upper_body"
+ width="512"
+ height="512">
+ <layer
+ name="base_upperbody bump"
+ render_pass="bump"
+ fixed_color="128,128,128,255">
+ </layer>
+ <layer
+ name="upperbody bump definition"
+ render_pass="bump">
+ <texture
+ tga_file="bump_upperbody_base.tga"
+ file_is_mask="FALSE"/>
+
+ <param
+ id="874"
+ group="1"
+ wearable="skin"
+ edit_group="driven"
+ edit_group_order="20"
+ name="Bump upperdef"
+ value_min="0"
+ value_max="1">
+ <param_alpha
+ domain="0" />
+ </param>
+ </layer>
+
+ <layer
+ name="base"
+ global_color="skin_color">
+ <texture
+ tga_file="body_skingrain.tga" />
+ </layer>
+
+ <layer
+ name="nipples">
+ <texture
+ tga_file="upperbody_color.tga" />
+ </layer>
+
+ <layer
+ name="shadow">
+ <texture
+ tga_file="upperbody_shading_alpha.tga"
+ file_is_mask="TRUE" />
+
+ <param
+ id="125"
+ group="1"
+ name="Shading"
+ wearable="skin"
+ value_min="0"
+ value_max="1">
+ <param_color>
+ <value
+ color="0, 0, 0, 0" />
+
+ <value
+ color="0, 0, 0, 128" />
+ </param_color>
+ </param>
+ </layer>
+
+ <layer
+ name="highlight">
+ <texture
+ tga_file="upperbody_highlights_alpha.tga"
+ file_is_mask="TRUE" />
+
+ <param
+ id="126"
+ group="1"
+ wearable="skin"
+ name="Shading"
+ value_min="0"
+ value_max="1">
+ <param_color>
+ <value
+ color="255, 255, 255, 0" />
+
+ <value
+ color="255, 255, 255, 64" />
+ </param_color>
+ </param>
+ </layer>
+
+ <layer
+ name="upper_bodypaint">
+ <texture
+ local_texture="upper_bodypaint" />
+ </layer>
+
+ <layer
+ name="freckles upper"
+ fixed_color="120,47,20,128">
+ <param
+ id="776"
+ group="1"
+ name="freckles upper"
+ wearable="skin"
+ value_min="0"
+ value_max="1">
+ <param_alpha
+ tga_file="upperbodyfreckles_alpha.tga"
+ skip_if_zero="true"
+ domain="0.6" />
+ </param>
+ </layer>
+
+ <layer
+ name="upper_tattoo">
+ <texture
+ local_texture="upper_tattoo" />
+
+ <param
+ id="1065"
+ group="1"
+ edit_group="colorpicker_driven"
+ wearable="tattoo"
+ name="tattoo_upper_red"
+ value_min="0"
+ value_max="1"
+ value_default="1">
+ <param_color>
+ <value
+ color="0, 0, 0, 255" />
+
+ <value
+ color="255, 0, 0, 255" />
+ </param_color>
+ </param>
+
+ <param
+ id="1066"
+ group="1"
+ edit_group="colorpicker_driven"
+ wearable="tattoo"
+ name="tattoo_upper_green"
+ value_min="0"
+ value_max="1"
+ value_default="1">
+ <param_color>
+ <value
+ color="0, 0, 0, 255" />
+
+ <value
+ color="0, 255, 0, 255" />
+ </param_color>
+ </param>
+
+ <param
+ id="1067"
+ group="1"
+ edit_group="colorpicker_driven"
+ wearable="tattoo"
+ name="tattoo_upper_blue"
+ value_min="0"
+ value_max="1"
+ value_default="1">
+ <param_color>
+ <value
+ color="0, 0, 0, 255" />
+
+ <value
+ color="0, 0, 255, 255" />
+ </param_color>
+ </param>
+
+ </layer>
+
+
+ <layer
+ name="upper_undershirt bump"
+ render_pass="bump"
+ fixed_color="128,128,128,255">
+ <texture
+ local_texture="upper_undershirt"
+ local_texture_alpha_only="true" />
+
+ <param
+ id="1043"
+ group="1"
+ wearable="undershirt"
+ edit_group="driven"
+ name="Sleeve Length bump"
+ value_min=".01"
+ value_max="1"
+ value_default=".4">
+ <param_alpha
+ tga_file="shirt_sleeve_alpha.tga"
+ multiply_blend="false"
+ domain="0.01" />
+ </param>
+
+ <param
+ id="1045"
+ group="1"
+ wearable="undershirt"
+ edit_group="undershirt"
+ edit_group_order="2"
+ name="Bottom bump"
+ value_min="0"
+ value_max="1"
+ value_default=".8">
+ <param_alpha
+ tga_file="shirt_bottom_alpha.tga"
+ multiply_blend="true"
+ domain="0.05" />
+ </param>
+
+ <param
+ id="1047"
+ group="1"
+ wearable="undershirt"
+ edit_group="driven"
+ name="Collar Front bump"
+ value_min="0"
+ value_max="1"
+ value_default=".8">
+ <param_alpha
+ tga_file="shirt_collar_alpha.tga"
+ multiply_blend="true"
+ domain="0.05" />
+ </param>
+
+ <param
+ id="1049"
+ group="1"
+ wearable="undershirt"
+ edit_group="driven"
+ name="Collar Back bump"
+ value_min="0"
+ value_max="1"
+ value_default=".8">
+ <param_alpha
+ tga_file="shirt_collar_back_alpha.tga"
+ multiply_blend="true"
+ domain="0.05" />
+ </param>
+ </layer>
+
+ <layer
+ name="upper_undershirt">
+ <texture
+ local_texture="upper_undershirt" />
+
+ <param
+ id="821"
+ group="0"
+ wearable="undershirt"
+ edit_group="colorpicker"
+ name="undershirt_red"
+ value_min="0"
+ value_max="1"
+ value_default="1">
+ <param_color>
+ <value
+ color="0, 0, 0, 255" />
+
+ <value
+ color="255, 0, 0, 255" />
+ </param_color>
+ </param>
+
+ <param
+ id="822"
+ group="0"
+ wearable="undershirt"
+ edit_group="colorpicker"
+ name="undershirt_green"
+ value_min="0"
+ value_max="1"
+ value_default="1">
+ <param_color>
+ <value
+ color="0, 0, 0, 255" />
+
+ <value
+ color="0, 255, 0, 255" />
+ </param_color>
+ </param>
+
+ <param
+ id="823"
+ group="0"
+ wearable="undershirt"
+ edit_group="colorpicker"
+ name="undershirt_blue"
+ value_min="0"
+ value_max="1"
+ value_default="1">
+ <param_color>
+ <value
+ color="0, 0, 0, 255" />
+
+ <value
+ color="0, 0, 255, 255" />
+ </param_color>
+ </param>
+
+ <param
+ id="1042"
+ group="1"
+ wearable="undershirt"
+ edit_group="driven"
+ name="Sleeve Length"
+ value_min=".01"
+ value_max="1"
+ value_default=".4">
+ <param_alpha
+ tga_file="shirt_sleeve_alpha.tga"
+ multiply_blend="false"
+ domain="0.01" />
+ </param>
+
+ <param
+ id="1044"
+ group="1"
+ wearable="undershirt"
+ edit_group="driven"
+ name="Bottom"
+ value_min="0"
+ value_max="1"
+ value_default=".8">
+ <param_alpha
+ tga_file="shirt_bottom_alpha.tga"
+ multiply_blend="true"
+ domain="0.05" />
+ </param>
+
+ <param
+ id="1046"
+ group="1"
+ wearable="undershirt"
+ edit_group="driven"
+ name="Collar Front"
+ value_min="0"
+ value_max="1"
+ value_default=".8">
+ <param_alpha
+ tga_file="shirt_collar_alpha.tga"
+ multiply_blend="true"
+ domain="0.05" />
+ </param>
+
+ <param
+ id="1048"
+ group="1"
+ wearable="undershirt"
+ edit_group="driven"
+ name="Collar Back"
+ label_min="Low"
+ label_max="High"
+ value_min="0"
+ value_max="1"
+ value_default=".8">
+ <param_alpha
+ tga_file="shirt_collar_back_alpha.tga"
+ multiply_blend="true"
+ domain="0.05" />
+ </param>
+ </layer>
+
+ <layer
+ name="Nail Polish">
+ <param
+ id="710"
+ group="0"
+ wearable="skin"
+ edit_group="skin_makeup"
+ edit_group_order="15"
+ name="Nail Polish"
+ label_min="No Polish"
+ label_max="Painted Nails"
+ value_min="0"
+ value_max="1"
+ value_default="0.0"
+ camera_distance="1.6"
+ camera_elevation="-.4"
+ camera_angle="70">
+ <param_alpha
+ tga_file="nailpolish_alpha.tga"
+ skip_if_zero="true"
+ domain="0.1" />
+ </param>
+
+ <param
+ id="715"
+ group="0"
+ wearable="skin"
+ edit_group="skin_makeup"
+ edit_group_order="16"
+ name="Nail Polish Color"
+ label_min="Pink"
+ label_max="Black"
+ value_min="0"
+ value_max="1"
+ camera_distance="1.6"
+ camera_elevation="-.4"
+ camera_angle="70">
+ <param_color>
+ <value
+ color="255,187,200,255" />
+
+ <value
+ color="194,102,127,255" />
+
+ <value
+ color="227,34,99,255" />
+
+ <value
+ color="168,41,60,255" />
+
+ <value
+ color="97,28,59,255" />
+
+ <value
+ color="234,115,93,255" />
+
+ <value
+ color="142,58,47,255" />
+
+ <value
+ color="114,30,46,255" />
+
+ <value
+ color="14,14,14,255" />
+ </param_color>
+ </param>
+ </layer>
+
+ <layer
+ name="upper_gloves bump"
+ render_pass="bump"
+ fixed_color="128,128,128,255">
+ <texture
+ local_texture="upper_gloves"
+ local_texture_alpha_only="true" />
+
+ <param
+ id="1059"
+ group="1"
+ wearable="gloves"
+ edit_group="driven"
+ name="Glove Length bump"
+ value_min=".01"
+ value_max="1"
+ value_default=".8">
+ <param_alpha
+ tga_file="glove_length_alpha.tga"
+ domain="0.01" />
+ </param>
+
+ <param
+ id="1061"
+ group="1"
+ wearable="gloves"
+ edit_group="driven"
+ name="Glove Fingers bump"
+ value_min=".01"
+ value_max="1"
+ value_default="1">
+ <param_alpha
+ tga_file="gloves_fingers_alpha.tga"
+ multiply_blend="true"
+ domain="0.01" />
+ </param>
+ </layer>
+
+ <layer
+ name="upper_gloves">
+ <texture
+ local_texture="upper_gloves" />
+
+ <param
+ id="827"
+ group="0"
+ wearable="gloves"
+ edit_group="colorpicker"
+ name="gloves_red"
+ value_min="0"
+ value_max="1"
+ value_default="1">
+ <param_color>
+ <value
+ color="0, 0, 0, 255" />
+
+ <value
+ color="255, 0, 0, 255" />
+ </param_color>
+ </param>
+
+ <param
+ id="829"
+ group="0"
+ wearable="gloves"
+ edit_group="colorpicker"
+ name="gloves_green"
+ value_min="0"
+ value_max="1"
+ value_default="1">
+ <param_color>
+ <value
+ color="0, 0, 0, 255" />
+
+ <value
+ color="0, 255, 0, 255" />
+ </param_color>
+ </param>
+
+ <param
+ id="830"
+ group="0"
+ wearable="gloves"
+ edit_group="colorpicker"
+ name="gloves_blue"
+ value_min="0"
+ value_max="1"
+ value_default="1">
+ <param_color>
+ <value
+ color="0, 0, 0, 255" />
+
+ <value
+ color="0, 0, 255, 255" />
+ </param_color>
+ </param>
+
+ <param
+ id="1058"
+ group="1"
+ wearable="gloves"
+ edit_group="driven"
+ name="Glove Length"
+ value_min=".01"
+ value_max="1"
+ value_default=".8">
+ <param_alpha
+ tga_file="glove_length_alpha.tga"
+ domain="0.01" />
+ </param>
+
+ <param
+ id="1060"
+ group="1"
+ wearable="gloves"
+ edit_group="driven"
+ name="Glove Fingers"
+ value_min=".01"
+ value_max="1"
+ value_default="1">
+ <param_alpha
+ tga_file="gloves_fingers_alpha.tga"
+ multiply_blend="true"
+ domain="0.01" />
+ </param>
+ </layer>
+
+ <layer
+ name="upper_clothes_shadow">
+ <texture
+ local_texture="upper_shirt" />
+
+ <param
+ id="899"
+ group="1"
+ edit_group="driven"
+ wearable="shirt"
+ name="Upper Clothes Shading"
+ value_min="0"
+ value_max="1"
+ value_default="0">
+ <param_color>
+ <value
+ color="0, 0, 0, 0" />
+
+ <value
+ color="0, 0, 0, 80" />
+ </param_color>
+ </param>
+
+ <param
+ id="900"
+ group="1"
+ wearable="shirt"
+ edit_group="driven"
+ name="Sleeve Length Shadow"
+ value_min="0.02"
+ value_max=".87"
+ value_default="0.02">
+ <param_alpha
+ multiply_blend="false"
+ tga_file="shirt_sleeve_alpha.tga"
+ skip_if_zero="true"
+ domain="0.03" />
+ </param>
+
+ <param
+ id="901"
+ group="1"
+ wearable="shirt"
+ edit_group="driven"
+ name="Shirt Shadow Bottom"
+ value_min="0.02"
+ value_max="1">
+ <param_alpha
+ multiply_blend="true"
+ tga_file="shirt_bottom_alpha.tga"
+ skip_if_zero="true"
+ domain="0.05" />
+ </param>
+
+ <param
+ id="902"
+ group="1"
+ wearable="shirt"
+ edit_group="driven"
+ name="Collar Front Shadow Height"
+ value_min="0.02"
+ value_max="1">
+ <param_alpha
+ multiply_blend="true"
+ tga_file="shirt_collar_alpha.tga"
+ skip_if_zero="true"
+ domain="0.02" />
+ </param>
+
+ <param
+ id="903"
+ group="1"
+ wearable="shirt"
+ edit_group="driven"
+ name="Collar Back Shadow Height"
+ value_min="0.02"
+ value_max="1">
+ <param_alpha
+ multiply_blend="true"
+ tga_file="shirt_collar_back_alpha.tga"
+ skip_if_zero="true"
+ domain="0.02" />
+ </param>
+ </layer>
+
+ <layer
+ name="upper_shirt base bump"
+ render_pass="bump"
+ fixed_color="128,128,128,255">
+ <texture
+ local_texture="upper_shirt"
+ local_texture_alpha_only="true" />
+
+ <param
+ id="1029"
+ group="1"
+ wearable="shirt"
+ edit_group="driven"
+ name="Sleeve Length Cloth"
+ value_min="0"
+ value_max="0.85">
+ <param_alpha
+ multiply_blend="false"
+ tga_file="shirt_sleeve_alpha.tga"
+ domain="0.01" />
+ </param>
+
+ <param
+ id="1030"
+ group="1"
+ wearable="shirt"
+ edit_group="driven"
+ name="Shirt Bottom Cloth"
+ value_min="0"
+ value_max="1">
+ <param_alpha
+ multiply_blend="true"
+ tga_file="shirt_bottom_alpha.tga"
+ domain="0.05" />
+ </param>
+
+ <param
+ id="1031"
+ group="1"
+ wearable="shirt"
+ edit_group="driven"
+ name="Collar Front Height Cloth"
+ value_min="0"
+ value_max="1">
+ <param_alpha
+ multiply_blend="true"
+ tga_file="shirt_collar_alpha.tga"
+ domain="0.05" />
+ </param>
+
+ <param
+ id="1032"
+ group="1"
+ wearable="shirt"
+ edit_group="driven"
+ name="Collar Back Height Cloth"
+ value_min="0"
+ value_max="1">
+ <param_alpha
+ multiply_blend="true"
+ tga_file="shirt_collar_back_alpha.tga"
+ domain="0.05" />
+ </param>
+ </layer>
+
+ <layer
+ name="upper_clothes bump"
+ render_pass="bump">
+ <texture
+ tga_file="bump_shirt_wrinkles.tga" />
+
+ <texture
+ local_texture="upper_shirt"
+ local_texture_alpha_only="true" />
+
+ <param
+ id="868"
+ group="3"
+ wearable="shirt"
+ edit_group="shirt"
+ edit_group_order="8"
+ name="Shirt Wrinkles"
+ value_min="0"
+ value_max="1"
+ value_default="0">
+ <param_color>
+ <value
+ color="255, 255, 255, 0" />
+
+ <value
+ color="255, 255, 255, 255" />
+ </param_color>
+ </param>
+
+ <param
+ id="1013"
+ group="1"
+ wearable="shirt"
+ edit_group="driven"
+ name="Sleeve Length Cloth"
+ value_min="0"
+ value_max="0.85">
+ <param_alpha
+ multiply_blend="false"
+ tga_file="shirt_sleeve_alpha.tga"
+ domain="0.01" />
+ </param>
+
+ <param
+ id="1014"
+ group="1"
+ wearable="shirt"
+ edit_group="driven"
+ name="Shirt Bottom Cloth"
+ value_min="0"
+ value_max="1">
+ <param_alpha
+ multiply_blend="true"
+ tga_file="shirt_bottom_alpha.tga"
+ domain="0.05" />
+ </param>
+
+ <param
+ id="1015"
+ group="1"
+ wearable="shirt"
+ edit_group="driven"
+ name="Collar Front Height Cloth"
+ value_min="0"
+ value_max="1">
+ <param_alpha
+ multiply_blend="true"
+ tga_file="shirt_collar_alpha.tga"
+ domain="0.05" />
+ </param>
+
+ <param
+ id="1016"
+ group="1"
+ wearable="shirt"
+ edit_group="driven"
+ name="Collar Back Height Cloth"
+ value_min="0"
+ value_max="1">
+ <param_alpha
+ multiply_blend="true"
+ tga_file="shirt_collar_back_alpha.tga"
+ domain="0.05" />
+ </param>
+ </layer>
+
+ <layer
+ name="upper_clothes">
+ <texture
+ local_texture="upper_shirt" />
+
+ <param
+ id="803"
+ group="0"
+ wearable="shirt"
+ edit_group="colorpicker"
+ name="shirt_red"
+ value_min="0"
+ value_max="1"
+ value_default="1">
+ <param_color>
+ <value
+ color="0, 0, 0, 255" />
+
+ <value
+ color="255, 0, 0, 255" />
+ </param_color>
+ </param>
+
+ <param
+ id="804"
+ group="0"
+ wearable="shirt"
+ edit_group="colorpicker"
+ name="shirt_green"
+ value_min="0"
+ value_max="1"
+ value_default="1">
+ <param_color>
+ <value
+ color="0, 0, 0, 255" />
+
+ <value
+ color="0, 255, 0, 255" />
+ </param_color>
+ </param>
+
+ <param
+ id="805"
+ group="0"
+ wearable="shirt"
+ edit_group="colorpicker"
+ name="shirt_blue"
+ value_min="0"
+ value_max="1"
+ value_default="1">
+ <param_color>
+ <value
+ color="0, 0, 0, 255" />
+
+ <value
+ color="0, 0, 255, 255" />
+ </param_color>
+ </param>
+
+ <param
+ id="600"
+ group="1"
+ wearable="shirt"
+ edit_group="driven"
+ name="Sleeve Length Cloth"
+ value_min="0"
+ value_max="0.85"
+ value_default=".7">
+ <param_alpha
+ multiply_blend="false"
+ tga_file="shirt_sleeve_alpha.tga"
+ domain="0.01" />
+ </param>
+
+ <param
+ id="601"
+ group="1"
+ wearable="shirt"
+ edit_group="driven"
+ name="Shirt Bottom Cloth"
+ value_min="0"
+ value_max="1"
+ value_default=".8">
+ <param_alpha
+ multiply_blend="true"
+ tga_file="shirt_bottom_alpha.tga"
+ domain="0.05" />
+ </param>
+
+ <param
+ id="602"
+ group="1"
+ wearable="shirt"
+ edit_group="driven"
+ name="Collar Front Height Cloth"
+ value_min="0"
+ value_max="1"
+ value_default=".8">
+ <param_alpha
+ multiply_blend="true"
+ tga_file="shirt_collar_alpha.tga"
+ domain="0.05" />
+ </param>
+
+ <param
+ id="778"
+ group="1"
+ wearable="shirt"
+ edit_group="driven"
+ name="Collar Back Height Cloth"
+ value_min="0"
+ value_max="1"
+ value_default=".8">
+ <param_alpha
+ multiply_blend="true"
+ tga_file="shirt_collar_back_alpha.tga"
+ domain="0.05" />
+ </param>
+ </layer>
+
+ <layer
+ name="upper_jacket base bump"
+ render_pass="bump"
+ fixed_color="128,128,128,255">
+ <texture
+ local_texture="upper_jacket"
+ local_texture_alpha_only="true" />
+
+ <param
+ id="1039"
+ group="1"
+ wearable="jacket"
+ edit_group="driven"
+ edit_group_order="1"
+ name="Jacket Sleeve Length bump"
+ value_min="0"
+ value_max="1">
+ <param_alpha
+ multiply_blend="false"
+ tga_file="shirt_sleeve_alpha.tga"
+ domain="0.01" />
+ </param>
+
+ <param
+ id="1040"
+ group="1"
+ wearable="jacket"
+ edit_group="driven"
+ name="Jacket Collar Front bump"
+ value_min="0"
+ value_max="1">
+ <param_alpha
+ multiply_blend="true"
+ tga_file="shirt_collar_alpha.tga"
+ domain="0.05" />
+ </param>
+
+ <param
+ id="1041"
+ group="1"
+ wearable="jacket"
+ edit_group="driven"
+ edit_group_order="3.5"
+ name="Jacket Collar Back bump"
+ value_min="0"
+ value_max="1">
+ <param_alpha
+ multiply_blend="true"
+ tga_file="shirt_collar_back_alpha.tga"
+ domain="0.05" />
+ </param>
+
+ <param
+ id="1037"
+ group="1"
+ wearable="jacket"
+ edit_group="driven"
+ name="jacket bottom length upper bump"
+ value_min="0"
+ value_max="1">
+ <param_alpha
+ multiply_blend="true"
+ tga_file="jacket_length_upper_alpha.tga"
+ domain="0.01" />
+ </param>
+
+ <param
+ id="1038"
+ group="1"
+ wearable="jacket"
+ edit_group="driven"
+ name="jacket open upper bump"
+ value_min="0"
+ value_max="1">
+ <param_alpha
+ multiply_blend="true"
+ tga_file="jacket_open_upper_alpha.tga"
+ domain="0.01" />
+ </param>
+ </layer>
+
+ <layer
+ name="upper_jacket bump"
+ render_pass="bump">
+ <texture
+ tga_file="bump_shirt_wrinkles.tga" />
+
+ <texture
+ local_texture="upper_jacket"
+ local_texture_alpha_only="true" />
+
+
+ <param
+ id="875"
+ group="1"
+ wearable="jacket"
+ name="jacket upper Wrinkles"
+ value_min="0"
+ value_max="1"
+ value_default="0">
+ <param_color>
+ <value
+ color="255, 255, 255, 0" />
+
+ <value
+ color="255, 255, 255, 255" />
+ </param_color>
+ </param>
+
+ <param
+ id="1019"
+ group="1"
+ wearable="jacket"
+ edit_group="driven"
+ edit_group_order="1"
+ name="Jacket Sleeve Length bump"
+ value_min="0"
+ value_max="1">
+ <param_alpha
+ multiply_blend="false"
+ tga_file="shirt_sleeve_alpha.tga"
+ domain="0.01" />
+ </param>
+
+ <param
+ id="1021"
+ group="1"
+ wearable="jacket"
+ edit_group="driven"
+ name="Jacket Collar Front bump"
+ value_min="0"
+ value_max="1">
+ <param_alpha
+ multiply_blend="true"
+ tga_file="shirt_collar_alpha.tga"
+ domain="0.05" />
+ </param>
+
+ <param
+ id="1023"
+ group="1"
+ wearable="jacket"
+ edit_group="driven"
+ edit_group_order="3.5"
+ name="Jacket Collar Back bump"
+ value_min="0"
+ value_max="1">
+ <param_alpha
+ multiply_blend="true"
+ tga_file="shirt_collar_back_alpha.tga"
+ domain="0.05" />
+ </param>
+
+ <param
+ id="1025"
+ group="1"
+ wearable="jacket"
+ edit_group="driven"
+ name="jacket bottom length upper bump"
+ value_min="0"
+ value_max="1">
+ <param_alpha
+ multiply_blend="true"
+ tga_file="jacket_length_upper_alpha.tga"
+ domain="0.01" />
+ </param>
+
+ <param
+ id="1026"
+ group="1"
+ wearable="jacket"
+ edit_group="driven"
+ name="jacket open upper bump"
+ value_min="0"
+ value_max="1">
+ <param_alpha
+ multiply_blend="true"
+ tga_file="jacket_open_upper_alpha.tga"
+ domain="0.01" />
+ </param>
+ </layer>
+
+ <layer
+ name="upper_jacket">
+ <texture
+ local_texture="upper_jacket" />
+
+ <param
+ id="831"
+ group="1"
+ edit_group="colorpicker_driven"
+ wearable="jacket"
+ name="upper_jacket_red"
+ value_min="0"
+ value_max="1"
+ value_default="1">
+ <param_color>
+ <value
+ color="0, 0, 0, 255" />
+
+ <value
+ color="255, 0, 0, 255" />
+ </param_color>
+ </param>
+
+ <param
+ id="832"
+ group="1"
+ edit_group="colorpicker_driven"
+ wearable="jacket"
+ name="upper_jacket_green"
+ value_min="0"
+ value_max="1"
+ value_default="1">
+ <param_color>
+ <value
+ color="0, 0, 0, 255" />
+
+ <value
+ color="0, 255, 0, 255" />
+ </param_color>
+ </param>
+
+ <param
+ id="833"
+ group="1"
+ edit_group="colorpicker_driven"
+ wearable="jacket"
+ name="upper_jacket_blue"
+ value_min="0"
+ value_max="1"
+ value_default="1">
+ <param_color>
+ <value
+ color="0, 0, 0, 255" />
+
+ <value
+ color="0, 0, 255, 255" />
+ </param_color>
+ </param>
+
+ <param
+ id="1020"
+ group="1"
+ edit_group="driven"
+ wearable="jacket"
+ name="jacket Sleeve Length" value_min="0"
+ value_max="1">
+ <param_alpha
+ multiply_blend="false"
+ tga_file="shirt_sleeve_alpha.tga"
+ domain="0.01" />
+ </param>
+
+ <param
+ id="1022"
+ group="1"
+ wearable="jacket"
+ edit_group="driven"
+ name="jacket Collar Front"
+ value_min="0"
+ value_max="1">
+ <param_alpha
+ multiply_blend="true"
+ tga_file="shirt_collar_alpha.tga"
+ domain="0.05" />
+ </param>
+
+ <param
+ id="1024"
+ group="1"
+ wearable="jacket"
+ edit_group="driven"
+ edit_group_order="3.5"
+ name="jacket Collar Back"
+ value_min="0"
+ value_max="1">
+ <param_alpha
+ multiply_blend="true"
+ tga_file="shirt_collar_back_alpha.tga"
+ domain="0.05" />
+ </param>
+
+ <param
+ id="620"
+ group="1"
+ wearable="jacket"
+ edit_group="jacket"
+ name="bottom length upper"
+ label_min="hi cut"
+ label_max="low cut"
+ value_min="0"
+ value_max="1"
+ value_default=".8"
+ camera_distance="1.2"
+ camera_angle="30"
+ camera_elevation=".2">
+ <param_alpha
+ multiply_blend="true"
+ tga_file="jacket_length_upper_alpha.tga"
+ domain="0.01" />
+ </param>
+
+ <param
+ id="622"
+ group="1"
+ wearable="jacket"
+ edit_group="jacket"
+ name="open upper"
+ label_min="closed"
+ label_max="open"
+ value_min="0"
+ value_max="1"
+ value_default=".8"
+ camera_distance="1.2"
+ camera_angle="30"
+ camera_elevation=".2">
+ <param_alpha
+ multiply_blend="true"
+ tga_file="jacket_open_upper_alpha.tga"
+ domain="0.01" />
+ </param>
+ </layer>
+
+ <layer
+ name="upper alpha"
+ visibility_mask="TRUE">
+ <texture
+ local_texture="upper_alpha" />
+ </layer>
+
+ </layer_set>
+
+ <!-- =========================================================== -->
+ <layer_set
+ body_region="lower_body"
+ width="512"
+ height="512">
+ <layer
+ name="lower body bump base"
+ fixed_color = "128,128,128,255"
+ render_pass="bump">
+ </layer>
+ <layer
+ name="base_lowerbody bump"
+ render_pass="bump">
+ <texture
+ tga_file="bump_lowerbody_base.tga"
+ file_is_mask="FALSE" />
+
+ <param
+ id="878"
+ group="1"
+ wearable="skin"
+ edit_group="driven"
+ edit_group_order="20"
+ name="Bump upperdef"
+ value_min="0"
+ value_max="1">
+ <param_alpha
+ domain="0" />
+ </param>
+ </layer>
+
+ <layer
+ name="base"
+ global_color="skin_color">
+ <texture
+ tga_file="body_skingrain.tga" />
+ </layer>
+
+ <layer
+ name="shadow">
+ <texture
+ tga_file="lowerbody_shading_alpha.tga"
+ file_is_mask="TRUE" />
+
+ <param
+ id="160"
+ group="1"
+ name="Shading"
+ wearable="pants"
+ cross_wearable="true"
+ value_min="0"
+ value_max="1">
+ <param_color>
+ <value
+ color="0, 0, 0, 0" />
+
+ <value
+ color="0, 0, 0, 128" />
+ </param_color>
+ </param>
+ </layer>
+
+ <layer
+ name="highlight">
+ <texture
+ tga_file="lowerbody_highlights_alpha.tga"
+ file_is_mask="TRUE" />
+
+ <param
+ id="161"
+ group="1"
+ name="Shading"
+ wearable="skin"
+ value_min="0"
+ value_max="1">
+ <param_color>
+ <value
+ color="255, 255, 255, 0" />
+
+ <value
+ color="255, 255, 255, 64" />
+ </param_color>
+ </param>
+ </layer>
+
+ <layer
+ name="toenails">
+ <texture
+ tga_file="lowerbody_color.tga" />
+ </layer>
+
+ <layer
+ name="lower_bodypaint">
+ <texture
+ local_texture="lower_bodypaint" />
+ </layer>
+
+ <layer
+ name="freckles lower"
+ fixed_color="120,47,20,128">
+ <param
+ id="777"
+ group="1"
+ name="freckles lower"
+ wearable="skin"
+ value_min="0"
+ value_max="1">
+ <param_alpha
+ tga_file="bodyfreckles_alpha.tga"
+ skip_if_zero="true"
+ domain="0.6" />
+ </param>
+ </layer>
+
+ <layer
+ name="lower_tattoo">
+ <texture
+ local_texture="lower_tattoo" />
+
+ <param
+ id="1068"
+ group="1"
+ edit_group="colorpicker_driven"
+ wearable="tattoo"
+ name="tattoo_lower_red"
+ value_min="0"
+ value_max="1"
+ value_default="1">
+ <param_color>
+ <value
+ color="0, 0, 0, 255" />
+
+ <value
+ color="255, 0, 0, 255" />
+ </param_color>
+ </param>
+
+ <param
+ id="1069"
+ group="1"
+ edit_group="colorpicker_driven"
+ wearable="tattoo"
+ name="tattoo_lower_green"
+ value_min="0"
+ value_max="1"
+ value_default="1">
+ <param_color>
+ <value
+ color="0, 0, 0, 255" />
+
+ <value
+ color="0, 255, 0, 255" />
+ </param_color>
+ </param>
+
+ <param
+ id="1070"
+ group="1"
+ edit_group="colorpicker_driven"
+ wearable="tattoo"
+ name="tattoo_lower_blue"
+ value_min="0"
+ value_max="1"
+ value_default="1">
+ <param_color>
+ <value
+ color="0, 0, 0, 255" />
+
+ <value
+ color="0, 0, 255, 255" />
+ </param_color>
+ </param>
+
+ </layer>
+
+ <layer
+ name="lower_underpants bump"
+ render_pass="bump"
+ fixed_color="128,128,128,255">
+ <texture
+ local_texture="lower_underpants"
+ local_texture_alpha_only="true" />
+
+ <param
+ id="1055"
+ group="1"
+ wearable="underpants"
+ edit_group="underpants"
+ name="Pants Length"
+ value_min="0"
+ value_max="1"
+ value_default=".3">
+ <param_alpha
+ tga_file="pants_length_alpha.tga"
+ domain="0.01" />
+ </param>
+
+ <param
+ id="1057"
+ group="1"
+ wearable="underpants"
+ edit_group="underpants"
+ name="Pants Waist"
+ value_min="0"
+ value_max="1"
+ value_default=".8">
+ <param_alpha
+ tga_file="pants_waist_alpha.tga"
+ domain="0.05" />
+ </param>
+ </layer>
+
+ <layer
+ name="lower_underpants">
+ <texture
+ local_texture="lower_underpants" />
+
+ <param
+ id="824"
+ group="0"
+ wearable="underpants"
+ edit_group="colorpicker"
+ name="underpants_red"
+ value_min="0"
+ value_max="1"
+ value_default="1">
+ <param_color>
+ <value
+ color="0, 0, 0, 255" />
+
+ <value
+ color="255, 0, 0, 255" />
+ </param_color>
+ </param>
+
+ <param
+ id="825"
+ group="0"
+ wearable="underpants"
+ edit_group="colorpicker"
+ name="underpants_green"
+ value_min="0"
+ value_max="1"
+ value_default="1">
+ <param_color>
+ <value
+ color="0, 0, 0, 255" />
+
+ <value
+ color="0, 255, 0, 255" />
+ </param_color>
+ </param>
+
+ <param
+ id="826"
+ group="0"
+ wearable="underpants"
+ edit_group="colorpicker"
+ name="underpants_blue"
+ value_min="0"
+ value_max="1"
+ value_default="1">
+ <param_color>
+ <value
+ color="0, 0, 0, 255" />
+
+ <value
+ color="0, 0, 255, 255" />
+ </param_color>
+ </param>
+
+ <param
+ id="1054"
+ group="1"
+ wearable="underpants"
+ edit_group="driven"
+ name="Pants Length"
+ value_min="0"
+ value_max="1"
+ value_default=".3"
+ camera_distance="1.2"
+ camera_angle="30"
+ camera_elevation="-.3">
+ <param_alpha
+ tga_file="pants_length_alpha.tga"
+ domain="0.01" />
+ </param>
+
+ <param
+ id="1056"
+ group="1"
+ wearable="underpants"
+ edit_group="driven"
+ name="Pants Waist"
+ value_min="0"
+ value_max="1"
+ value_default=".8">
+ <param_alpha
+ tga_file="pants_waist_alpha.tga"
+ domain="0.05" />
+ </param>
+ </layer>
+
+ <layer
+ name="lower_socks bump"
+ render_pass="bump"
+ fixed_color="128,128,128,255">
+ <texture
+ local_texture="lower_socks"
+ local_texture_alpha_only="true" />
+
+ <param
+ id="1051"
+ group="1"
+ wearable="socks"
+ edit_group="driven"
+ name="Socks Length bump"
+ value_min="0"
+ value_max="1"
+ value_default="0.35">
+ <param_alpha
+ tga_file="shoe_height_alpha.tga"
+ domain="0.01" />
+ </param>
+ </layer>
+
+ <layer
+ name="lower_socks">
+ <texture
+ local_texture="lower_socks" />
+
+ <param
+ id="818"
+ group="0"
+ wearable="socks"
+ edit_group="colorpicker"
+ name="socks_red"
+ value_min="0"
+ value_max="1"
+ value_default="1">
+ <param_color>
+ <value
+ color="0, 0, 0, 255" />
+
+ <value
+ color="255, 0, 0, 255" />
+ </param_color>
+ </param>
+
+ <param
+ id="819"
+ group="0"
+ wearable="socks"
+ edit_group="colorpicker"
+ name="socks_green"
+ value_min="0"
+ value_max="1"
+ value_default="1">
+ <param_color>
+ <value
+ color="0, 0, 0, 255" />
+
+ <value
+ color="0, 255, 0, 255" />
+ </param_color>
+ </param>
+
+ <param
+ id="820"
+ group="0"
+ wearable="socks"
+ edit_group="colorpicker"
+ name="socks_blue"
+ value_min="0"
+ value_max="1"
+ value_default="1">
+ <param_color>
+ <value
+ color="0, 0, 0, 255" />
+
+ <value
+ color="0, 0, 255, 255" />
+ </param_color>
+ </param>
+
+ <param
+ id="1050"
+ group="1"
+ wearable="socks"
+ edit_group="driven"
+ name="Socks Length bump"
+ value_min="0"
+ value_max="1"
+ value_default="0.35">
+ <param_alpha
+ tga_file="shoe_height_alpha.tga"
+ domain="0.01" />
+ </param>
+ </layer>
+
+ <layer
+ name="lower_shoes bump"
+ render_pass="bump"
+ fixed_color="128,128,128,255">
+ <texture
+ local_texture="lower_shoes"
+ local_texture_alpha_only="true" />
+
+ <param
+ id="1053"
+ group="1"
+ wearable="shoes"
+ edit_group="driven"
+ name="Shoe Height bump"
+ value_min="0"
+ value_max="1"
+ value_default="0.1">
+ <param_alpha
+ tga_file="shoe_height_alpha.tga"
+ domain="0.01" />
+ </param>
+ </layer>
+
+ <layer
+ name="lower_shoes">
+ <texture
+ local_texture="lower_shoes" />
+
+ <param
+ id="812"
+ group="0"
+ wearable="shoes"
+ edit_group="colorpicker"
+ name="shoes_red"
+ value_min="0"
+ value_max="1"
+ value_default="1">
+ <param_color>
+ <value
+ color="0, 0, 0, 255" />
+
+ <value
+ color="255, 0, 0, 255" />
+ </param_color>
+ </param>
+
+ <param
+ id="813"
+ group="0"
+ wearable="shoes"
+ edit_group="colorpicker"
+ name="shoes_green"
+ value_min="0"
+ value_max="1"
+ value_default="1">
+ <param_color>
+ <value
+ color="0, 0, 0, 255" />
+
+ <value
+ color="0, 255, 0, 255" />
+ </param_color>
+ </param>
+
+ <param
+ id="817"
+ group="0"
+ wearable="shoes"
+ edit_group="colorpicker"
+ name="shoes_blue"
+ value_min="0"
+ value_max="1"
+ value_default="1">
+ <param_color>
+ <value
+ color="0, 0, 0, 255" />
+
+ <value
+ color="0, 0, 255, 255" />
+ </param_color>
+ </param>
+
+ <param
+ id="1052"
+ group="1"
+ wearable="shoes"
+ edit_group="driven"
+ name="Shoe Height"
+ value_min="0"
+ value_max="1"
+ value_default="0.1">
+ <param_alpha
+ tga_file="shoe_height_alpha.tga"
+ domain="0.01" />
+ </param>
+ </layer>
+
+ <layer
+ name="lower_clothes_shadow">
+ <texture
+ local_texture="lower_pants" />
+
+ <param
+ id="913"
+ group="1"
+ edit_group="driven"
+ wearable="pants"
+ name="Lower Clothes Shading"
+ value_min="0"
+ value_max="1"
+ value_default="0">
+ <param_color>
+ <value
+ color="0, 0, 0, 0" />
+
+ <value
+ color="0, 0, 0, 80" />
+ </param_color>
+ </param>
+
+ <param
+ id="914"
+ group="1"
+ edit_group="driven"
+ wearable="pants"
+ name="Waist Height Shadow"
+ value_min="0.02"
+ value_max="1">
+ <param_alpha
+ tga_file="pants_waist_alpha.tga"
+ skip_if_zero="true"
+ domain="0.04" />
+ </param>
+
+ <param
+ id="915"
+ group="1"
+ edit_group="driven"
+ wearable="pants"
+ name="Pants Length Shadow"
+ value_min="0.02"
+ value_max="1">
+ <param_alpha
+ tga_file="pants_length_alpha.tga"
+ skip_if_zero="true"
+ domain="0.03" />
+ </param>
+ </layer>
+
+ <layer
+ name="lower_pants base bump"
+ render_pass="bump"
+ fixed_color="128,128,128,255">
+ <texture
+ local_texture="lower_pants"
+ local_texture_alpha_only="true" />
+
+ <param
+ id="1035"
+ group="1"
+ edit_group="driven"
+ wearable="pants"
+ name="Waist Height Cloth"
+ value_min="0"
+ value_max="1">
+ <param_alpha
+ tga_file="pants_waist_alpha.tga"
+ domain="0.05" />
+ </param>
+
+ <param
+ id="1036"
+ group="1"
+ edit_group="driven"
+ wearable="pants"
+ name="Pants Length Cloth"
+ value_min="0"
+ value_max="1">
+ <param_alpha
+ tga_file="pants_length_alpha.tga"
+ domain="0.01" />
+ </param>
+ </layer>
+
+ <layer
+ name="lower_pants bump"
+ render_pass="bump">
+ <texture
+ tga_file="bump_pants_wrinkles.tga" />
+
+ <texture
+ local_texture="lower_pants"
+ local_texture_alpha_only="true" />
+
+ <param
+ id="869"
+ group="3"
+ wearable="pants"
+ edit_group="pants"
+ edit_group_order="6"
+ name="Pants Wrinkles"
+ value_min="0"
+ value_max="1"
+ value_default="0">
+ <param_color>
+ <value
+ color="255, 255, 255, 0" />
+
+ <value
+ color="255, 255, 255, 255" />
+ </param_color>
+ </param>
+
+ <param
+ id="1017"
+ group="1"
+ edit_group="driven"
+ wearable="pants"
+ name="Waist Height Cloth"
+ value_min="0"
+ value_max="1">
+ <param_alpha
+ tga_file="pants_waist_alpha.tga"
+ domain="0.05" />
+ </param>
+
+ <param
+ id="1018"
+ group="1"
+ edit_group="driven"
+ wearable="pants"
+ name="Pants Length Cloth"
+ value_min="0"
+ value_max="1">
+ <param_alpha
+ tga_file="pants_length_alpha.tga"
+ domain="0.01" />
+ </param>
+ </layer>
+
+ <layer
+ name="lower_pants">
+ <texture
+ local_texture="lower_pants" />
+
+ <param
+ id="806"
+ group="0"
+ wearable="pants"
+ edit_group="colorpicker"
+ name="pants_red"
+ value_min="0"
+ value_max="1"
+ value_default="1">
+ <param_color>
+ <value
+ color="0, 0, 0, 255" />
+
+ <value
+ color="255, 0, 0, 255" />
+ </param_color>
+ </param>
+
+ <param
+ id="807"
+ group="0"
+ wearable="pants"
+ edit_group="colorpicker"
+ name="pants_green"
+ value_min="0"
+ value_max="1"
+ value_default="1">
+ <param_color>
+ <value
+ color="0, 0, 0, 255" />
+
+ <value
+ color="0, 255, 0, 255" />
+ </param_color>
+ </param>
+
+ <param
+ id="808"
+ group="0"
+ wearable="pants"
+ edit_group="colorpicker"
+ name="pants_blue"
+ value_min="0"
+ value_max="1"
+ value_default="1">
+ <param_color>
+ <value
+ color="0, 0, 0, 255" />
+
+ <value
+ color="0, 0, 255, 255" />
+ </param_color>
+ </param>
+
+ <param
+ id="614"
+ group="1"
+ edit_group="driven"
+ wearable="pants"
+ name="Waist Height Cloth"
+ value_min="0"
+ value_max="1"
+ value_default=".8">
+ <param_alpha
+ tga_file="pants_waist_alpha.tga"
+ domain="0.05" />
+ </param>
+
+ <param
+ id="615"
+ group="1"
+ edit_group="driven"
+ wearable="pants"
+ name="Pants Length Cloth"
+ value_min="0"
+ value_max="1"
+ value_default=".8">
+ <param_alpha
+ tga_file="pants_length_alpha.tga"
+ domain="0.01" />
+ </param>
+ </layer>
+
+ <layer
+ name="lower_jacket base bump"
+ render_pass="bump"
+ fixed_color="128,128,128,255">
+ <texture
+ local_texture="lower_jacket"
+ local_texture_alpha_only="true" />
+
+ <param
+ id="1033"
+ group="1"
+ wearable="jacket"
+ edit_group="driven"
+ cross_wearable="true"
+ name="jacket bottom length lower bump"
+ value_min="0"
+ value_max="1">
+ <param_alpha
+ multiply_blend="false"
+ tga_file="jacket_length_lower_alpha.tga"
+ domain="0.01" />
+ </param>
+
+ <param
+ id="1034"
+ group="1"
+ wearable="jacket"
+ edit_group="driven"
+ name="jacket open lower bump"
+ value_min="0"
+ value_max="1">
+ <param_alpha
+ multiply_blend="true"
+ tga_file="jacket_open_lower_alpha.tga"
+ domain="0.01" />
+ </param>
+ </layer>
+
+ <layer
+ name="lower_jacket bump"
+ render_pass="bump">
+ <texture
+ tga_file="bump_pants_wrinkles.tga" />
+
+ <texture
+ local_texture="lower_jacket"
+ local_texture_alpha_only="true" />
+
+
+ <param
+ id="876"
+ group="1"
+ wearable="jacket"
+ name="jacket upper Wrinkles"
+ value_min="0"
+ value_max="1"
+ value_default="0">
+ <param_color>
+ <value
+ color="255, 255, 255, 0" />
+
+ <value
+ color="255, 255, 255, 255" />
+ </param_color>
+ </param>
+
+ <param
+ id="1027"
+ group="1"
+ wearable="jacket"
+ edit_group="driven"
+ name="jacket bottom length lower bump"
+ value_min="0"
+ value_max="1">
+ <param_alpha
+ multiply_blend="false"
+ tga_file="jacket_length_lower_alpha.tga"
+ domain="0.01" />
+ </param>
+
+ <param
+ id="1028"
+ group="1"
+ wearable="jacket"
+ edit_group="driven"
+ name="jacket open lower bump"
+ value_min="0"
+ value_max="1">
+ <param_alpha
+ multiply_blend="true"
+ tga_file="jacket_open_lower_alpha.tga"
+ domain="0.01" />
+ </param>
+ </layer>
+
+ <layer
+ name="lower_jacket">
+ <texture
+ local_texture="lower_jacket" />
+
+ <param
+ id="809"
+ group="1"
+ edit_group="colorpicker_driven"
+ wearable="jacket"
+ name="lower_jacket_red"
+ value_min="0"
+ value_max="1"
+ value_default="1">
+ <param_color>
+ <value
+ color="0, 0, 0, 255" />
+
+ <value
+ color="255, 0, 0, 255" />
+ </param_color>
+ </param>
+
+ <param
+ id="810"
+ group="1"
+ edit_group="colorpicker_driven"
+ wearable="jacket"
+ name="lower_jacket_green"
+ value_min="0"
+ value_max="1"
+ value_default="1">
+ <param_color>
+ <value
+ color="0, 0, 0, 255" />
+
+ <value
+ color="0, 255, 0, 255" />
+ </param_color>
+ </param>
+
+ <param
+ id="811"
+ group="1"
+ edit_group="colorpicker_driven"
+ wearable="jacket"
+ name="lower_jacket_blue"
+ value_min="0"
+ value_max="1"
+ value_default="1">
+ <param_color>
+ <value
+ color="0, 0, 0, 255" />
+
+ <value
+ color="0, 0, 255, 255" />
+ </param_color>
+ </param>
+
+ <param
+ id="621"
+ group="1"
+ wearable="jacket"
+ edit_group="jacket"
+ name="bottom length lower"
+ label_min="hi cut"
+ label_max="low cut"
+ value_min="0"
+ value_max="1"
+ value_default=".8"
+ camera_distance="1.2"
+ camera_angle="30"
+ camera_elevation=".2">
+ <param_alpha
+ multiply_blend="false"
+ tga_file="jacket_length_lower_alpha.tga"
+ domain="0.01" />
+ </param>
+
+ <param
+ id="623"
+ group="1"
+ wearable="jacket"
+ edit_group="jacket"
+ name="open lower"
+ label_min="open"
+ label_max="closed"
+ value_min="0"
+ value_max="1"
+ value_default=".8"
+ camera_distance="1.2"
+ camera_angle="30"
+ camera_elevation=".2">
+ <param_alpha
+ multiply_blend="true"
+ tga_file="jacket_open_lower_alpha.tga"
+ domain="0.01" />
+ </param>
+ </layer>
+
+ <layer
+ name="lower alpha"
+ visibility_mask="TRUE">
+ <texture
+ local_texture="lower_alpha" />
+ </layer>
+
+ </layer_set>
+
+ <!-- =========================================================== -->
+ <layer_set
+ body_region="eyes"
+ width="128"
+ height="128">
+ <layer
+ name="whites">
+ <texture
+ tga_file="eyewhite.tga" />
+ </layer>
+
+ <layer
+ name="iris"
+ global_color="eye_color">
+ <texture
+ local_texture="eyes_iris" />
+ </layer>
+
+ <layer
+ name="eyes alpha"
+ visibility_mask="TRUE">
+ <texture
+ local_texture="eyes_alpha" />
+ </layer>
+
+ </layer_set>
+
+ <!-- =========================================================== -->
+ <layer_set
+ body_region="skirt"
+ width="512"
+ height="512"
+ clear_alpha="false">
+ <layer
+ name="skirt_fabric"
+ write_all_channels="true">
+ <texture
+ local_texture="skirt" />
+
+ <param
+ id="921"
+ group="0"
+ wearable="skirt"
+ edit_group="colorpicker"
+ name="skirt_red"
+ value_min="0"
+ value_max="1"
+ value_default="1">
+ <param_color>
+ <value
+ color="0, 0, 0, 255" />
+
+ <value
+ color="255, 0, 0, 255" />
+ </param_color>
+ </param>
+
+ <param
+ id="922"
+ group="0"
+ wearable="skirt"
+ edit_group="colorpicker"
+ name="skirt_green"
+ value_min="0"
+ value_max="1"
+ value_default="1">
+ <param_color>
+ <value
+ color="0, 0, 0, 255" />
+
+ <value
+ color="0, 255, 0, 255" />
+ </param_color>
+ </param>
+
+ <param
+ id="923"
+ group="0"
+ wearable="skirt"
+ edit_group="colorpicker"
+ name="skirt_blue"
+ value_min="0"
+ value_max="1"
+ value_default="1">
+ <param_color>
+ <value
+ color="0, 0, 0, 255" />
+
+ <value
+ color="0, 0, 255, 255" />
+ </param_color>
+ </param>
+ </layer>
+
+ <layer
+ name="skirt_fabric_alpha">
+ <param
+ id="858"
+ group="0"
+ wearable="skirt"
+ edit_group="skirt"
+ edit_group_order="1"
+ name="Skirt Length"
+ show_simple="true"
+ label_min="Short"
+ label_max="Long"
+ value_min=".01"
+ value_max="1"
+ value_default=".4"
+ simple_percent_min="40"
+ simple_percent_max="100"
+ camera_distance="1.3"
+ camera_elevation="-.5"
+ camera_angle="30">
+ <param_alpha
+ tga_file="skirt_length_alpha.tga"
+ domain="0"
+ multiply_blend="true" />
+ </param>
+
+ <param
+ id="859"
+ group="0"
+ wearable="skirt"
+ edit_group="skirt"
+ edit_group_order="4"
+ name="Slit Front"
+ label_min="Open Front"
+ label_max="Closed Front"
+ value_min="0"
+ value_max="1"
+ value_default="1"
+ camera_distance="1.3"
+ camera_elevation="-.5"
+ camera_angle="30">
+ <param_alpha
+ tga_file="skirt_slit_front_alpha.tga"
+ multiply_blend="true"
+ domain="0" />
+ </param>
+
+ <param
+ id="860"
+ group="0"
+ wearable="skirt"
+ edit_group="skirt"
+ edit_group_order="5"
+ name="Slit Back"
+ label_min="Open Back"
+ label_max="Closed Back"
+ value_min="0"
+ value_max="1"
+ value_default="1"
+ camera_distance="1.3"
+ camera_elevation="-.5"
+ camera_angle="160">
+ <param_alpha
+ tga_file="skirt_slit_back_alpha.tga"
+ multiply_blend="true"
+ domain="0" />
+ </param>
+
+ <param
+ id="861"
+ group="0"
+ wearable="skirt"
+ edit_group="skirt"
+ edit_group_order="6"
+ name="Slit Left"
+ label_min="Open Left"
+ label_max="Closed Left"
+ value_min="0"
+ value_max="1"
+ value_default="1"
+ camera_distance="1.3"
+ camera_elevation="-.5"
+ camera_angle="30">
+ <param_alpha
+ tga_file="skirt_slit_left_alpha.tga"
+ multiply_blend="true"
+ domain="0" />
+ </param>
+
+ <param
+ id="862"
+ group="0"
+ wearable="skirt"
+ edit_group="skirt"
+ edit_group_order="7"
+ name="Slit Right"
+ label_min="Open Right"
+ label_max="Closed Right"
+ value_min="0"
+ value_max="1"
+ value_default="1"
+ camera_distance="1.3"
+ camera_elevation="-.5"
+ camera_angle="-30">
+ <param_alpha
+ tga_file="skirt_slit_right_alpha.tga"
+ multiply_blend="true"
+ domain="0" />
+ </param>
+ </layer>
+
+ </layer_set>
+
+ <!-- =========================================================== -->
+ <driver_parameters>
+
+ <param
+ id="828"
+ group="0"
+ name="Loose Upper Clothing"
+ label="Shirt Fit"
+ show_simple="true"
+ wearable="shirt"
+ edit_group="shirt"
+ edit_group_order="4"
+ label_min="Tight Shirt"
+ label_max="Loose Shirt"
+ value_min="0"
+ value_max="1"
+ camera_distance="1.2"
+ camera_angle="30"
+ camera_elevation=".2">
+ <param_driver>
+ <driven
+ id="628" />
+
+ <driven
+ id="899"
+ min1="0.1"
+ max1="0.5"
+ max2="1"
+ min2="1" />
+ </param_driver>
+ </param>
+
+ <param
+ id="816"
+ group="0"
+ name="Loose Lower Clothing"
+ label="Pants Fit"
+ show_simple="true"
+ wearable="pants"
+ edit_group="pants"
+ edit_group_order="2.5"
+ label_min="Tight Pants"
+ label_max="Loose Pants"
+ value_min="0"
+ value_max="1"
+ camera_distance="1.8"
+ camera_angle="30"
+ camera_elevation="-.3">
+ <param_driver>
+ <driven
+ id="516" />
+
+ <driven
+ id="913"
+ min1="0.1"
+ max1="0.5"
+ max2="1"
+ min2="1" />
+ </param_driver>
+ </param>
+
+ <param
+ id="814"
+ group="0"
+ wearable="pants"
+ edit_group="pants"
+ edit_group_order="2"
+ name="Waist Height"
+ label_min="Low"
+ label_max="High"
+ value_min="0"
+ value_max="1"
+ value_default="1"
+ camera_distance="1.2"
+ camera_angle="30"
+ camera_elevation="-.3">
+ <param_driver>
+ <driven
+ id="614" />
+
+ <driven
+ id="1017" />
+
+ <driven
+ id="1035" />
+
+ <driven
+ id="914"
+ min1="0"
+ max1=".98"
+ max2="1"
+ min2="1" />
+ </param_driver>
+ </param>
+
+ <param
+ id="815"
+ group="0"
+ wearable="pants"
+ edit_group="pants"
+ edit_group_order="1"
+ name="Pants Length"
+ show_simple="true"
+ label_min="Short"
+ label_max="Long"
+ value_min="0"
+ value_max="1"
+ value_default=".8"
+ simple_percent_min="20"
+ simple_percent_max="100"
+ camera_distance="1.8"
+ camera_angle="30"
+ camera_elevation="-.3">
+ <param_driver>
+ <driven
+ id="615"
+ min1="0"
+ max1=".9"
+ max2="1"
+ min2="1" />
+
+ <driven
+ id="1018"
+ min1="0"
+ max1=".9"
+ max2="1"
+ min2="1" />
+
+ <driven
+ id="1036"
+ min1="0"
+ max1=".9"
+ max2="1"
+ min2="1" />
+
+ <driven
+ id="793"
+ min1=".9"
+ max1="1"
+ max2="1"
+ min2="1" />
+
+ <driven
+ id="915"
+ min1="0"
+ max1=".882"
+ max2="1"
+ min2="1" />
+ </param_driver>
+ </param>
+
+ <param
+ id="800"
+ group="0"
+ wearable="shirt"
+ edit_group="shirt"
+ edit_group_order="1"
+ name="Sleeve Length"
+ show_simple="true"
+ label_min="Short"
+ label_max="Long"
+ value_min="0"
+ value_max="1"
+ value_default=".89"
+ simple_percent_min="15"
+ simple_percent_max="100"
+ camera_distance="1.2"
+ camera_angle="30"
+ camera_elevation=".2">
+ <param_driver>
+ <driven
+ id="600" />
+
+ <driven
+ id="1013" />
+
+ <driven
+ id="1029" />
+
+ <driven
+ id="900"
+ min1="0"
+ max1="1"
+ max2="1"
+ min2="1" />
+ </param_driver>
+ </param>
+
+ <param
+ id="801"
+ group="0"
+ wearable="shirt"
+ edit_group="shirt"
+ edit_group_order="2"
+ name="Shirt Bottom"
+ label_min="Short"
+ label_max="Long"
+ value_min="0"
+ value_max="1"
+ value_default="1"
+ camera_distance="1.2"
+ camera_angle="30"
+ camera_elevation=".2">
+ <param_driver>
+ <driven
+ id="601" />
+
+ <driven
+ id="1014" />
+
+ <driven
+ id="1030" />
+
+ <driven
+ id="901"
+ min1="0"
+ max1=".98"
+ max2="1"
+ min2="1" />
+ </param_driver>
+ </param>
+
+ <param
+ id="802"
+ group="0"
+ wearable="shirt"
+ edit_group="shirt"
+ edit_group_order="3"
+ name="Collar Front"
+ show_simple="true"
+ label_min="Low"
+ label_max="High"
+ value_min="0"
+ value_max="1"
+ value_default=".78"
+ simple_percent_min="40"
+ simple_percent_max="100"
+ camera_distance="1.2"
+ camera_angle="15"
+ camera_elevation=".2">
+ <param_driver>
+ <driven
+ id="602" />
+
+ <driven
+ id="1015" />
+
+ <driven
+ id="1031" />
+
+ <driven
+ id="902"
+ min1="0"
+ max1=".98"
+ max2="1"
+ min2="1" />
+ </param_driver>
+ </param>
+
+ <param
+ id="781"
+ group="0"
+ wearable="shirt"
+ edit_group="shirt"
+ edit_group_order="3.1"
+ name="Collar Back"
+ label_min="Low"
+ label_max="High"
+ value_min="0"
+ value_max="1"
+ value_default=".78"
+ camera_distance="1.2"
+ camera_angle="195"
+ camera_elevation=".2">
+ <param_driver>
+ <driven
+ id="778" />
+
+ <driven
+ id="1016" />
+
+ <driven
+ id="1032" />
+
+ <driven
+ id="903"
+ min1="0"
+ max1=".98"
+ max2="1"
+ min2="1" />
+ </param_driver>
+ </param>
+
+ <param
+ id="150"
+ group="0"
+ wearable="skin"
+ edit_group="skin_bodydetail"
+ name="Body Definition"
+ label_min="Less"
+ label_max="More"
+ value_min="0"
+ value_max="1"
+ value_default="0"
+ camera_distance="1.4"
+ camera_elevation="-.2">
+ <param_driver>
+ <driven
+ id="125" />
+
+ <driven
+ id="126" />
+
+ <driven
+ id="160" />
+
+ <driven
+ id="161" />
+
+ <driven
+ id="874" />
+
+ <driven
+ id="878" />
+
+ </param_driver>
+ </param>
+
+ <param
+ id="775"
+ group="0"
+ wearable="skin"
+ edit_group="skin_bodydetail"
+ name="Body Freckles"
+ label_min="Less Freckles"
+ label_max="More Freckles"
+ value_min="0"
+ value_max="1"
+ value_default="0"
+ camera_distance="1.4"
+ camera_elevation="-.2">
+ <param_driver>
+ <driven
+ id="776" />
+
+ <driven
+ id="777" />
+ </param_driver>
+ </param>
+
+ <param
+ id="162"
+ group="0"
+ wearable="skin"
+ edit_group="skin_facedetail"
+ edit_group_order="1"
+ name="Facial Definition"
+ label_min="Less"
+ label_max="More"
+ value_min="0"
+ value_max="1"
+ camera_distance=".3"
+ camera_elevation=".07"
+ value_default="0">
+ <param_driver>
+ <driven
+ id="158" />
+
+ <driven
+ id="159" />
+
+ <driven
+ id="873" />
+ </param_driver>
+ </param>
+
+ <param
+ id="163"
+ group="3"
+ wearable="skin"
+ edit_group="skin_facedetail"
+ edit_group_order="3"
+ name="Wrinkles"
+ label_min="Less"
+ label_max="More"
+ value_min="0"
+ value_max="1"
+ camera_distance=".3"
+ camera_elevation=".07"
+ value_default="0">
+ <param_driver>
+ <!--<driven
+ id="128" />-->
+ <driven
+ id="118" />
+ </param_driver>
+ </param>
+
+ <param
+ id="505"
+ group="0"
+ wearable="shape"
+ edit_group="shape_mouth"
+ edit_group_order="3"
+ name="Lip Thickness"
+ label_min="Thin Lips"
+ label_max="Fat Lips"
+ value_min="0"
+ value_max="1"
+ value_default=".5"
+ camera_distance=".3"
+ camera_elevation=".04"
+ camera_angle="20">
+ <param_driver>
+ <driven
+ id="26"
+ min1="0"
+ max1="0"
+ max2="0"
+ min2=".5" />
+
+ <driven
+ id="28"
+ min1=".5"
+ max1="1"
+ max2="1"
+ min2="1" />
+ </param_driver>
+ </param>
+
+ <param
+ id="799"
+ group="0"
+ wearable="shape"
+ edit_group="shape_mouth"
+ edit_group_order="3.2"
+ name="Lip Ratio"
+ label="Lip Ratio"
+ show_simple="true"
+ label_min="More Upper Lip"
+ label_max="More Lower Lip"
+ value_min="0"
+ value_max="1"
+ value_default=".5"
+ camera_distance=".3"
+ camera_elevation=".04"
+ camera_angle="20">
+ <param_driver>
+ <driven
+ id="797"
+ min1="0"
+ max1="0"
+ max2="0"
+ min2=".5" />
+
+ <driven
+ id="798"
+ min1=".5"
+ max1="1"
+ max2="1"
+ min2="1" />
+ </param_driver>
+ </param>
+
+ <param
+ id="155"
+ group="0"
+ wearable="shape"
+ edit_group="shape_mouth"
+ edit_group_order="1"
+ name="Lip Width"
+ label="Lip Width"
+ label_min="Narrow Lips"
+ label_max="Wide Lips"
+ show_simple="true"
+ value_min="-0.9"
+ value_max="1.3"
+ camera_distance=".3"
+ camera_elevation=".04"
+ value_default="0">
+ <param_driver>
+ <driven
+ id="29" />
+
+ <driven
+ id="30" />
+ </param_driver>
+ </param>
+
+ <param
+ id="196"
+ group="0"
+ wearable="shape"
+ edit_group="shape_eyes"
+ edit_group_order="2"
+ name="Eye Spacing"
+ label="Eye Spacing"
+ label_min="Close Set Eyes"
+ label_max="Far Set Eyes"
+ show_simple="true"
+ value_min="-2"
+ value_max="1"
+ value_default="0"
+ camera_elevation=".1"
+ camera_distance=".35"
+ camera_angle="5">
+ <param_driver>
+ <driven
+ id="194" />
+
+ <driven
+ id="195" />
+ </param_driver>
+ </param>
+
+ <param
+ id="769"
+ group="0"
+ wearable="shape"
+ edit_group="shape_eyes"
+ edit_group_order="4.5"
+ name="Eye Depth"
+ label_min="Sunken Eyes"
+ label_max="Bugged Eyes"
+ value_min="0"
+ value_max="1"
+ value_default=".5"
+ camera_elevation=".1"
+ camera_distance=".3"
+ camera_angle="75">
+ <param_driver>
+ <driven
+ id="767" />
+
+ <driven
+ id="768" />
+ </param_driver>
+ </param>
+
+ <param
+ id="198"
+ group="0"
+ wearable="shoes"
+ edit_group="shoes"
+ edit_group_order="2"
+ name="Heel Height"
+ label_min="Low Heels"
+ label_max="High Heels"
+ value_min="0"
+ value_max="1"
+ value_default="0"
+ camera_angle="45"
+ camera_distance=".8"
+ camera_elevation="-1">
+ <param_driver>
+ <driven
+ id="197" />
+
+ <driven
+ id="500" />
+ </param_driver>
+ </param>
+
+ <param
+ id="513"
+ group="0"
+ wearable="shoes"
+ edit_group="shoes"
+ edit_group_order="3"
+ name="Heel Shape"
+ label_min="Pointy Heels"
+ label_max="Thick Heels"
+ value_min="0"
+ value_max="1"
+ value_default=".5"
+ camera_angle="45"
+ camera_distance="1.5"
+ camera_elevation="-1">
+ <param_driver>
+ <driven
+ id="509"
+ min1="0"
+ max1="0"
+ max2="0"
+ min2=".5" />
+
+ <driven
+ id="510"
+ min1=".5"
+ max1="1"
+ max2="1"
+ min2="1" />
+ </param_driver>
+ </param>
+
+ <param
+ id="514"
+ group="0"
+ wearable="shoes"
+ edit_group="shoes"
+ edit_group_order="4"
+ name="Toe Shape"
+ label_min="Pointy"
+ label_max="Square"
+ value_min="0"
+ value_max="1"
+ value_default=".5"
+ camera_angle="5"
+ camera_distance=".8"
+ camera_elevation="-.8">
+ <param_driver>
+ <driven
+ id="511"
+ min1="0"
+ max1="0"
+ max2="0"
+ min2=".5" />
+
+ <driven
+ id="512"
+ min1=".5"
+ max1="1"
+ max2="1"
+ min2="1" />
+ </param_driver>
+ </param>
+
+ <param
+ id="503"
+ group="0"
+ wearable="shoes"
+ edit_group="shoes"
+ edit_group_order="6"
+ name="Platform Height"
+ label_min="Low Platforms"
+ label_max="High Platforms"
+ value_min="0"
+ value_max="1"
+ value_default="0"
+ camera_angle="45"
+ camera_distance=".5"
+ camera_elevation="-1">
+ <param_driver>
+ <driven
+ id="501" />
+
+ <driven
+ id="502" />
+ </param_driver>
+ </param>
+
+ <param
+ id="193"
+ group="0"
+ wearable="shape"
+ edit_group="shape_head"
+ edit_group_order="3"
+ name="Head Shape"
+ label="Head Shape"
+ label_min="More Square"
+ label_max="More Round"
+ show_simple="true"
+ value_min="0"
+ value_max="1"
+ value_default=".5"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="20">
+ <param_driver>
+ <driven
+ id="188"
+ min1="0"
+ max1="0"
+ max2="0"
+ min2=".5" />
+
+ <driven
+ id="642"
+ min1="0"
+ max1="0"
+ max2="0"
+ min2=".5" />
+
+ <driven
+ id="189"
+ min1=".5"
+ max1="1"
+ max2="1"
+ min2="1" />
+
+ <driven
+ id="643"
+ min1=".5"
+ max1="1"
+ max2="1"
+ min2="1" />
+ </param_driver>
+ </param>
+
+ <param
+ id="157"
+ group="0"
+ wearable="shape"
+ edit_group="shape_torso"
+ edit_group_order="13"
+ name="Belly Size"
+ label_min="Small"
+ label_max="Big"
+ value_min="0"
+ value_max="1"
+ value_default="0"
+ camera_distance="1.4"
+ camera_angle="30"
+ camera_elevation=".2">
+ <param_driver>
+ <driven
+ id="104" />
+
+ <driven
+ id="156" />
+
+ <driven
+ id="849" />
+ </param_driver>
+ </param>
+
+ <param
+ id="637"
+ group="0"
+ wearable="shape"
+ edit_group="shape_body"
+ edit_group_order="3"
+ name="Body Fat"
+ label_min="Less Body Fat"
+ label_max="More Body Fat"
+ value_min="0"
+ value_max="1"
+ value_default="0"
+ camera_distance="1.8">
+ <param_driver>
+ <driven
+ id="633" />
+
+ <driven
+ id="634" />
+
+ <driven
+ id="635" />
+
+ <driven
+ id="851" />
+ </param_driver>
+ </param>
+
+ <param
+ id="130"
+ group="0"
+ wearable="hair"
+ edit_group="hair_style"
+ edit_group_order="8"
+ name="Front Fringe"
+ label_min="Short"
+ label_max="Long"
+ value_min="0"
+ value_max="1"
+ value_default=".45"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="20">
+ <param_driver>
+ <driven
+ id="144"
+ min1="0"
+ max1="0"
+ max2="0"
+ min2=".5" />
+
+ <driven
+ id="145"
+ min1=".5"
+ max1="1"
+ max2="1"
+ min2="1" />
+ </param_driver>
+ </param>
+
+ <param
+ id="131"
+ group="0"
+ wearable="hair"
+ edit_group="hair_style"
+ edit_group_order="9"
+ name="Side Fringe"
+ label_min="Short"
+ label_max="Long"
+ value_min="0"
+ value_max="1"
+ value_default=".5"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="90">
+ <param_driver>
+ <driven
+ id="146"
+ min1="0"
+ max1="0"
+ max2="0"
+ min2=".5" />
+
+ <driven
+ id="147"
+ min1=".5"
+ max1="1"
+ max2="1"
+ min2="1" />
+ </param_driver>
+ </param>
+
+ <param
+ id="132"
+ group="0"
+ wearable="hair"
+ edit_group="hair_style"
+ edit_group_order="10"
+ name="Back Fringe"
+ label_min="Short"
+ label_max="Long"
+ value_min="0"
+ value_max="1"
+ value_default=".39"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="160">
+ <param_driver>
+ <driven
+ id="148"
+ min1="0"
+ max1="0"
+ max2="0"
+ min2=".5" />
+
+ <driven
+ id="149"
+ min1=".5"
+ max1="1"
+ max2="1"
+ min2="1" />
+ </param_driver>
+ </param>
+
+ <param
+ id="133"
+ group="0"
+ wearable="hair"
+ edit_group="hair_style"
+ edit_group_order="2"
+ name="Hair Front"
+ label_min="Short"
+ label_max="Long"
+ value_min="0"
+ value_max="1"
+ value_default=".25"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="20">
+ <param_driver>
+ <driven
+ id="172"
+ min1="0"
+ max1="0"
+ max2="0"
+ min2=".5" />
+
+ <driven
+ id="171"
+ min1=".5"
+ max1="1"
+ max2="1"
+ min2="1" />
+ </param_driver>
+ </param>
+
+ <param
+ id="134"
+ group="0"
+ wearable="hair"
+ edit_group="hair_style"
+ edit_group_order="3"
+ name="Hair Sides"
+ label_min="Short"
+ label_max="Long"
+ value_min="0"
+ value_max="1"
+ value_default=".5"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="90">
+ <param_driver>
+ <driven
+ id="174"
+ min1="0"
+ max1="0"
+ max2="0"
+ min2=".5" />
+
+ <driven
+ id="173"
+ min1=".5"
+ max1="1"
+ max2="1"
+ min2="1" />
+ </param_driver>
+ </param>
+
+ <param
+ id="135"
+ group="0"
+ wearable="hair"
+ edit_group="hair_style"
+ edit_group_order="4"
+ name="Hair Back"
+ show_simple="true"
+ label_min="Short"
+ label_max="Long"
+ value_min="0"
+ value_max="1"
+ value_default=".55"
+ camera_elevation="-.1"
+ camera_distance=".8"
+ camera_angle="160">
+ <param_driver>
+ <driven
+ id="176"
+ min1="0"
+ max1="0"
+ max2="0"
+ min2=".5" />
+
+ <driven
+ id="175"
+ min1=".5"
+ max1="1"
+ max2="1"
+ min2="1" />
+ </param_driver>
+ </param>
+
+ <param
+ id="136"
+ group="0"
+ wearable="hair"
+ edit_group="hair_style"
+ edit_group_order="11.5"
+ name="Hair Sweep"
+ label_min="Sweep Forward"
+ label_max="Sweep Back"
+ value_min="0"
+ value_max="1"
+ value_default=".5"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="90">
+ <param_driver>
+ <driven
+ id="179"
+ min1="0"
+ max1="0"
+ max2="0"
+ min2=".5" />
+
+ <driven
+ id="178"
+ min1=".5"
+ max1="1"
+ max2="1"
+ min2="1" />
+ </param_driver>
+ </param>
+
+ <param
+ id="137"
+ group="0"
+ wearable="hair"
+ edit_group="hair_style"
+ edit_group_order="16"
+ name="Hair Tilt"
+ label_min="Left"
+ label_max="Right"
+ value_min="0"
+ value_max="1"
+ value_default=".5"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="0">
+ <param_driver>
+ <driven
+ id="190"
+ min1="0"
+ max1="0"
+ max2="0"
+ min2=".5" />
+
+ <driven
+ id="191"
+ min1=".5"
+ max1="1"
+ max2="1"
+ min2="1" />
+ </param_driver>
+ </param>
+
+ <param
+ id="608"
+ group="0"
+ wearable="jacket"
+ edit_group="jacket"
+ edit_group_order="2"
+ name="bottom length lower"
+ label="Jacket Length"
+ label_min="Short"
+ label_max="Long"
+ value_min="0"
+ value_max="1"
+ value_default=".8"
+ camera_distance="1.4"
+ camera_angle="30"
+ camera_elevation=".2">
+ <param_driver>
+ <driven
+ id="620" />
+
+ <driven
+ id="1025" />
+
+ <driven
+ id="1037" />
+
+ <driven
+ id="621" />
+
+ <driven
+ id="1027" />
+
+ <driven
+ id="1033" />
+ </param_driver>
+ </param>
+
+ <param
+ id="609"
+ group="0"
+ wearable="jacket"
+ edit_group="jacket"
+ edit_group_order="4"
+ name="open jacket"
+ label="Open Front"
+ label_min="Open"
+ label_max="Closed"
+ value_min="0"
+ value_max="1"
+ value_default=".2"
+ camera_distance="1.4"
+ camera_angle="30"
+ camera_elevation=".2">
+ <param_driver>
+ <driven
+ id="622" />
+
+ <driven
+ id="1026" />
+
+ <driven
+ id="1038" />
+
+ <driven
+ id="623" />
+
+ <driven
+ id="1028" />
+
+ <driven
+ id="1034" />
+ </param_driver>
+ </param>
+
+ <param
+ id="105"
+ group="0"
+ sex="female"
+ wearable="shape"
+ edit_group="shape_torso"
+ edit_group_order="6"
+ name="Breast Size"
+ label_min="Small"
+ label_max="Large"
+ value_min="0"
+ value_max="1"
+ value_default=".5"
+ camera_elevation=".3"
+ camera_distance="1.2"
+ camera_angle="30">
+ <param_driver>
+ <driven
+ id="843"
+ min1="0"
+ max1="0"
+ max2="0"
+ min2=".01" />
+
+ <driven
+ id="627"
+ min1="0"
+ max1="0.01"
+ max2="0.01"
+ min2=".5" />
+
+ <driven
+ id="626"
+ min1=".5"
+ max1="1"
+ max2="1"
+ min2="1" />
+ </param_driver>
+ </param>
+
+ <param
+ id="629"
+ group="0"
+ wearable="shape"
+ edit_group="shape_head"
+ edit_group_order="6"
+ name="Forehead Angle"
+ label_min="More Vertical"
+ label_max="More Sloped"
+ value_min="0"
+ value_max="1"
+ value_default=".5"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="70">
+ <param_driver>
+ <driven
+ id="630"
+ min1="0"
+ max1="0"
+ max2="0"
+ min2=".5" />
+
+ <driven
+ id="644"
+ min1="0"
+ max1="0"
+ max2="0"
+ min2=".5" />
+
+ <driven
+ id="631"
+ min1=".5"
+ max1="1"
+ max2="1"
+ min2="1" />
+
+ <driven
+ id="645"
+ min1=".5"
+ max1="1"
+ max2="1"
+ min2="1" />
+ </param_driver>
+ </param>
+
+ <param
+ id="646"
+ group="0"
+ name="Egg_Head"
+ label="Egg Head"
+ wearable="shape"
+ edit_group="shape_head"
+ edit_group_order="4"
+ label_min="Chin Heavy"
+ label_max="Forehead Heavy"
+ show_simple="true"
+ value_min="-1.3"
+ value_max="1"
+ value_default="0"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="20">
+ <param_driver>
+ <driven
+ id="640" />
+
+ <driven
+ id="186" />
+ </param_driver>
+ </param>
+
+ <param
+ id="647"
+ group="0"
+ name="Squash_Stretch_Head"
+ label="Head Stretch"
+ wearable="shape"
+ edit_group="shape_head"
+ edit_group_order="2"
+ show_simple="true"
+ label_min="Squash Head"
+ label_max="Stretch Head"
+ value_min="-0.5"
+ value_max="1"
+ value_default="0"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="20">
+ <param_driver>
+ <driven
+ id="641" />
+
+ <driven
+ id="187" />
+ </param_driver>
+ </param>
+
+ <param
+ id="649"
+ group="0"
+ sex="female"
+ wearable="shape"
+ edit_group="shape_torso"
+ edit_group_order="1.1"
+ name="Torso Muscles"
+ label="Torso Muscles"
+ show_simple="true"
+ label_min="Less Muscular"
+ label_max="More Muscular"
+ value_min="0"
+ value_max="1"
+ value_default=".5"
+ camera_elevation=".1"
+ camera_distance="1"
+ camera_angle="15">
+ <param_driver>
+ <driven
+ id="648"
+ min1="0"
+ max1="0"
+ max2="0"
+ min2=".5" />
+
+ <driven
+ id="106"
+ min1=".5"
+ max1="1"
+ max2="1"
+ min2="1" />
+ </param_driver>
+ </param>
+
+ <param
+ id="678"
+ group="0"
+ sex="male"
+ wearable="shape"
+ edit_group="shape_torso"
+ edit_group_order="1"
+ name="Torso Muscles"
+ show_simple="true"
+ label_min="Less Muscular"
+ label_max="More Muscular"
+ value_min="0"
+ value_max="1"
+ value_default=".5"
+ camera_elevation=".1"
+ camera_distance="1.2"
+ camera_angle="0">
+ <param_driver>
+ <driven
+ id="677"
+ min1="0"
+ max1="0"
+ max2="0"
+ min2=".5" />
+
+ <driven
+ id="106"
+ min1=".5"
+ max1="1"
+ max2="1"
+ min2="1" />
+ </param_driver>
+ </param>
+
+ <param
+ id="652"
+ group="0"
+ wearable="shape"
+ edit_group="shape_legs"
+ edit_group_order="1"
+ name="Leg Muscles"
+ label_min="Less Muscular"
+ label_max="More Muscular"
+ show_simple="true"
+ value_min="0"
+ value_max="1"
+ value_default=".5"
+ camera_distance="1.3"
+ camera_elevation="-.5"
+ camera_angle="15">
+ <param_driver>
+ <driven
+ id="651"
+ min1="0"
+ max1="0"
+ max2="0"
+ min2=".5" />
+
+ <driven
+ id="152"
+ min1=".5"
+ max1="1"
+ max2="1"
+ min2="1" />
+ </param_driver>
+ </param>
+
+ <param
+ id="80"
+ name="male"
+ group="0"
+ edit_group="dummy"
+ wearable="shape"
+ value_min="0"
+ value_max="1">
+ <param_driver>
+ <driven
+ id="32" />
+
+ <driven
+ id="153" />
+
+ <driven
+ id="40" />
+
+ <driven
+ id="100" />
+
+ <driven
+ id="857" />
+ </param_driver>
+ </param>
+
+ <param
+ id="659"
+ group="0"
+ wearable="shape"
+ edit_group="shape_mouth"
+ edit_group_order="5"
+ name="Mouth Corner"
+ label_min="Corner Down"
+ label_max="Corner Up"
+ value_min="0"
+ value_max="1"
+ value_default=".5"
+ camera_elevation="0"
+ camera_distance=".28">
+ <param_driver>
+ <driven
+ id="658"
+ min1="0"
+ max1="0"
+ max2="0"
+ min2=".5" />
+
+ <driven
+ id="657"
+ min1=".5"
+ max1="1"
+ max2="1"
+ min2="1" />
+ </param_driver>
+ </param>
+
+ <param
+ id="662"
+ group="0"
+ wearable="shape"
+ edit_group="shape_head"
+ edit_group_order="5"
+ name="Face Shear"
+ label_min="Shear Right Up"
+ label_max="Shear Left Up"
+ value_min="0"
+ value_max="1"
+ value_default=".5"
+ camera_elevation=".1"
+ camera_distance=".5">
+ <param_driver>
+ <driven
+ id="660" />
+
+ <driven
+ id="661" />
+
+ <driven
+ id="774" />
+ </param_driver>
+ </param>
+
+ <param
+ id="773"
+ group="0"
+ wearable="shape"
+ edit_group="shape_head"
+ edit_group_order="4.5"
+ name="Head Length"
+ label_min="Flat Head"
+ label_max="Long Head"
+ value_min="0"
+ value_max="1"
+ value_default=".5"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="75">
+ <param_driver>
+ <driven
+ id="770" />
+
+ <driven
+ id="771" />
+
+ <driven
+ id="772" />
+ </param_driver>
+ </param>
+
+ <param
+ id="682"
+ group="0"
+ wearable="shape"
+ edit_group="shape_head"
+ edit_group_order="1"
+ name="Head Size"
+ label="Head Size"
+ label_min="Small Head"
+ label_max="Big Head"
+ show_simple="true"
+ value_min="0"
+ value_max="1"
+ value_default=".5"
+ camera_elevation=".1"
+ camera_distance=".5">
+ <param_driver>
+ <driven
+ id="679" />
+
+ <driven
+ id="694" />
+
+ <driven
+ id="680" />
+
+ <driven
+ id="681" />
+
+ <driven
+ id="655" />
+ </param_driver>
+ </param>
+
+ <param
+ id="690"
+ group="0"
+ wearable="shape"
+ edit_group="shape_eyes"
+ edit_group_order="1"
+ name="Eye Size"
+ label="Eye Size"
+ label_min="Beady Eyes"
+ label_max="Anime Eyes"
+ value_min="0"
+ value_max="1"
+ value_default=".5"
+ show_simple="true"
+ camera_elevation=".1"
+ camera_distance=".35">
+ <param_driver>
+ <driven
+ id="686" />
+
+ <driven
+ id="687" />
+
+ <driven
+ id="695" />
+
+ <driven
+ id="688" />
+
+ <driven
+ id="691" />
+
+ <driven
+ id="689" />
+ </param_driver>
+ </param>
+
+ <param
+ id="752"
+ group="0"
+ sex="male"
+ wearable="hair"
+ edit_group="hair_facial"
+ edit_group_order="1"
+ name="Hair Thickness"
+ label_min="5 O'Clock Shadow"
+ label_max="Bushy Hair"
+ value_min="0"
+ value_max="1"
+ value_default=".5"
+ camera_elevation="0"
+ camera_distance=".28">
+ <param_driver>
+ <driven
+ id="751"
+ min1="0"
+ max1="0"
+ max2="0"
+ min2=".2" />
+
+ <driven
+ id="1012"
+ min1="0"
+ max1="0"
+ max2=".2"
+ min2=".6" />
+
+ <driven
+ id="400"
+ min1=".2"
+ max1="1"
+ max2="1"
+ min2="1" />
+ </param_driver>
+ </param>
+
+ <param
+ id="763"
+ group="0"
+ wearable="hair"
+ edit_group="hair_style"
+ edit_group_order="1"
+ name="Hair Volume"
+ show_simple="true"
+ label_min="Less Volume"
+ label_max="More Volume"
+ value_min="0"
+ value_max="1"
+ value_default=".55"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="20">
+ <param_driver>
+ <driven
+ id="761"
+ min1="0"
+ max1="0"
+ max2="0"
+ min2=".5" />
+
+ <driven
+ id="180"
+ min1=".5"
+ max1="1"
+ max2="1"
+ min2="1" />
+ </param_driver>
+ </param>
+
+ <param
+ id="834"
+ group="0"
+ wearable="jacket"
+ edit_group="colorpicker"
+ name="jacket_red"
+ value_min="0"
+ value_max="1"
+ value_default="1">
+ <param_driver>
+ <driven
+ id="809"
+ min1="0"
+ max1="1"
+ max2="1"
+ min2="1" />
+
+ <driven
+ id="831"
+ min1="0"
+ max1="1"
+ max2="1"
+ min2="1" />
+ </param_driver>
+ </param>
+
+ <param
+ id="835"
+ group="0"
+ wearable="jacket"
+ edit_group="colorpicker"
+ name="jacket_green"
+ value_min="0"
+ value_max="1"
+ value_default="1">
+ <param_driver>
+ <driven
+ id="810"
+ min1="0"
+ max1="1"
+ max2="1"
+ min2="1" />
+
+ <driven
+ id="832"
+ min1="0"
+ max1="1"
+ max2="1"
+ min2="1" />
+ </param_driver>
+ </param>
+
+ <param
+ id="836"
+ group="0"
+ wearable="jacket"
+ edit_group="colorpicker"
+ name="jacket_blue"
+ value_min="0"
+ value_max="1"
+ value_default="1">
+ <param_driver>
+ <driven
+ id="811"
+ min1="0"
+ max1="1"
+ max2="1"
+ min2="1" />
+
+ <driven
+ id="833"
+ min1="0"
+ max1="1"
+ max2="1"
+ min2="1" />
+ </param_driver>
+ </param>
+
+ <param
+ id="785"
+ group="0"
+ wearable="hair"
+ edit_group="hair_style"
+ edit_group_order="14.6"
+ name="Pigtails"
+ show_simple="true"
+ label_min="Short Pigtails"
+ label_max="Long Pigtails"
+ value_min="0"
+ value_max="1"
+ value_default="0"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="15">
+ <param_driver>
+ <driven
+ id="782"
+ min1="0"
+ max1=".10"
+ max2=".10"
+ min2=".5" />
+
+ <driven
+ id="783"
+ min1=".10"
+ max1=".5"
+ max2=".5"
+ min2=".75" />
+
+ <driven
+ id="790"
+ min1=".5"
+ max1=".75"
+ max2=".75"
+ min2="1" />
+
+ <driven
+ id="784"
+ min1=".75"
+ max1="1"
+ max2="1"
+ min2="1" />
+ </param_driver>
+ </param>
+
+ <param
+ id="789"
+ group="0"
+ wearable="hair"
+ edit_group="hair_style"
+ edit_group_order="14.7"
+ name="Ponytail"
+ label_min="Short Ponytail"
+ label_max="Long Ponytail"
+ value_min="0"
+ value_max="1"
+ value_default="0"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="180">
+ <param_driver>
+ <driven
+ id="786"
+ min1="0"
+ max1=".10"
+ max2=".10"
+ min2=".66" />
+
+ <driven
+ id="787"
+ min1=".10"
+ max1=".66"
+ max2=".66"
+ min2="1" />
+
+ <driven
+ id="788"
+ min1=".66"
+ max1="1"
+ max2="1"
+ min2="1" />
+ </param_driver>
+ </param>
+
+ <param
+ id="795"
+ group="0"
+ name="Butt Size"
+ label="Butt Size"
+ wearable="shape"
+ edit_group="shape_legs"
+ edit_group_order="4"
+ label_min="Flat Butt"
+ label_max="Big Butt"
+ value_min="0"
+ value_max="1"
+ value_default=".25"
+ camera_angle="180"
+ camera_distance=".6">
+ <param_driver>
+ <driven
+ id="867"
+ min1="0"
+ max1="0"
+ max2="0"
+ min2=".3" />
+
+ <driven
+ id="794"
+ min1="0"
+ max1="0"
+ max2="0"
+ min2=".3" />
+
+ <driven
+ id="151"
+ min1=".3"
+ max1="1"
+ max2="1"
+ min2="1" />
+
+ <driven
+ id="852"
+ min1=".3"
+ max1="1"
+ max2="1"
+ min2="1" />
+ </param_driver>
+ </param>
+
+ <param
+ id="841"
+ group="0"
+ name="Bowed_Legs"
+ label="Knee Angle"
+ wearable="shape"
+ edit_group_order="5.5"
+ edit_group="shape_legs"
+ label_min="Knock Kneed"
+ label_max="Bow Legged"
+ value_min="-1"
+ value_max="1"
+ value_default="0"
+ camera_distance="1.3"
+ camera_elevation="-.5">
+ <param_driver>
+ <driven
+ id="853" />
+
+ <driven
+ id="847" />
+ </param_driver>
+ </param>
+
+ <param
+ id="753"
+ group="0"
+ name="Saddlebags"
+ label="Saddle Bags"
+ wearable="shape"
+ edit_group="shape_legs"
+ edit_group_order="5"
+ label_min="Less Saddle"
+ label_max="More Saddle"
+ value_min="-0.5"
+ value_max="3"
+ value_default="0"
+ camera_angle="0"
+ camera_distance="1.2">
+ <param_driver>
+ <driven
+ id="850" />
+
+ <driven
+ id="854" />
+ </param_driver>
+ </param>
+
+ <param
+ id="676"
+ group="0"
+ name="Love_Handles"
+ label="Love Handles"
+ wearable="shape"
+ edit_group="shape_torso"
+ edit_group_order="12"
+ label_min="Less Love"
+ label_max="More Love"
+ value_min="-1"
+ value_max="2"
+ value_default="0"
+ camera_elevation=".3"
+ camera_distance=".9">
+ <param_driver>
+ <driven
+ id="855" />
+
+ <driven
+ id="856" />
+ </param_driver>
+ </param>
+
+ <param
+ id="863"
+ group="0"
+ name="skirt_looseness"
+ label="Skirt Fit"
+ show_simple="true"
+ clothing_morph="true"
+ wearable="skirt"
+ edit_group_order="2"
+ edit_group="skirt"
+ label_min="Tight Skirt"
+ label_max="Poofy Skirt"
+ value_min="0"
+ value_max="1"
+ value_default=".333"
+ camera_distance="1.3"
+ camera_elevation="-.5">
+ <param_driver>
+ <driven
+ id="866"
+ min1="0"
+ max1="0"
+ max2="0"
+ min2=".2" />
+
+ <driven
+ id="846"
+ min1="0"
+ max1=".5"
+ max2=".5"
+ min2="1" />
+
+ <driven
+ id="845"
+ min1=".5"
+ max1="1"
+ max2="1"
+ min2="1" />
+ </param_driver>
+ </param>
+
+ <param
+ id="119"
+ group="0"
+ wearable="hair"
+ edit_group="hair_eyebrows"
+ edit_group_order="1"
+ name="Eyebrow Size"
+ show_simple="true"
+ label_min="Thin Eyebrows"
+ label_max="Bushy Eyebrows"
+ value_min="0"
+ value_max="1"
+ value_default="0.5"
+ camera_elevation=".1"
+ camera_distance=".3">
+ <param_driver>
+ <driven
+ id="1000" />
+
+ <driven
+ id="1001" />
+ </param_driver>
+ </param>
+
+ <param
+ id="750"
+ group="0"
+ wearable="hair"
+ edit_group="hair_eyebrows"
+ edit_group_order="2"
+ name="Eyebrow Density"
+ label_min="Sparse"
+ label_max="Dense"
+ value_min="0"
+ value_max="1"
+ value_default="0.7"
+ camera_elevation=".1"
+ camera_distance=".3">
+ <param_driver>
+ <driven
+ id="1002" />
+
+ <driven
+ id="1003" />
+ </param_driver>
+ </param>
+
+ <param
+ id="166"
+ sex="male"
+ group="0"
+ wearable="hair"
+ edit_group="hair_facial"
+ edit_group_order="2"
+ name="Sideburns"
+ show_simple="true"
+ label_min="Short Sideburns"
+ label_max="Mutton Chops"
+ value_min="0"
+ value_max="1"
+ value_default="0.0"
+ camera_elevation=".1"
+ camera_distance=".3"
+ camera_angle="30">
+ <param_driver>
+ <driven
+ id="1004" />
+
+ <driven
+ id="1005" />
+ </param_driver>
+ </param>
+
+ <param
+ id="167"
+ sex="male"
+ group="0"
+ wearable="hair"
+ edit_group="hair_facial"
+ edit_group_order="3"
+ name="Moustache"
+ show_simple="true"
+ label_min="Chaplin"
+ label_max="Handlebars"
+ value_min="0"
+ value_max="1"
+ value_default="0.0"
+ camera_elevation=".1"
+ camera_distance=".3"
+ camera_angle="30">
+ <param_driver>
+ <driven
+ id="1006" />
+
+ <driven
+ id="1007" />
+ </param_driver>
+ </param>
+
+ <param
+ id="168"
+ sex="male"
+ group="0"
+ wearable="hair"
+ edit_group="hair_facial"
+ edit_group_order="5"
+ name="Soulpatch"
+ show_simple="true"
+ label_min="Less soul"
+ label_max="More soul"
+ value_min="0"
+ value_max="1"
+ value_default="0.0"
+ camera_elevation="-.1"
+ camera_distance=".3"
+ camera_angle="0">
+ <param_driver>
+ <driven
+ id="1008" />
+
+ <driven
+ id="1009" />
+ </param_driver>
+ </param>
+
+ <param
+ id="169"
+ sex="male"
+ group="0"
+ wearable="hair"
+ edit_group="hair_facial"
+ edit_group_order="4"
+ name="Chin Curtains"
+ show_simple="true"
+ label_min="Less Curtains"
+ label_max="More Curtains"
+ value_min="0"
+ value_max="1"
+ value_default="0.0"
+ camera_elevation="-.1"
+ camera_distance=".3"
+ camera_angle="45">
+ <param_driver>
+ <driven
+ id="1010" />
+
+ <driven
+ id="1011" />
+ </param_driver>
+ </param>
+
+ <param
+ id="606"
+ group="0"
+ wearable="jacket"
+ edit_group="jacket"
+ edit_group_order="1"
+ name="Sleeve Length"
+ label_min="Short"
+ label_max="Long"
+ value_min="0"
+ value_max="1"
+ value_default=".8"
+ camera_distance="1.2"
+ camera_angle="30"
+ camera_elevation=".2">
+ <param_driver>
+ <driven
+ id="1019" />
+
+ <driven
+ id="1039" />
+
+ <driven
+ id="1020" />
+ </param_driver>
+ </param>
+
+ <param
+ id="607"
+ group="0"
+ wearable="jacket"
+ edit_group="jacket"
+ edit_group_order="3"
+ name="Collar Front"
+ label_min="Low"
+ label_max="High"
+ value_min="0"
+ value_max="1"
+ value_default=".8"
+ camera_distance="1.2"
+ camera_angle="15"
+ camera_elevation=".2">
+ <param_driver>
+ <driven
+ id="1021" />
+
+ <driven
+ id="1040" />
+
+ <driven
+ id="1022" />
+ </param_driver>
+ </param>
+
+ <param
+ id="780"
+ group="0"
+ wearable="jacket"
+ edit_group="jacket"
+ edit_group_order="3.5"
+ name="Collar Back"
+ label_min="Low"
+ label_max="High"
+ value_min="0"
+ value_max="1"
+ value_default=".8"
+ camera_distance="1.2"
+ camera_angle="195"
+ camera_elevation=".2">
+ <param_driver>
+ <driven
+ id="1023" />
+
+ <driven
+ id="1041" />
+
+ <driven
+ id="1024" />
+ </param_driver>
+ </param>
+
+ <param
+ id="603"
+ group="0"
+ wearable="undershirt"
+ edit_group="undershirt"
+ edit_group_order="1"
+ name="Sleeve Length"
+ label_min="Short"
+ label_max="Long"
+ value_min=".01"
+ value_max="1"
+ value_default=".4"
+ camera_distance="1.2"
+ camera_angle="30"
+ camera_elevation=".2">
+ <param_driver>
+ <driven
+ id="1042" />
+
+ <driven
+ id="1043" />
+ </param_driver>
+ </param>
+
+ <param
+ id="604"
+ group="0"
+ wearable="undershirt"
+ edit_group="undershirt"
+ edit_group_order="2"
+ name="Bottom"
+ label_min="Short"
+ label_max="Long"
+ value_min="0"
+ value_max="1"
+ value_default=".85"
+ camera_distance="1.2"
+ camera_angle="30"
+ camera_elevation=".2">
+ <param_driver>
+ <driven
+ id="1044" />
+
+ <driven
+ id="1045" />
+ </param_driver>
+ </param>
+
+ <param
+ id="605"
+ group="0"
+ wearable="undershirt"
+ edit_group="undershirt"
+ edit_group_order="3"
+ name="Collar Front"
+ label_min="Low"
+ label_max="High"
+ value_min="0"
+ value_max="1"
+ value_default=".84"
+ camera_distance=".8"
+ camera_angle="15"
+ camera_elevation=".2">
+ <param_driver>
+ <driven
+ id="1046" />
+
+ <driven
+ id="1047" />
+ </param_driver>
+ </param>
+
+ <param
+ id="779"
+ group="0"
+ wearable="undershirt"
+ edit_group="undershirt"
+ edit_group_order="4"
+ name="Collar Back"
+ label_min="Low"
+ label_max="High"
+ value_min="0"
+ value_max="1"
+ value_default=".84"
+ camera_distance=".8"
+ camera_angle="195"
+ camera_elevation=".2">
+ <param_driver>
+ <driven
+ id="1048" />
+
+ <driven
+ id="1049" />
+ </param_driver>
+ </param>
+
+ <param
+ id="617"
+ group="0"
+ wearable="socks"
+ edit_group="socks"
+ name="Socks Length"
+ label_min="Short"
+ label_max="Long"
+ value_min="0"
+ value_max="1"
+ value_default="0.35"
+ camera_distance=".95"
+ camera_angle="30"
+ camera_elevation="-.75">
+ <param_driver>
+ <driven
+ id="1050" />
+
+ <driven
+ id="1051" />
+ </param_driver>
+ </param>
+
+ <param
+ id="616"
+ group="0"
+ wearable="shoes"
+ edit_group="shoes"
+ edit_group_order="1"
+ name="Shoe Height"
+ label_min="Short"
+ label_max="Tall"
+ value_min="0"
+ value_max="1"
+ value_default="0.1"
+ camera_distance="1.2"
+ camera_angle="30"
+ camera_elevation="-.75">
+ <param_driver>
+ <driven
+ id="1052" />
+
+ <driven
+ id="1053" />
+ </param_driver>
+ </param>
+
+ <param
+ id="619"
+ group="0"
+ wearable="underpants"
+ edit_group="underpants"
+ name="Pants Length"
+ label_min="Short"
+ label_max="Long"
+ value_min="0"
+ value_max="1"
+ value_default=".3"
+ camera_distance="1.2"
+ camera_angle="30"
+ camera_elevation="-.3">
+ <param_driver>
+ <driven
+ id="1054" />
+
+ <driven
+ id="1055" />
+ </param_driver>
+ </param>
+
+ <param
+ id="624"
+ group="0"
+ wearable="underpants"
+ edit_group="underpants"
+ name="Pants Waist"
+ label_min="Low"
+ label_max="High"
+ value_min="0"
+ value_max="1"
+ value_default=".8"
+ camera_distance="1.2"
+ camera_angle="30"
+ camera_elevation="-.3">
+ <param_driver>
+ <driven
+ id="1056" />
+
+ <driven
+ id="1057" />
+ </param_driver>
+ </param>
+
+ <param
+ id="93"
+ group="0"
+ wearable="gloves"
+ edit_group="gloves"
+ name="Glove Length"
+ label_min="Short"
+ label_max="Long"
+ value_min=".01"
+ value_max="1"
+ value_default=".8"
+ camera_distance="1.2"
+ camera_angle="30"
+ camera_elevation=".2">
+ <param_driver>
+ <driven
+ id="1058" />
+
+ <driven
+ id="1059" />
+ </param_driver>
+ </param>
+
+ <param
+ id="844"
+ group="0"
+ wearable="gloves"
+ edit_group="gloves"
+ name="Glove Fingers"
+ label_min="Fingerless"
+ label_max="Fingers"
+ value_min=".01"
+ value_max="1"
+ value_default="1"
+ camera_distance="1.2"
+ camera_angle="30"
+ camera_elevation=".2">
+ <param_driver>
+ <driven
+ id="1060" />
+
+ <driven
+ id="1061" />
+ </param_driver>
+ </param>
+
+ <!--Pointy eyebrows became a driver/driven param with new max value for backwards compatibility between 1.0 and 1.1-->
+ <param
+ id="16"
+ group="0"
+ name="Pointy_Eyebrows"
+ label="Eyebrow Points"
+ wearable="hair"
+ edit_group="hair_eyebrows"
+ edit_group_order="4"
+ label_min="Smooth"
+ label_max="Pointy"
+ value_min="-.5"
+ value_max="3"
+ camera_elevation=".1"
+ camera_distance=".3">
+ <param_driver>
+ <driven
+ id="870" />
+ </param_driver>
+ </param>
+
+ <!--Lower eyebrows became a driver/driven param with new min value for backwards compatibility between 1.0 and 1.1-->
+ <param
+ id="757"
+ group="0"
+ name="Lower_Eyebrows"
+ label="Eyebrow Height"
+ show_simple="true"
+ wearable="hair"
+ edit_group="hair_eyebrows"
+ edit_group_order="2.5"
+ label_min="Higher"
+ label_max="Lower"
+ value_min="-4"
+ value_max="2"
+ value_default="-1"
+ camera_elevation=".1"
+ camera_distance=".3">
+ <param_driver>
+ <driven
+ id="871" />
+ </param_driver>
+ </param>
+
+ <!--Arced eyebrows became a driver/driven param with new max value for backwards compatibility between 1.0 and 1.1-->
+ <param
+ id="31"
+ group="0"
+ name="Arced_Eyebrows"
+ label="Eyebrow Arc"
+ wearable="hair"
+ edit_group="hair_eyebrows"
+ edit_group_order="3"
+ label_min="Flat"
+ label_max="Arced"
+ value_min="0"
+ value_max="2"
+ value_default=".5"
+ camera_elevation=".1"
+ camera_distance=".3">
+ <param_driver>
+ <driven
+ id="872" />
+ </param_driver>
+ </param>
+
+
+ <param
+ id="877"
+ group="3"
+ name="Jacket Wrinkles"
+ label="Jacket Wrinkles"
+ wearable="jacket"
+ edit_group="jacket"
+ edit_group_order="20"
+ label_min="No Wrinkles"
+ label_max="Wrinkles"
+ value_min="0"
+ value_max="1"
+ value_default="0"
+ camera_elevation=".1"
+ camera_distance=".3">
+ <param_driver>
+ <driven
+ id="875" />
+
+
+ <driven
+ id="876" />
+ </param_driver>
+ </param>
+
+ <param
+ id="1071"
+ group="2"
+ wearable="tattoo"
+ edit_group="colorpicker"
+ name="tattoo_red"
+ value_min="0"
+ value_max="1"
+ value_default="1">
+ <param_driver>
+ <driven
+ id="1062"
+ min1="0"
+ max1="1"
+ max2="1"
+ min2="1" />
+
+ <driven
+ id="1065"
+ min1="0"
+ max1="1"
+ max2="1"
+ min2="1" />
+
+ <driven
+ id="1068"
+ min1="0"
+ max1="1"
+ max2="1"
+ min2="1" />
+ </param_driver>
+ </param>
+
+ <param
+ id="1072"
+ group="2"
+ wearable="tattoo"
+ edit_group="colorpicker"
+ name="tattoo_green"
+ value_min="0"
+ value_max="1"
+ value_default="1">
+ <param_driver>
+ <driven
+ id="1063"
+ min1="0"
+ max1="1"
+ max2="1"
+ min2="1" />
+
+ <driven
+ id="1066"
+ min1="0"
+ max1="1"
+ max2="1"
+ min2="1" />
+
+ <driven
+ id="1069"
+ min1="0"
+ max1="1"
+ max2="1"
+ min2="1" />
+ </param_driver>
+ </param>
+
+ <param
+ id="1073"
+ group="2"
+ wearable="tattoo"
+ edit_group="colorpicker"
+ name="tattoo_blue"
+ value_min="0"
+ value_max="1"
+ value_default="1">
+ <param_driver>
+ <driven
+ id="1064"
+ min1="0"
+ max1="1"
+ max2="1"
+ min2="1" />
+
+ <driven
+ id="1067"
+ min1="0"
+ max1="1"
+ max2="1"
+ min2="1" />
+
+ <driven
+ id="1070"
+ min1="0"
+ max1="1"
+ max2="1"
+ min2="1" />
+
+ </param_driver>
+ </param>
+
+ <!-- ==PHYSICS PARAMETERS======================================= -->
+
+ <param
+ id="1100"
+ group="1"
+ sex="female"
+ wearable="physics"
+ name="Breast_Physics_UpDown_Controller"
+ label="Breast Physics UpDown Controller"
+ value_min="-1"
+ value_max="1"
+ value_default="0">
+ <param_driver>
+ <driven
+ id="1200" />
+ </param_driver>
+ </param>
+
+ <param
+ id="1101"
+ group="1"
+ sex="female"
+ wearable="physics"
+ name="Breast_Physics_InOut_Controller"
+ label="Breast Physics InOut Controller"
+ value_min="-1"
+ value_max="1"
+ value_default="0">
+ <param_driver>
+ <driven
+ id="1201" />
+ </param_driver>
+ </param>
+
+ <param
+ id="1102"
+ group="1"
+ wearable="physics"
+ name="Belly_Physics_UpDown_Controller"
+ label="Belly Physics UpDown Controller"
+ value_min="-1"
+ value_max="1"
+ value_default="0">
+ <param_driver>
+ <driven
+ id="1202" />
+ <driven
+ id="1203" />
+ <driven
+ id="1204" />
+ </param_driver>
+ </param>
+
+ <param
+ id="1103"
+ group="1"
+ wearable="shape"
+ name="Butt_Physics_UpDown_Controller"
+ label="Butt Physics UpDown Controller"
+ value_min="-1"
+ value_max="1"
+ value_default="0">
+ <param_driver>
+ <driven
+ id="1205" />
+ </param_driver>
+ </param>
+
+ <param
+ id="1104"
+ group="1"
+ wearable="shape"
+ name="Butt_Physics_LeftRight_Controller"
+ label="Butt Physics LeftRight Controller"
+ value_min="-1"
+ value_max="1"
+ value_default="0">
+ <param_driver>
+ <driven
+ id="1206" />
+ </param_driver>
+ </param>
+
+ <param
+ id="1105"
+ group="1"
+ wearable="shape"
+ name="Breast_Physics_LeftRight_Controller"
+ label="Breast Physics LeftRight Controller"
+ value_min="-1"
+ value_max="1"
+ value_default="0">
+ <param_driver>
+ <driven
+ id="1207" />
+ </param_driver>
+ </param>
+
+ <param
+ id="10000"
+ group="0"
+ sex="female"
+ name="Breast_Physics_Mass"
+ label="Breast Physics Mass"
+ wearable="physics"
+ edit_group="physics_advanced"
+ value_default=".1"
+ value_min=".1"
+ value_max="1">
+ <param_driver />
+ </param>
+ <param
+ id="10001"
+ group="0"
+ sex="female"
+ name="Breast_Physics_Gravity"
+ label="Breast Physics Gravity"
+ wearable="physics"
+ edit_group="physics_advanced"
+ value_default="0"
+ value_min="0"
+ value_max="30">
+ <param_driver />
+ </param>
+
+ <param
+ id="10002"
+ group="0"
+ sex="female"
+ name="Breast_Physics_Drag"
+ label="Breast Physics Drag"
+ wearable="physics"
+ edit_group="physics_advanced"
+ value_default="1"
+ value_min="0"
+ value_max="10">
+ <param_driver />
+ </param>
+
+ <param
+ id="10003"
+ group="0"
+ sex="female"
+ name="Breast_Physics_UpDown_Max_Effect"
+ label="Breast Physics UpDown Max Effect"
+ wearable="physics"
+ edit_group="physics_breasts_updown"
+ value_default="0"
+ value_min="0"
+ value_max="3">
+ <param_driver />
+ </param>
+ <param
+ id="10004"
+ group="0"
+ sex="female"
+ name="Breast_Physics_UpDown_Spring"
+ label="Breast Physics UpDown Spring"
+ wearable="physics"
+ edit_group="physics_breasts_updown"
+ value_default="10"
+ value_min="0"
+ value_max="100">
+ <param_driver />
+ </param>
+ <param
+ id="10005"
+ group="0"
+ sex="female"
+ name="Breast_Physics_UpDown_Gain"
+ label="Breast Physics UpDown Gain"
+ wearable="physics"
+ edit_group="physics_breasts_updown"
+ value_default="10"
+ value_min="1"
+ value_max="100">
+ <param_driver />
+ </param>
+ <param
+ id="10006"
+ group="0"
+ sex="female"
+ name="Breast_Physics_UpDown_Damping"
+ label="Breast Physics UpDown Damping"
+ wearable="physics"
+ edit_group="physics_breasts_updown"
+ value_default=".2"
+ value_min="0"
+ value_max="1">
+ <param_driver />
+ </param>
+
+ <param
+ id="10007"
+ group="0"
+ sex="female"
+ name="Breast_Physics_InOut_Max_Effect"
+ label="Breast Physics InOut Max Effect"
+ wearable="physics"
+ edit_group="physics_breasts_inout"
+ value_default="0"
+ value_min="0"
+ value_max="3">
+ <param_driver />
+ </param>
+ <param
+ id="10008"
+ group="0"
+ sex="female"
+ name="Breast_Physics_InOut_Spring"
+ label="Breast Physics InOut Spring"
+ wearable="physics"
+ edit_group="physics_breasts_inout"
+ value_default="10"
+ value_min="0"
+ value_max="100">
+ <param_driver />
+ </param>
+ <param
+ id="10009"
+ group="0"
+ sex="female"
+ name="Breast_Physics_InOut_Gain"
+ label="Breast Physics InOut Gain"
+ wearable="physics"
+ edit_group="physics_breasts_inout"
+ value_default="10"
+ value_min="1"
+ value_max="100">
+ <param_driver />
+ </param>
+ <param
+ id="10010"
+ group="0"
+ sex="female"
+ name="Breast_Physics_InOut_Damping"
+ label="Breast Physics InOut Damping"
+ wearable="physics"
+ edit_group="physics_breasts_inout"
+ value_default=".2"
+ value_min="0"
+ value_max="1">
+ <param_driver />
+ </param>
+
+ <param
+ id="10011"
+ group="0"
+ name="Belly_Physics_Mass"
+ label="Belly Physics Mass"
+ wearable="physics"
+ edit_group="physics_advanced"
+ value_default=".1"
+ value_min=".1"
+ value_max="1">
+ <param_driver />
+ </param>
+ <param
+ id="10012"
+ group="0"
+ name="Belly_Physics_Gravity"
+ label="Belly Physics Gravity"
+ wearable="physics"
+ edit_group="physics_advanced"
+ value_default="0"
+ value_min="0"
+ value_max="30">
+ <param_driver />
+ </param>
+ <param
+ id="10013"
+ group="0"
+ name="Belly_Physics_Drag"
+ label="Belly Physics Drag"
+ wearable="physics"
+ edit_group="physics_advanced"
+ value_default="1"
+ value_min="0"
+ value_max="10">
+ <param_driver />
+ </param>
+ <param
+ id="10014"
+ group="0"
+ name="Belly_Physics_UpDown_Max_Effect"
+ label="Belly Physics UpDown Max Effect"
+ wearable="physics"
+ edit_group="physics_belly_updown"
+ value_default="0"
+ value_min="0"
+ value_max="3">
+ <param_driver />
+ </param>
+ <param
+ id="10015"
+ group="0"
+ name="Belly_Physics_UpDown_Spring"
+ label="Belly Physics UpDown Spring"
+ wearable="physics"
+ edit_group="physics_belly_updown"
+ value_default="10"
+ value_min="0"
+ value_max="100">
+ <param_driver />
+ </param>
+ <param
+ id="10016"
+ group="0"
+ name="Belly_Physics_UpDown_Gain"
+ label="Belly Physics UpDown Gain"
+ wearable="physics"
+ edit_group="physics_belly_updown"
+ value_default="10"
+ value_min="1"
+ value_max="100">
+ <param_driver />
+ </param>
+ <param
+ id="10017"
+ group="0"
+ name="Belly_Physics_UpDown_Damping"
+ label="Belly Physics UpDown Damping"
+ wearable="physics"
+ edit_group="physics_belly_updown"
+ value_default=".2"
+ value_min="0"
+ value_max="1">
+ <param_driver />
+ </param>
+
+ <param
+ id="10018"
+ group="0"
+ name="Butt_Physics_Mass"
+ label="Butt Physics Mass"
+ wearable="physics"
+ edit_group="physics_advanced"
+ value_default=".1"
+ value_min=".1"
+ value_max="1">
+ <param_driver />
+ </param>
+ <param
+ id="10019"
+ group="0"
+ name="Butt_Physics_Gravity"
+ label="Butt Physics Gravity"
+ wearable="physics"
+ edit_group="physics_advanced"
+ value_default="0"
+ value_min="0"
+ value_max="30">
+ <param_driver />
+ </param>
+ <param
+ id="10020"
+ group="0"
+ name="Butt_Physics_Drag"
+ label="Butt Physics Drag"
+ wearable="physics"
+ edit_group="physics_advanced"
+ value_default="1"
+ value_min="0"
+ value_max="10">
+ <param_driver />
+ </param>
+
+ <param
+ id="10021"
+ group="0"
+ name="Butt_Physics_UpDown_Max_Effect"
+ label="Butt Physics UpDown Max Effect"
+ wearable="physics"
+ edit_group="physics_butt_updown"
+ value_default="0"
+ value_min="0"
+ value_max="3">
+ <param_driver />
+ </param>
+ <param
+ id="10022"
+ group="0"
+ name="Butt_Physics_UpDown_Spring"
+ label="Butt Physics UpDown Spring"
+ wearable="physics"
+ edit_group="physics_butt_updown"
+ value_default="10"
+ value_min="0"
+ value_max="100">
+ <param_driver />
+ </param>
+ <param
+ id="10023"
+ group="0"
+ name="Butt_Physics_UpDown_Gain"
+ label="Butt Physics UpDown Gain"
+ wearable="physics"
+ edit_group="physics_butt_updown"
+ value_default="10"
+ value_min="1"
+ value_max="100">
+ <param_driver />
+ </param>
+ <param
+ id="10024"
+ group="0"
+ name="Butt_Physics_UpDown_Damping"
+ label="Butt Physics UpDown Damping"
+ wearable="physics"
+ edit_group="physics_butt_updown"
+ value_default=".2"
+ value_min="0"
+ value_max="1">
+ <param_driver />
+ </param>
+
+ <param
+ id="10025"
+ group="0"
+ name="Butt_Physics_LeftRight_Max_Effect"
+ label="Butt Physics LeftRight Max Effect"
+ wearable="physics"
+ edit_group="physics_butt_leftright"
+ value_default="0"
+ value_min="0"
+ value_max="3">
+ <param_driver />
+ </param>
+ <param
+ id="10026"
+ group="0"
+ name="Butt_Physics_LeftRight_Spring"
+ label="Butt Physics LeftRight Spring"
+ wearable="physics"
+ edit_group="physics_butt_leftright"
+ value_default="10"
+ value_min="0"
+ value_max="100">
+ <param_driver />
+ </param>
+ <param
+ id="10027"
+ group="0"
+ name="Butt_Physics_LeftRight_Gain"
+ label="Butt Physics LeftRight Gain"
+ wearable="physics"
+ edit_group="physics_butt_leftright"
+ value_default="10"
+ value_min="1"
+ value_max="100">
+ <param_driver />
+ </param>
+ <param
+ id="10028"
+ group="0"
+ name="Butt_Physics_LeftRight_Damping"
+ label="Butt Physics LeftRight Damping"
+ wearable="physics"
+ edit_group="physics_butt_leftright"
+ value_default=".2"
+ value_min="0"
+ value_max="1">
+ <param_driver />
+ </param>
+
+ <param
+ id="10029"
+ group="0"
+ sex="female"
+ name="Breast_Physics_LeftRight_Max_Effect"
+ label="Breast Physics LeftRight Max Effect"
+ wearable="physics"
+ edit_group="physics_breasts_leftright"
+ value_default="0"
+ value_min="0"
+ value_max="3">
+ <param_driver />
+ </param>
+ <param
+ id="10030"
+ group="0"
+ sex="female"
+ name="Breast_Physics_LeftRight_Spring"
+ label="Breast Physics LeftRight Spring"
+ wearable="physics"
+ edit_group="physics_breasts_leftright"
+ value_default="10"
+ value_min="0"
+ value_max="100">
+ <param_driver />
+ </param>
+ <param
+ id="10031"
+ group="0"
+ sex="female"
+ name="Breast_Physics_LeftRight_Gain"
+ label="Breast Physics LeftRight Gain"
+ wearable="physics"
+ edit_group="physics_breasts_leftright"
+ value_default="10"
+ value_min="1"
+ value_max="100">
+ <param_driver />
+ </param>
+ <param
+ id="10032"
+ group="0"
+ sex="female"
+ name="Breast_Physics_LeftRight_Damping"
+ label="Breast Physics LeftRight Damping"
+ wearable="physics"
+ edit_group="physics_breasts_leftright"
+ value_default=".2"
+ value_min="0"
+ value_max="1">
+ <param_driver />
+ </param>
+
+ <param
+ id="11000"
+ group="0"
+ name="AppearanceMessage_Version"
+ label="AppearanceMessage Version"
+ value_default="0"
+ value_min="0"
+ value_max="255">
+ <param_driver />
+ </param>
+
+ </driver_parameters>
+
+ <morph_masks>
+ <mask
+ morph_name="Displace_Hair_Facial"
+ body_region="head"
+ layer="facialhair" />
+ <mask
+ morph_name="Displace_Loose_Upperbody"
+ body_region="upper_body"
+ layer="upper_clothes" />
+ <mask
+ morph_name="Shirtsleeve_flair"
+ body_region="upper_body"
+ layer="upper_clothes" />
+ <mask
+ morph_name="Displace_Loose_Lowerbody"
+ body_region="lower_body"
+ layer="lower_pants" />
+ <mask
+ morph_name="Leg_Pantflair"
+ body_region="lower_body"
+ layer="lower_pants" />
+ <mask
+ morph_name="Low_Crotch"
+ body_region="lower_body"
+ layer="lower_pants" />
+ <mask
+ morph_name="Leg_Longcuffs"
+ body_region="lower_body"
+ layer="lower_pants" />
+ </morph_masks>
+</linden_avatar>
+
diff --git a/indra/newview/character/avatar_lad_wings_tail.xml b/indra/newview/character/avatar_lad_wings_tail.xml
new file mode 100644
index 0000000000..ac0b8b5704
--- /dev/null
+++ b/indra/newview/character/avatar_lad_wings_tail.xml
@@ -0,0 +1,12615 @@
+<?xml version="1.0" encoding="US-ASCII" standalone="yes"?>
+<linden_avatar
+ version="1.0" wearable_definition_version="22">
+ <!-- The wearable_definition_version is checked during asset upload. -->
+ <!-- If you increment it, check indra/lib/python/indra/assetutil.py. -->
+ <skeleton
+ file_name="avatar_skeleton.xml">
+ <attachment_point
+ id="1"
+ group="6"
+ pie_slice="2"
+ name="Chest"
+ joint="mChest"
+ position="0.15 0 -0.1"
+ rotation="0 90 90"
+ visible_in_first_person="true" />
+
+ <attachment_point
+ id="2"
+ group="2"
+ pie_slice="2"
+ name="Skull"
+ joint="mHead"
+ position="0 0 0.15"
+ rotation="0 0 90"
+ visible_in_first_person="false" />
+
+ <attachment_point
+ id="3"
+ group="3"
+ pie_slice="3"
+ name="Left Shoulder"
+ joint="mCollarLeft"
+ position="0 0 0.08"
+ rotation="0 0 0"
+ visible_in_first_person="true" />
+
+ <attachment_point
+ id="4"
+ group="1"
+ pie_slice="1"
+ name="Right Shoulder"
+ joint="mCollarRight"
+ position="0 0 0.08"
+ rotation="0 0 0"
+ visible_in_first_person="true"/>
+
+ <attachment_point
+ id="5"
+ group="4"
+ name="Left Hand"
+ joint="mWristLeft"
+ position="0 0.08 -0.02"
+ rotation="0 0 0"
+ visible_in_first_person="true"
+ max_attachment_offset="1.5" />
+
+ <attachment_point
+ id="6"
+ group="0"
+ name="Right Hand"
+ joint="mWristRight"
+ position="0 -0.08 -0.02"
+ rotation="0 0 0"
+ visible_in_first_person="true"
+ max_attachment_offset="1.5" />
+
+ <attachment_point
+ id="7"
+ group="5"
+ pie_slice="6"
+ name="Left Foot"
+ joint="mFootLeft"
+ position="0 0.0 0.0"
+ rotation="0 0 0"
+ visible_in_first_person="true"/>
+
+ <attachment_point
+ id="8"
+ group="7"
+ pie_slice="6"
+ name="Right Foot"
+ joint="mFootRight"
+ position="0 0.0 0.0"
+ rotation="0 0 0"
+ visible_in_first_person="true"/>
+
+ <attachment_point
+ id="9"
+ group="6"
+ pie_slice="7"
+ name="Spine"
+ joint="mChest"
+ position="-0.15 0 -0.1"
+ rotation="0 -90 90"
+ visible_in_first_person="true" />
+
+ <attachment_point
+ id="10"
+ group="6"
+ pie_slice="6"
+ name="Pelvis"
+ joint="mPelvis"
+ position="0 0 -0.15"
+ rotation="0 0 0"
+ visible_in_first_person="true" />
+
+ <attachment_point
+ id="11"
+ group="2"
+ pie_slice="6"
+ name="Mouth"
+ joint="mHead"
+ position="0.12 0 0.001"
+ rotation="0 0 0"
+ visible_in_first_person="false"/>
+
+ <attachment_point
+ id="12"
+ group="2"
+ pie_slice="7"
+ name="Chin"
+ joint="mHead"
+ position="0.12 0 -0.04"
+ rotation="0 0 0"
+ visible_in_first_person="false" />
+
+ <attachment_point
+ id="13"
+ group="2"
+ pie_slice="4"
+ name="Left Ear"
+ joint="mHead"
+ position="0.015 0.08 0.017"
+ rotation="0 0 0"
+ visible_in_first_person="false" />
+
+ <attachment_point
+ id="14"
+ group="2"
+ pie_slice="0"
+ name="Right Ear"
+ joint="mHead"
+ position="0.015 -0.08 0.017"
+ rotation="0 0 0"
+ visible_in_first_person="false" />
+
+ <attachment_point
+ id="15"
+ group="2"
+ pie_slice="3"
+ name="Left Eyeball"
+ joint="mEyeLeft"
+ position="0 0 0"
+ rotation="0 0 0"
+ visible_in_first_person="false"/>
+
+ <attachment_point
+ id="16"
+ group="2"
+ pie_slice="1"
+ name="Right Eyeball"
+ joint="mEyeRight"
+ position="0 0 0"
+ rotation="0 0 0"
+ visible_in_first_person="false" />
+
+ <attachment_point
+ id="17"
+ group="2"
+ pie_slice="5"
+ name="Nose"
+ joint="mHead"
+ position="0.1 0 0.05"
+ rotation="0 0 0"
+ visible_in_first_person="false"/>
+
+ <attachment_point
+ id="18"
+ group="1"
+ pie_slice="0"
+ name="R Upper Arm"
+ joint="mShoulderRight"
+ position="0.01 -0.13 0.01"
+ rotation="0 0 0"
+ visible_in_first_person="true" />
+
+ <attachment_point
+ id="19"
+ group="1"
+ pie_slice="7"
+ name="R Forearm"
+ joint="mElbowRight"
+ position="0 -0.12 0"
+ rotation="0 0 0"
+ visible_in_first_person="true"/>
+
+ <attachment_point
+ id="20"
+ group="3"
+ pie_slice="4"
+ name="L Upper Arm"
+ joint="mShoulderLeft"
+ position="0.01 0.15 -0.01"
+ rotation="0 0 0"
+ visible_in_first_person="true" />
+
+ <attachment_point
+ id="21"
+ group="3"
+ pie_slice="5"
+ name="L Forearm"
+ joint="mElbowLeft"
+ position="0 0.113 0"
+ rotation="0 0 0"
+ visible_in_first_person="true" />
+
+ <attachment_point
+ id="22"
+ group="7"
+ pie_slice="1"
+ name="Right Hip"
+ joint="mHipRight"
+ position="0 0 0"
+ rotation="0 0 0"
+ visible_in_first_person="true" />
+
+ <attachment_point
+ id="23"
+ group="7"
+ pie_slice="0"
+ name="R Upper Leg"
+ joint="mHipRight"
+ position="-0.017 0.041 -0.310"
+ rotation="0 0 0"
+ visible_in_first_person="true" />
+
+ <attachment_point
+ id="24"
+ group="7"
+ pie_slice="7"
+ name="R Lower Leg"
+ joint="mKneeRight"
+ position="-0.044 -0.007 -0.262"
+ rotation="0 0 0"
+ visible_in_first_person="true" />
+
+ <attachment_point
+ id="25"
+ group="5"
+ pie_slice="3"
+ name="Left Hip"
+ joint="mHipLeft"
+ position="0 0 0"
+ rotation="0 0 0"
+ visible_in_first_person="true" />
+
+ <attachment_point
+ id="26"
+ group="5"
+ pie_slice="4"
+ name="L Upper Leg"
+ joint="mHipLeft"
+ position="-0.019 -0.034 -0.310"
+ rotation="0 0 0"
+ visible_in_first_person="true"/>
+
+ <attachment_point
+ id="27"
+ group="5"
+ pie_slice="5"
+ name="L Lower Leg"
+ joint="mKneeLeft"
+ position="-0.044 -0.007 -0.261"
+ rotation="0 0 0"
+ visible_in_first_person="true" />
+
+ <attachment_point
+ id="28"
+ group="6"
+ pie_slice="5"
+ name="Stomach"
+ joint="mPelvis"
+ position="0.092 0.0 0.088"
+ rotation="0 0 0"
+ visible_in_first_person="true" />
+
+ <attachment_point
+ id="29"
+ group="6"
+ pie_slice="3"
+ name="Left Pec"
+ joint="mTorso"
+ position="0.104 0.082 0.247"
+ rotation="0 0 0"
+ visible_in_first_person="true" />
+
+ <attachment_point
+ id="30"
+ group="6"
+ pie_slice="1"
+ name="Right Pec"
+ joint="mTorso"
+ position="0.104 -0.082 0.247"
+ rotation="0 0 0"
+ visible_in_first_person="true" />
+
+ <attachment_point
+ id="31"
+ group="8"
+ name="Center 2"
+ joint="mScreen"
+ position="0 0 0"
+ rotation="0 0 0"
+ hud="true"
+ max_attachment_offset="2.0"
+ visible_in_first_person="true" />
+
+ <attachment_point
+ id="32"
+ group="8"
+ name="Top Right"
+ joint="mScreen"
+ position="0 -0.5 0.5"
+ rotation="0 0 0"
+ hud="true"
+ max_attachment_offset="2.0"
+ visible_in_first_person="true" />
+
+ <attachment_point
+ id="33"
+ group="8"
+ name="Top"
+ joint="mScreen"
+ position="0 0 0.5"
+ rotation="0 0 0"
+ hud="true"
+ max_attachment_offset="2.0"
+ visible_in_first_person="true" />
+
+ <attachment_point
+ id="34"
+ group="8"
+ name="Top Left"
+ joint="mScreen"
+ position="0 0.5 0.5"
+ rotation="0 0 0"
+ hud="true"
+ max_attachment_offset="2.0"
+ visible_in_first_person="true" />
+
+ <attachment_point
+ id="35"
+ group="8"
+ name="Center"
+ joint="mScreen"
+ position="0 0 0"
+ rotation="0 0 0"
+ hud="true"
+ max_attachment_offset="2.0"
+ visible_in_first_person="true" />
+
+ <attachment_point
+ id="36"
+ group="8"
+ name="Bottom Left"
+ joint="mScreen"
+ position="0 0.5 -0.5"
+ rotation="0 0 0"
+ hud="true"
+ max_attachment_offset="2.0"
+ visible_in_first_person="true" />
+
+ <attachment_point
+ id="37"
+ group="8"
+ name="Bottom"
+ joint="mScreen"
+ position="0 0 -0.5"
+ rotation="0 0 0"
+ hud="true"
+ max_attachment_offset="2.0"
+ visible_in_first_person="true" />
+
+ <attachment_point
+ id="38"
+ group="8"
+ name="Bottom Right"
+ joint="mScreen"
+ position="0 -0.5 -0.5"
+ rotation="0 0 0"
+ hud="true"
+ max_attachment_offset="2.0"
+ visible_in_first_person="true" />
+
+ <attachment_point
+ id="39"
+ group="6"
+ pie_slice="1"
+ name="Neck"
+ joint="mNeck"
+ position="0 0 0"
+ rotation="0 0 0"
+ visible_in_first_person="true" />
+
+ <attachment_point
+ id="40"
+ group="6"
+ pie_slice="2"
+ name="Avatar Center"
+ joint="mRoot"
+ position="0 0 0"
+ rotation="0 0 0"
+ visible_in_first_person="true" />
+
+ <attachment_point
+ id="41"
+ group="6"
+ pie_slice="2"
+ name="L Wing Shoulder"
+ joint="mLeftWingShoulder"
+ position="0 0 0"
+ rotation="0 0 0"
+ visible_in_first_person="true" />
+
+ <attachment_point
+ id="42"
+ group="6"
+ pie_slice="2"
+ name="L Wing Elbow"
+ joint="mLeftWingElbow"
+ position="0 0 0"
+ rotation="0 0 0"
+ visible_in_first_person="true" />
+
+ <attachment_point
+ id="43"
+ group="6"
+ pie_slice="2"
+ name="L Wing Wrist"
+ joint="mLeftWingWrist"
+ position="0 0 0"
+ rotation="0 0 0"
+ visible_in_first_person="true" />
+
+ <attachment_point
+ id="44"
+ group="6"
+ pie_slice="2"
+ name="L Wing Tip"
+ joint="mLeftWingTip"
+ position="0 0 0"
+ rotation="0 0 0"
+ visible_in_first_person="true" />
+
+ <attachment_point
+ id="45"
+ group="6"
+ pie_slice="2"
+ name="R Wing Shoulder"
+ joint="mRightWingShoulder"
+ position="0 0 0"
+ rotation="0 0 0"
+ visible_in_first_person="true" />
+
+ <attachment_point
+ id="46"
+ group="6"
+ pie_slice="2"
+ name="R Wing Elbow"
+ joint="mRightWingElbow"
+ position="0 0 0"
+ rotation="0 0 0"
+ visible_in_first_person="true" />
+
+ <attachment_point
+ id="47"
+ group="6"
+ pie_slice="2"
+ name="R Wing Wrist"
+ joint="mRightWingWrist"
+ position="0 0 0"
+ rotation="0 0 0"
+ visible_in_first_person="true" />
+
+ <attachment_point
+ id="48"
+ group="6"
+ pie_slice="2"
+ name="R Wing Tip"
+ joint="mRightWingTip"
+ position="0 0 0"
+ rotation="0 0 0"
+ visible_in_first_person="true" />
+
+ <attachment_point
+ id="49"
+ group="6"
+ pie_slice="2"
+ name="Tail 1"
+ joint="mTail_1"
+ position="0 0 0"
+ rotation="0 0 0"
+ visible_in_first_person="true" />
+
+ <attachment_point
+ id="50"
+ group="6"
+ pie_slice="2"
+ name="Tail 2"
+ joint="mTail_2"
+ position="0 0 0"
+ rotation="0 0 0"
+ visible_in_first_person="true" />
+
+ <attachment_point
+ id="51"
+ group="6"
+ pie_slice="2"
+ name="Tail 3"
+ joint="mTail_3"
+ position="0 0 0"
+ rotation="0 0 0"
+ visible_in_first_person="true" />
+
+ <param
+ id="32"
+ group="1"
+ wearable="shape"
+ name="Male_Skeleton"
+ label_min="Female"
+ label_max="Male"
+ value_min="0"
+ value_max="1">
+ <param_skeleton>
+ <bone
+ name="mNeck"
+ scale="0 0 .2" />
+
+ <bone
+ name="mCollarLeft"
+ scale="0 .4 0" />
+
+ <bone
+ name="mCollarRight"
+ scale="0 .4 0" />
+
+ <bone
+ name="mShoulderLeft"
+ scale="0 .35 0" />
+
+ <bone
+ name="mShoulderRight"
+ scale="0 .35 0" />
+
+ <bone
+ name="mElbowLeft"
+ scale="0 .1 0" />
+
+ <bone
+ name="mElbowRight"
+ scale="0 .1 0" />
+
+ <bone
+ name="mChest"
+ scale=".05 .05 .05" />
+
+ <bone
+ name="mTorso"
+ scale="0 0 .05" />
+
+ <bone
+ name="mPelvis"
+ scale="0 0 0" />
+
+ <bone
+ name="mHipLeft"
+ scale=".05 .05 0" />
+
+ <bone
+ name="mHipRight"
+ scale=".05 .05 0" />
+
+ <bone
+ name="mKneeLeft"
+ scale=".05 .05 .1" />
+
+ <bone
+ name="mKneeRight"
+ scale=".05 .05 .1" />
+ </param_skeleton>
+ </param>
+
+ <param
+ id="33"
+ group="0"
+ name="Height"
+ label="Height"
+ wearable="shape"
+ edit_group="shape_body"
+ edit_group_order="1"
+ label_min="Short"
+ label_max="Tall"
+ show_simple="true"
+ value_min="-2.3"
+ value_max="2"
+ camera_distance="2.2">
+ <param_skeleton>
+ <bone
+ name="mNeck"
+ scale="0 0 .02" />
+
+ <bone
+ name="mCollarLeft"
+ scale="0 0 0" />
+
+ <bone
+ name="mCollarRight"
+ scale="0 0 0" />
+
+ <bone
+ name="mShoulderLeft"
+ scale="0 0.08 0" />
+
+ <bone
+ name="mShoulderRight"
+ scale="0 0.08 0" />
+
+ <bone
+ name="mElbowLeft"
+ scale="0 0.06 0" />
+
+ <bone
+ name="mElbowRight"
+ scale="0 0.06 0" />
+
+ <bone
+ name="mChest"
+ scale="0 0 0.05" />
+
+ <bone
+ name="mTorso"
+ scale="0 0 0.05" />
+
+ <bone
+ name="mPelvis"
+ scale="0 0 0" />
+
+ <bone
+ name="mHipLeft"
+ scale="0 0 0.1" />
+
+ <bone
+ name="mHipRight"
+ scale="0 0 0.1" />
+
+ <bone
+ name="mKneeLeft"
+ scale="0 0 0.1" />
+
+ <bone
+ name="mKneeRight"
+ scale="0 0 0.1" />
+ </param_skeleton>
+ </param>
+
+ <param
+ id="34"
+ group="0"
+ name="Thickness"
+ label="Body Thickness"
+ wearable="shape"
+ edit_group="shape_body"
+ edit_group_order="2"
+ label_min="Body Thin"
+ label_max="Body Thick"
+ show_simple="true"
+ value_min="-0.7"
+ value_max="1.5"
+ camera_distance="1.8">
+ <param_skeleton>
+ <bone
+ name="mNeck"
+ scale="0.1 0.1 0" />
+
+ <bone
+ name="mCollarLeft"
+ scale="0 0.2 0" />
+
+ <bone
+ name="mCollarRight"
+ scale="0 0.2 0" />
+
+ <bone
+ name="mShoulderLeft"
+ scale="0.1 0 0.1" />
+
+ <bone
+ name="mShoulderRight"
+ scale="0.1 0 0.1" />
+
+ <bone
+ name="mElbowLeft"
+ scale="0.1 0 0.1" />
+
+ <bone
+ name="mElbowRight"
+ scale="0.1 0 0.1" />
+
+ <bone
+ name="mChest"
+ scale="0.1 0.1 0" />
+
+ <bone
+ name="mTorso"
+ scale="0.1 0.1 0" />
+
+ <bone
+ name="mPelvis"
+ scale="0.1 0.1 0" />
+
+ <bone
+ name="mHipLeft"
+ scale="0.13 0.13 0" />
+
+ <bone
+ name="mHipRight"
+ scale="0.13 0.13 0" />
+
+ <bone
+ name="mKneeLeft"
+ scale="0.12 0.12 0" />
+
+ <bone
+ name="mKneeRight"
+ scale="0.12 0.12 0" />
+ </param_skeleton>
+ </param>
+
+ <param
+ id="36"
+ group="0"
+ name="Shoulders"
+ label="Shoulders"
+ wearable="shape"
+ edit_group="shape_torso"
+ edit_group_order="4"
+ label_min="Narrow"
+ label_max="Broad"
+ show_simple="true"
+ value_min="-1.8"
+ value_max="1.4"
+ value_default="-0.5"
+ camera_elevation=".1"
+ camera_distance="1.2"
+ camera_angle="0">
+ <param_skeleton>
+ <bone
+ name="mNeck"
+ scale="0.01 0.03 0" />
+
+ <bone
+ name="mCollarLeft"
+ scale="0 0 0"
+ offset="0 .02 0" />
+
+ <bone
+ name="mCollarRight"
+ scale="0 0 0"
+ offset="0 -.02 0" />
+
+ <bone
+ name="mChest"
+ scale="0.02 0.08 0" />
+ </param_skeleton>
+ </param>
+
+ <param
+ id="37"
+ group="0"
+ name="Hip Width"
+ label="Hip Width"
+ wearable="shape"
+ edit_group="shape_legs"
+ edit_group_order="3"
+ label_min="Narrow"
+ label_max="Wide"
+ show_simple="true"
+ value_min="-3.2"
+ value_max="2.8"
+ camera_distance="1.8">
+ <param_skeleton>
+ <bone
+ name="mPelvis"
+ scale="0 0.1 0" />
+
+ <bone
+ name="mHipLeft"
+ scale="0 0 0"
+ offset="0 .004 0" />
+
+ <bone
+ name="mHipRight"
+ scale="0 0 0"
+ offset="0 -.004 0" />
+ </param_skeleton>
+ </param>
+
+ <param
+ id="842"
+ group="0"
+ name="Hip Length"
+ wearable="shape"
+ edit_group="shape_legs"
+ edit_group_order="3.2"
+ label_min="Short hips"
+ label_max="Long Hips"
+ value_min="-1"
+ value_max="1"
+ camera_distance="1.8">
+ <param_skeleton>
+ <bone
+ name="mPelvis"
+ scale="0 0 0.3" />
+ </param_skeleton>
+ </param>
+
+ <param
+ id="38"
+ group="0"
+ name="Torso Length"
+ wearable="shape"
+ edit_group="shape_torso"
+ edit_group_order="11"
+ label_min="Short Torso"
+ label_max="Long Torso"
+ value_min="-1"
+ value_max="1"
+ camera_distance="1.8">
+ <param_skeleton>
+ <bone
+ name="mTorso"
+ scale="0 0 .3" />
+
+ <bone
+ name="mPelvis"
+ scale="0 0 .1" />
+
+ <bone
+ name="mHipLeft"
+ scale="0 0 -.1" />
+
+ <bone
+ name="mHipRight"
+ scale="0 0 -.1" />
+
+ <bone
+ name="mKneeRight"
+ scale="0 0 -.05" />
+
+ <bone
+ name="mKneeLeft"
+ scale="0 0 -.05" />
+ </param_skeleton>
+ </param>
+
+ <param
+ id="195"
+ group="1"
+ name="EyeBone_Spread"
+ wearable="shape"
+ edit_group="shape_eyes"
+ label_min="Eyes Together"
+ label_max="Eyes Spread"
+ value_min="-1"
+ value_max="1">
+ <param_skeleton>
+ <bone
+ name="mEyeLeft"
+ scale="0 0 0"
+ offset="0 .009 0" />
+
+ <bone
+ name="mEyeRight"
+ scale="0 0 0"
+ offset="0 -.009 0" />
+ </param_skeleton>
+ </param>
+
+ <param
+ id="661"
+ group="1"
+ name="EyeBone_Head_Shear"
+ wearable="shape"
+ edit_group="shape_eyes"
+ label_min="Eyes Shear Left Up"
+ label_max="Eyes Shear Right Up"
+ value_min="-2"
+ value_max="2">
+ <param_skeleton>
+ <bone
+ name="mEyeLeft"
+ scale="0 0 0"
+ offset="0 0 .004" />
+
+ <bone
+ name="mEyeRight"
+ scale="0 0 0"
+ offset="0 0 -.004" />
+ </param_skeleton>
+ </param>
+
+ <param
+ id="772"
+ group="1"
+ name="EyeBone_Head_Elongate"
+ wearable="shape"
+ edit_group="shape_eyes"
+ label_min="Eyes Short Head"
+ label_max="Eyes Long Head"
+ value_min="-1"
+ value_max="1">
+ <param_skeleton>
+ <bone
+ name="mEyeLeft"
+ scale="0 0 0"
+ offset=".016 0 0" />
+
+ <bone
+ name="mEyeRight"
+ scale="0 0 0"
+ offset=".016 0 0" />
+ </param_skeleton>
+ </param>
+
+ <param
+ id="768"
+ group="1"
+ name="EyeBone_Bug"
+ wearable="shape"
+ edit_group="shape_eyes"
+ label_min="Eyes Sunken"
+ label_max="Eyes Bugged"
+ value_min="-2"
+ value_max="2">
+ <param_skeleton>
+ <bone
+ name="mEyeLeft"
+ scale="0 0 0"
+ offset=".005 0 0" />
+
+ <bone
+ name="mEyeRight"
+ scale="0 0 0"
+ offset=".005 0 0" />
+ </param_skeleton>
+ </param>
+
+ <param
+ id="655"
+ group="1"
+ name="Head Size"
+ label="Head Size"
+ wearable="shape"
+ edit_group="shape_head"
+ label_min="Small Head"
+ label_max="Big Head"
+ show_simple="true"
+ value_min="-.25"
+ value_max=".10">
+ <param_skeleton>
+ <bone
+ name="mSkull"
+ scale="1 1 1"
+ offset="0 0 0.1" />
+
+ <bone
+ name="mHead"
+ scale="1 1 1"
+ offset="0 0 0" />
+
+ <bone
+ name="mEyeLeft"
+ scale="1 1 1"
+ offset="0 0 0" />
+
+ <bone
+ name="mEyeRight"
+ scale="1 1 1"
+ offset="0 0 0" />
+ </param_skeleton>
+ </param>
+
+ <param
+ id="197"
+ group="1"
+ wearable="shoes"
+ name="Shoe_Heels"
+ edit_group="shoes"
+ label_min="No Heels"
+ label_max="High Heels"
+ value_min="0"
+ value_max="1">
+ <param_skeleton>
+ <bone
+ name="mFootRight"
+ scale="0 0 0"
+ offset="0 0 -.08" />
+
+ <bone
+ name="mFootLeft"
+ scale="0 0 0"
+ offset="0 0 -.08" />
+ </param_skeleton>
+ </param>
+
+ <param
+ id="502"
+ group="1"
+ wearable="shoes"
+ name="Shoe_Platform"
+ edit_group="shoes"
+ label_min="No Heels"
+ label_max="High Heels"
+ value_min="0"
+ value_max="1">
+ <param_skeleton>
+ <bone
+ name="mFootRight"
+ scale="0 0 0"
+ offset="0 0 -.07" />
+
+ <bone
+ name="mFootLeft"
+ scale="0 0 0"
+ offset="0 0 -.07" />
+ </param_skeleton>
+ </param>
+
+ <param
+ id="675"
+ group="0"
+ name="Hand Size"
+ wearable="shape"
+ edit_group="shape_torso"
+ edit_group_order="10"
+ label_min="Small Hands"
+ label_max="Large Hands"
+ value_min="-.3"
+ value_max=".3"
+ camera_elevation=".1"
+ camera_distance="1.4"
+ camera_angle="0">
+ <param_skeleton>
+ <bone
+ name="mWristRight"
+ scale="1 1 1"
+ offset="0 0 0" />
+
+ <bone
+ name="mWristLeft"
+ scale="1 1 1"
+ offset="0 0 0" />
+ </param_skeleton>
+ </param>
+
+ <param
+ id="683"
+ group="0"
+ name="Neck Thickness"
+ wearable="shape"
+ edit_group="shape_torso"
+ edit_group_order="2"
+ label_min="Skinny Neck"
+ label_max="Thick Neck"
+ value_min="-.4"
+ value_max=".2"
+ value_default="-.15"
+ camera_elevation=".3"
+ camera_distance=".8"
+ camera_angle="15">
+ <param_skeleton>
+ <bone
+ name="mNeck"
+ scale="1 1 0"
+ offset="0 0 0" />
+ </param_skeleton>
+ </param>
+
+ <param
+ id="689"
+ group="1"
+ wearable="shape"
+ name="EyeBone_Big_Eyes"
+ edit_group="shape_eyes"
+ label_min="Eyes Back"
+ label_max="Eyes Forward"
+ value_min="-1"
+ value_max="1">
+ <param_skeleton>
+ <bone
+ name="mEyeLeft"
+ scale="0 0 0"
+ offset="-.005 0 0" />
+
+ <bone
+ name="mEyeRight"
+ scale="0 0 0"
+ offset="-.005 0 0" />
+ </param_skeleton>
+ </param>
+
+ <param
+ id="692"
+ group="0"
+ name="Leg Length"
+ wearable="shape"
+ edit_group="shape_legs"
+ edit_group_order="2"
+ label_min="Short Legs"
+ label_max="Long Legs"
+ value_min="-1"
+ value_max="1"
+ camera_distance="2.5">
+ <param_skeleton>
+ <bone
+ name="mHipLeft"
+ scale="0 0 .2" />
+
+ <bone
+ name="mHipRight"
+ scale="0 0 .2" />
+
+ <bone
+ name="mKneeRight"
+ scale="0 0 .2" />
+
+ <bone
+ name="mKneeLeft"
+ scale="0 0 .2" />
+ </param_skeleton>
+ </param>
+
+ <param
+ id="693"
+ group="0"
+ name="Arm Length"
+ wearable="shape"
+ edit_group="shape_torso"
+ edit_group_order="9"
+ label_min="Short Arms"
+ label_max="Long arms"
+ value_min="-1"
+ value_max="1"
+ value_default=".6"
+ camera_distance="1.5">
+ <param_skeleton>
+ <bone
+ name="mShoulderLeft"
+ scale="0 .2 0" />
+
+ <bone
+ name="mShoulderRight"
+ scale="0 .2 0" />
+
+ <bone
+ name="mElbowRight"
+ scale="0 .3 0" />
+
+ <bone
+ name="mElbowLeft"
+ scale="0 .3 0" />
+ </param_skeleton>
+ </param>
+
+ <param
+ id="756"
+ group="0"
+ name="Neck Length"
+ wearable="shape"
+ edit_group="shape_torso"
+ edit_group_order="3"
+ label_min="Short Neck"
+ label_max="Long Neck"
+ value_min="-1"
+ value_max="1"
+ value_default="0"
+ camera_elevation=".3"
+ camera_distance=".8"
+ camera_angle="15">
+ <param_skeleton>
+ <bone
+ name="mNeck"
+ scale="0 0 .5" />
+ </param_skeleton>
+ </param>
+ <param
+ id="11001"
+ group="0"
+ name="Hover"
+ wearable="shape"
+ edit_group="shape_body"
+ edit_group_order="4"
+ label_min="Lower"
+ label_max="Higher"
+ value_min="-2"
+ value_max="2"
+ value_default="0"
+ camera_distance="2.5">
+ <param_skeleton />
+ </param>
+
+ </skeleton>
+
+ <mesh
+ type="hairMesh"
+ lod="0"
+ file_name="avatar_hair.llm"
+ min_pixel_width="320">
+ <!-- begin morph targets -->
+ <param
+ id="180"
+ group="1"
+ name="Hair_Volume"
+ label="Hair Volume"
+ show_simple="true"
+ wearable="hair"
+ clothing_morph="true"
+ edit_group="hair_style"
+ label_min="Less"
+ label_max="More"
+ value_min="0"
+ value_max="1.3"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="20">
+ <param_morph />
+ </param>
+
+ <param
+ id="761"
+ group="1"
+ name="Hair_Volume_Small"
+ label="Hair Volume"
+ show_simple="true"
+ wearable="hair"
+ edit_group="hair_style"
+ label_min="Less"
+ label_max="More"
+ value_min="0"
+ value_max="1.3"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="20">
+ <param_morph />
+ </param>
+
+ <param
+ id="181"
+ group="0"
+ name="Hair_Big_Front"
+ label="Big Hair Front"
+ wearable="hair"
+ edit_group="hair_style"
+ edit_group_order="5"
+ label_min="Less"
+ label_max="More"
+ value_min="-1"
+ value_max="1"
+ value_default="0.14"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="90">
+ <param_morph />
+ </param>
+
+ <param
+ id="182"
+ group="0"
+ name="Hair_Big_Top"
+ label="Big Hair Top"
+ wearable="hair"
+ edit_group="hair_style"
+ edit_group_order="6"
+ label_min="Less"
+ label_max="More"
+ value_min="-1"
+ value_max="1"
+ value_default=".7"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="90">
+ <param_morph />
+ </param>
+
+ <param
+ id="183"
+ group="0"
+ name="Hair_Big_Back"
+ clothing_morph="true"
+ label="Big Hair Back"
+ wearable="hair"
+ edit_group="hair_style"
+ edit_group_order="7"
+ label_min="Less"
+ label_max="More"
+ value_min="-1"
+ value_max="1"
+ value_default="0.05"
+ camera_elevation=".1"
+ camera_distance=".7"
+ camera_angle="90">
+ <param_morph />
+ </param>
+
+ <param
+ id="184"
+ group="0"
+ name="Hair_Spiked"
+ label="Spiked Hair"
+ show_simple="true"
+ wearable="hair"
+ clothing_morph="true"
+ edit_group="hair_style"
+ edit_group_order="15"
+ label_min="No Spikes"
+ label_max="Big Spikes"
+ value_min="0"
+ value_max="1"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="20">
+ <param_morph />
+ </param>
+
+ <param
+ id="140"
+ group="0"
+ name="Hair_Part_Middle"
+ label="Middle Part"
+ wearable="hair"
+ edit_group="hair_style"
+ edit_group_order="17"
+ label_min="No Part"
+ label_max="Part"
+ value_min="0"
+ value_max="2"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="0">
+ <param_morph />
+ </param>
+
+ <param
+ id="141"
+ group="0"
+ name="Hair_Part_Right"
+ label="Right Part"
+ wearable="hair"
+ edit_group="hair_style"
+ edit_group_order="18"
+ label_min="No Part"
+ label_max="Part"
+ value_min="0"
+ value_max="2"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="0">
+ <param_morph />
+ </param>
+
+ <param
+ id="142"
+ group="0"
+ name="Hair_Part_Left"
+ label="Left Part"
+ wearable="hair"
+ edit_group="hair_style"
+ edit_group_order="19"
+ label_min="No Part"
+ label_max="Part"
+ value_min="0"
+ value_max="2"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="0">
+ <param_morph />
+ </param>
+
+ <param
+ id="143"
+ group="0"
+ name="Hair_Sides_Full"
+ label="Full Hair Sides"
+ show_simple="true"
+ wearable="hair"
+ edit_group="hair_style"
+ edit_group_order="11"
+ label_min="Mowhawk"
+ label_max="Full Sides"
+ value_min="-4"
+ value_max="1.5"
+ value_default="0.125"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="20">
+ <param_morph />
+ </param>
+
+ <param
+ id="144"
+ group="1"
+ name="Bangs_Front_Up"
+ label="Front Bangs Up"
+ wearable="hair"
+ edit_group="hair_style"
+ label_min="Bangs"
+ label_max="Bangs Up"
+ value_min="0"
+ value_max="1"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="20">
+ <param_morph />
+ </param>
+
+ <param
+ id="145"
+ group="1"
+ clothing_morph="true"
+ name="Bangs_Front_Down"
+ label="Front Bangs Down"
+ wearable="hair"
+ edit_group="hair_style"
+ label_min="Bangs"
+ label_max="Bangs Down"
+ value_min="0"
+ value_max="5"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="20">
+ <param_morph />
+ </param>
+
+ <param
+ id="146"
+ group="1"
+ name="Bangs_Sides_Up"
+ label="Side Bangs Up"
+ wearable="hair"
+ edit_group="hair_style"
+ label_min="Side Bangs"
+ label_max="Side Bangs Up"
+ value_min="0"
+ value_max="1"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="20">
+ <param_morph />
+ </param>
+
+ <param
+ id="147"
+ group="1"
+ clothing_morph="true"
+ name="Bangs_Sides_Down"
+ label="Side Bangs Down"
+ wearable="hair"
+ edit_group="hair_style"
+ label_min="Side Bangs"
+ label_max="Side Bangs Down"
+ value_min="0"
+ value_max="2"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="20">
+ <param_morph />
+ </param>
+
+ <param
+ id="148"
+ group="1"
+ name="Bangs_Back_Up"
+ label="Back Bangs Up"
+ wearable="hair"
+ edit_group="hair_style"
+ label_min="Back Bangs"
+ label_max="Back Bangs Up"
+ value_min="0"
+ value_max="1"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="150">
+ <param_morph />
+ </param>
+
+ <param
+ id="149"
+ group="1"
+ name="Bangs_Back_Down"
+ label="Back Bangs Down"
+ clothing_morph="true"
+ wearable="hair"
+ edit_group="hair_style"
+ label_min="Back Bangs"
+ label_max="Back Bangs Down"
+ value_min="0"
+ value_max="2"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="150">
+ <param_morph />
+ </param>
+
+ <param
+ id="171"
+ group="1"
+ name="Hair_Front_Down"
+ label="Front Hair Down"
+ wearable="hair"
+ edit_group="hair_style"
+ label_min="Front Hair"
+ label_max="Front Hair Down"
+ value_min="0"
+ value_max="1"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="20">
+ <param_morph />
+ </param>
+
+ <param
+ id="172"
+ group="1"
+ name="Hair_Front_Up"
+ label="Front Hair Up"
+ wearable="hair"
+ edit_group="hair_style"
+ label_min="Front Hair"
+ label_max="Front Hair Up"
+ value_min="0"
+ value_max="1"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="20">
+ <param_morph />
+ </param>
+
+ <param
+ id="173"
+ group="1"
+ name="Hair_Sides_Down"
+ label="Sides Hair Down"
+ wearable="hair"
+ edit_group="hair_style"
+ label_min="Sides Hair"
+ label_max="Sides Hair Down"
+ value_min="0"
+ value_max="1"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="20">
+ <param_morph />
+ </param>
+
+ <param
+ id="174"
+ group="1"
+ name="Hair_Sides_Up"
+ label="Sides Hair Up"
+ wearable="hair"
+ edit_group="hair_style"
+ label_min="Sides Hair"
+ label_max="Sides Hair Up"
+ value_min="0"
+ value_max="1"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="20">
+ <param_morph />
+ </param>
+
+ <param
+ id="175"
+ group="1"
+ name="Hair_Back_Down"
+ label="Back Hair Down"
+ clothing_morph="true"
+ wearable="hair"
+ edit_group="hair_style"
+ label_min="Back Hair"
+ label_max="Back Hair Down"
+ value_min="0"
+ value_max="3"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="150">
+ <param_morph />
+ </param>
+
+ <param
+ id="176"
+ group="1"
+ name="Hair_Back_Up"
+ label="Back Hair Up"
+ wearable="hair"
+ edit_group="hair_style"
+ label_min="Back Hair"
+ label_max="Back Hair Up"
+ value_min="0"
+ value_max="1"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="150">
+ <param_morph />
+ </param>
+
+ <param
+ id="177"
+ group="0"
+ name="Hair_Rumpled"
+ label="Rumpled Hair"
+ show_simple="true"
+ wearable="hair"
+ clothing_morph="true"
+ edit_group="hair_style"
+ edit_group_order="14.5"
+ label_min="Smooth Hair"
+ label_max="Rumpled Hair"
+ value_min="0"
+ value_max="1"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="20">
+ <param_morph />
+ </param>
+
+ <param
+ id="178"
+ group="1"
+ name="Hair_Swept_Back"
+ label="Swept Back Hair"
+ wearable="hair"
+ edit_group="hair_style"
+ label_min="NotHair"
+ label_max="Swept Back"
+ value_min="0"
+ value_max="1"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="90">
+ <param_morph />
+ </param>
+
+ <param
+ id="179"
+ group="1"
+ name="Hair_Swept_Forward"
+ label="Swept Forward Hair"
+ wearable="hair"
+ edit_group="hair_style"
+ label_min="Hair"
+ label_max="Swept Forward"
+ value_min="0"
+ value_max="1"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="90">
+ <param_morph />
+ </param>
+
+ <param
+ id="190"
+ group="1"
+ name="Hair_Tilt_Right"
+ label="Hair Tilted Right"
+ wearable="hair"
+ edit_group="hair_style"
+ label_min="Hair"
+ label_max="Tilt Right"
+ value_min="0"
+ value_max="1"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="0">
+ <param_morph />
+ </param>
+
+ <param
+ id="191"
+ group="1"
+ name="Hair_Tilt_Left"
+ label="Hair Tilted Left"
+ wearable="hair"
+ edit_group="hair_style"
+ label_min="Hair"
+ label_max="Tilt Left"
+ value_min="0"
+ value_max="1"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="0">
+ <param_morph />
+ </param>
+
+ <param
+ id="192"
+ group="0"
+ name="Bangs_Part_Middle"
+ label="Part Bangs"
+ wearable="hair"
+ edit_group="hair_style"
+ edit_group_order="20"
+ label_min="No Part"
+ label_max="Part Bangs"
+ value_min="0"
+ value_max="1"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="0">
+ <param_morph />
+ </param>
+
+ <param
+ id="640"
+ group="1"
+ name="Hair_Egg_Head"
+ wearable="hair"
+ edit_group="hair_style"
+ cross_wearable="true"
+ value_min="-1.3"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="641"
+ group="1"
+ name="Hair_Squash_Stretch_Head"
+ wearable="hair"
+ edit_group="hair_style"
+ cross_wearable="true"
+ value_min="-.5"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="642"
+ group="1"
+ name="Hair_Square_Head"
+ wearable="hair"
+ edit_group="hair_style"
+ cross_wearable="true"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="643"
+ group="1"
+ name="Hair_Round_Head"
+ wearable="hair"
+ edit_group="hair_style"
+ cross_wearable="true"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="644"
+ group="1"
+ name="Hair_Forehead_Round"
+ wearable="hair"
+ edit_group="hair_style"
+ cross_wearable="true"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="645"
+ group="1"
+ name="Hair_Forehead_Slant"
+ wearable="hair"
+ edit_group="hair_style"
+ cross_wearable="true"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="774"
+ group="1"
+ name="Shear_Head_Hair"
+ wearable="hair"
+ edit_group="hair_style"
+ cross_wearable="true"
+ value_min="-2"
+ value_max="2">
+ <param_morph />
+ </param>
+
+ <param
+ id="771"
+ group="1"
+ name="Elongate_Head_Hair"
+ wearable="hair"
+ edit_group="hair_style"
+ cross_wearable="true"
+ value_min="-1"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="674"
+ group="0"
+ name="Hair_Shear_Back"
+ wearable="hair"
+ edit_group="hair_style"
+ edit_group_order="12"
+ label="Shear Back"
+ label_min="Full Back"
+ label_max="Sheared Back"
+ value_min="-1"
+ value_max="2"
+ value_default="-0.3"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="100">
+ <param_morph />
+ </param>
+
+ <param
+ id="762"
+ group="0"
+ name="Hair_Shear_Front"
+ wearable="hair"
+ edit_group="hair_style"
+ edit_group_order="11.8"
+ label="Shear Front"
+ show_simple="true"
+ label_min="Full Front"
+ label_max="Sheared Front"
+ value_min="0"
+ value_max="3"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="30">
+ <param_morph />
+ </param>
+
+ <param
+ id="754"
+ group="0"
+ name="Hair_Taper_Back"
+ wearable="hair"
+ edit_group="hair_style"
+ edit_group_order="14"
+ label="Taper Back"
+ label_min="Wide Back"
+ label_max="Narrow Back"
+ value_min="-1"
+ value_max="2"
+ value_default="0"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="160">
+ <param_morph />
+ </param>
+
+ <param
+ id="755"
+ group="0"
+ name="Hair_Taper_Front"
+ wearable="hair"
+ edit_group="hair_style"
+ edit_group_order="13"
+ label="Taper Front"
+ label_min="Wide Front"
+ label_max="Narrow Front"
+ value_min="-1.5"
+ value_max="1.5"
+ value_default="0.05"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="20">
+ <param_morph />
+ </param>
+
+ <param
+ id="782"
+ group="1"
+ clothing_morph="true"
+ name="Hair_Pigtails_Short"
+ wearable="hair"
+ edit_group="hair_style"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="783"
+ group="1"
+ clothing_morph="true"
+ name="Hair_Pigtails_Med"
+ wearable="hair"
+ edit_group="hair_style"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="790"
+ group="1"
+ clothing_morph="true"
+ name="Hair_Pigtails_Medlong"
+ wearable="hair"
+ edit_group="hair_style"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="784"
+ group="1"
+ clothing_morph="true"
+ name="Hair_Pigtails_Long"
+ wearable="hair"
+ edit_group="hair_style"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="786"
+ group="1"
+ name="Hair_Ponytail_Short"
+ wearable="hair"
+ edit_group="hair_style"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="787"
+ group="1"
+ name="Hair_Ponytail_Med"
+ wearable="hair"
+ edit_group="hair_style"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="788"
+ group="1"
+ name="Hair_Ponytail_Long"
+ clothing_morph="true"
+ wearable="hair"
+ edit_group="hair_style"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <!-- #end morph targets -->
+ </mesh>
+
+ <mesh
+ type="hairMesh"
+ lod="1"
+ file_name="avatar_hair_1.llm"
+ min_pixel_width="160"
+ reference="avatar_hair.llm">
+ </mesh>
+
+ <mesh
+ type="hairMesh"
+ lod="2"
+ file_name="avatar_hair_2.llm"
+ min_pixel_width="80"
+ reference="avatar_hair.llm">
+ </mesh>
+
+ <mesh
+ type="hairMesh"
+ lod="3"
+ file_name="avatar_hair_3.llm"
+ min_pixel_width="40"
+ reference="avatar_hair.llm">
+ </mesh>
+
+ <mesh
+ type="hairMesh"
+ lod="4"
+ file_name="avatar_hair_4.llm"
+ min_pixel_width="20"
+ reference="avatar_hair.llm">
+ </mesh>
+
+ <mesh
+ type="hairMesh"
+ lod="5"
+ file_name="avatar_hair_5.llm"
+ min_pixel_width="0"
+ reference="avatar_hair.llm">
+ </mesh>
+
+ <mesh
+ type="headMesh"
+ lod="0"
+ file_name="avatar_head.llm"
+ min_pixel_width="320">
+ <!--
+ begin morph targets
+ #############
+ tweakable morphs
+ #############
+ -->
+ <param
+ id="1"
+ group="0"
+ name="Big_Brow"
+ label="Brow Size"
+ wearable="shape"
+ edit_group="shape_head"
+ edit_group_order="7"
+ label_min="Small"
+ label_max="Large"
+ value_min="-.3"
+ value_max="2"
+ camera_elevation=".1"
+ camera_distance=".4"
+ camera_angle="45">
+ <param_morph />
+ </param>
+
+ <param
+ id="2"
+ group="0"
+ name="Nose_Big_Out"
+ label="Nose Size"
+ wearable="shape"
+ edit_group="shape_nose"
+ edit_group_order="1"
+ label_min="Small"
+ label_max="Large"
+ show_simple="true"
+ value_min="-0.8"
+ value_max="2.5"
+ camera_elevation=".1"
+ camera_distance=".35"
+ camera_angle="50">
+ <param_morph />
+ </param>
+
+ <param
+ id="4"
+ group="0"
+ name="Broad_Nostrils"
+ label="Nostril Width"
+ wearable="shape"
+ edit_group="shape_nose"
+ edit_group_order="3"
+ label_min="Narrow"
+ label_max="Broad"
+ value_min="-.5"
+ value_max="1"
+ camera_elevation=".1"
+ camera_distance=".3"
+ camera_angle="-20">
+ <param_morph />
+ </param>
+
+ <param
+ id="759"
+ group="0"
+ name="Low_Septum_Nose"
+ label="Nostril Division"
+ wearable="shape"
+ edit_group="shape_nose"
+ edit_group_order="3.5"
+ label_min="High"
+ label_max="Low"
+ value_min="-1"
+ value_max="1.5"
+ value_default="0.5"
+ camera_elevation=".1"
+ camera_distance=".3"
+ camera_angle="-20">
+ <param_morph />
+ </param>
+
+ <param
+ id="517"
+ group="0"
+ name="Wide_Nose"
+ label="Nose Width"
+ wearable="shape"
+ edit_group="shape_nose"
+ edit_group_order="2"
+ label_min="Narrow"
+ label_max="Wide"
+ show_simple="true"
+ value_min="-.5"
+ value_max="1"
+ camera_elevation=".1"
+ camera_distance=".3"
+ camera_angle="-20">
+ <param_morph />
+ </param>
+
+ <param
+ id="5"
+ group="0"
+ name="Cleft_Chin"
+ label="Chin Cleft"
+ wearable="shape"
+ edit_group="shape_chin"
+ edit_group_order="6"
+ label_min="Round"
+ label_max="Cleft"
+ value_min="-.1"
+ value_max="1"
+ camera_elevation="0"
+ camera_distance=".28"
+ camera_angle="-20">
+ <param_morph />
+ </param>
+
+ <param
+ id="6"
+ group="0"
+ name="Bulbous_Nose_Tip"
+ label="Nose Tip Shape"
+ wearable="shape"
+ edit_group="shape_nose"
+ edit_group_order="8"
+ label_min="Pointy"
+ label_max="Bulbous"
+ value_min="-.3"
+ value_max="1"
+ camera_elevation=".1"
+ camera_distance=".35"
+ camera_angle="15">
+ <param_morph />
+ </param>
+
+ <param
+ id="7"
+ group="0"
+ name="Weak_Chin"
+ label="Chin Angle"
+ wearable="shape"
+ edit_group="shape_chin"
+ edit_group_order="1"
+ label_min="Chin Out"
+ label_max="Chin In"
+ value_min="-.5"
+ value_max=".5"
+ camera_elevation=".1"
+ camera_distance=".4"
+ camera_angle="45">
+ <param_morph />
+ </param>
+
+ <param
+ id="8"
+ group="0"
+ name="Double_Chin"
+ label="Chin-Neck"
+ wearable="shape"
+ edit_group="shape_chin"
+ edit_group_order="8"
+ label_min="Tight Chin"
+ label_max="Double Chin"
+ value_min="-.5"
+ value_max="1.5"
+ camera_elevation="-.1"
+ camera_distance=".3"
+ camera_angle="60">
+ <param_morph />
+ </param>
+
+ <param
+ id="10"
+ group="0"
+ name="Sunken_Cheeks"
+ label="Lower Cheeks"
+ wearable="shape"
+ edit_group="shape_head"
+ edit_group_order="9"
+ label_min="Well-Fed"
+ label_max="Sunken"
+ show_simple="true"
+ value_min="-1.5"
+ value_max="3"
+ camera_elevation=".1"
+ camera_distance=".4"
+ camera_angle="5">
+ <param_morph />
+ </param>
+
+ <param
+ id="11"
+ group="0"
+ name="Noble_Nose_Bridge"
+ label="Upper Bridge"
+ wearable="shape"
+ edit_group="shape_nose"
+ edit_group_order="5"
+ label_min="Low"
+ label_max="High"
+ value_min="-.5"
+ value_max="1.5"
+ camera_elevation=".1"
+ camera_distance=".35"
+ camera_angle="70">
+ <param_morph />
+ </param>
+
+ <param
+ id="758"
+ group="0"
+ name="Lower_Bridge_Nose"
+ label="Lower Bridge"
+ wearable="shape"
+ edit_group="shape_nose"
+ edit_group_order="5.5"
+ label_min="Low"
+ label_max="High"
+ value_min="-1.5"
+ value_max="1.5"
+ camera_elevation=".1"
+ camera_distance=".35"
+ camera_angle="70">
+ <param_morph />
+ </param>
+
+ <param
+ id="12"
+ group="0"
+ name="Jowls"
+ wearable="shape"
+ edit_group="shape_chin"
+ edit_group_order="5"
+ label_min="Less"
+ label_max="More"
+ value_min="-.5"
+ value_max="2.5"
+ camera_elevation=".1"
+ camera_distance=".4"
+ camera_angle="0">
+ <param_morph />
+ </param>
+
+ <param
+ id="13"
+ group="0"
+ name="Cleft_Chin_Upper"
+ label="Upper Chin Cleft"
+ wearable="shape"
+ edit_group="shape_chin"
+ edit_group_order="7"
+ label_min="Round"
+ label_max="Cleft"
+ value_min="0"
+ value_max="1.5"
+ camera_elevation="0"
+ camera_distance=".28"
+ camera_angle="-20">
+ <param_morph />
+ </param>
+
+ <param
+ id="14"
+ group="0"
+ name="High_Cheek_Bones"
+ label="Cheek Bones"
+ wearable="shape"
+ edit_group="shape_head"
+ edit_group_order="10"
+ label_min="Low"
+ label_max="High"
+ value_min="-.5"
+ value_max="1"
+ camera_elevation=".1"
+ camera_distance=".3"
+ camera_angle="-20">
+ <param_morph />
+ </param>
+
+ <param
+ id="15"
+ group="0"
+ name="Ears_Out"
+ label="Ear Angle"
+ wearable="shape"
+ edit_group="shape_ears"
+ edit_group_order="2"
+ label_min="In"
+ label_max="Out"
+ value_min="-.5"
+ value_max="1.5"
+ camera_elevation=".1"
+ camera_distance=".3"
+ camera_angle="-20">
+ <param_morph />
+ </param>
+
+ <!--Pointy eyebrows became a driver/driven param with new max value for backwards compatibility between 1.0 and 1.1-->
+ <param
+ id="870"
+ group="1"
+ name="Pointy_Eyebrows"
+ label="Eyebrow Points"
+ wearable="hair"
+ edit_group="hair_eyebrows"
+ edit_group_order="4"
+ label_min="Smooth"
+ label_max="Pointy"
+ value_min="-.5"
+ value_max="1"
+ camera_elevation=".1"
+ camera_distance=".3">
+ <param_morph />
+ </param>
+
+ <param
+ id="17"
+ group="0"
+ name="Square_Jaw"
+ label="Jaw Shape"
+ wearable="shape"
+ edit_group="shape_chin"
+ edit_group_order="2"
+ label_min="Pointy"
+ label_max="Square"
+ value_min="-.5"
+ value_max="1"
+ camera_distance=".3"
+ camera_elevation=".04"
+ camera_angle="-20">
+ <param_morph />
+ </param>
+
+ <param
+ id="18"
+ group="0"
+ name="Puffy_Upper_Cheeks"
+ label="Upper Cheeks"
+ wearable="shape"
+ edit_group="shape_head"
+ edit_group_order="8"
+ label_min="Thin"
+ label_max="Puffy"
+ value_min="-1.5"
+ value_max="2.5"
+ camera_elevation=".1"
+ camera_distance=".3"
+ camera_angle="-20">
+ <param_morph />
+ </param>
+
+ <param
+ id="19"
+ group="0"
+ name="Upturned_Nose_Tip"
+ label="Nose Tip Angle"
+ wearable="shape"
+ edit_group="shape_nose"
+ edit_group_order="7"
+ label_min="Downturned"
+ label_max="Upturned"
+ value_min="-1.5"
+ value_max="1"
+ camera_elevation=".1"
+ camera_distance=".35"
+ camera_angle="15">
+ <param_morph />
+ </param>
+
+ <param
+ id="20"
+ group="0"
+ name="Bulbous_Nose"
+ label="Nose Thickness"
+ wearable="shape"
+ edit_group="shape_nose"
+ edit_group_order="4"
+ label_min="Thin Nose"
+ label_max="Bulbous Nose"
+ show_simple="true"
+ value_min="-.5"
+ value_max="1.5"
+ camera_elevation=".1"
+ camera_distance=".3">
+ <param_morph />
+ </param>
+
+ <param
+ id="21"
+ group="0"
+ name="Upper_Eyelid_Fold"
+ label="Upper Eyelid Fold"
+ wearable="shape"
+ edit_group="shape_eyes"
+ edit_group_order="5"
+ label_min="Uncreased"
+ label_max="Creased"
+ value_min="-0.2"
+ value_max="1.3"
+ camera_elevation=".1"
+ camera_distance=".35">
+ <param_morph />
+ </param>
+
+ <param
+ id="22"
+ group="0"
+ name="Attached_Earlobes"
+ label="Attached Earlobes"
+ wearable="shape"
+ edit_group="shape_ears"
+ edit_group_order="3"
+ label_min="Unattached"
+ label_max="Attached"
+ value_min="0"
+ value_max="1"
+ camera_elevation=".1"
+ camera_distance=".3"
+ camera_angle="45">
+ <param_morph />
+ </param>
+
+ <param
+ id="23"
+ group="0"
+ name="Baggy_Eyes"
+ label="Eye Bags"
+ wearable="shape"
+ edit_group="shape_eyes"
+ edit_group_order="6"
+ label_min="Smooth"
+ label_max="Baggy"
+ value_min="-.5"
+ value_max="1.5"
+ camera_elevation=".1"
+ camera_distance=".35">
+ <param_morph />
+ </param>
+
+ <param
+ id="765"
+ group="0"
+ name="Puffy_Lower_Lids"
+ label="Puffy Eyelids"
+ wearable="shape"
+ edit_group="shape_eyes"
+ edit_group_order="6.1"
+ label_min="Flat"
+ label_max="Puffy"
+ value_min="-.3"
+ value_max="2.5"
+ camera_elevation=".1"
+ camera_distance=".35">
+ <param_morph />
+ </param>
+
+ <param
+ id="24"
+ group="0"
+ name="Wide_Eyes"
+ label="Eye Opening"
+ wearable="shape"
+ edit_group="shape_eyes"
+ edit_group_order="1.1"
+ label_min="Narrow"
+ label_max="Wide"
+ value_min="-1.5"
+ value_max="2"
+ show_simple="true"
+ camera_elevation=".1"
+ camera_distance=".35">
+ <param_morph />
+ </param>
+
+ <param
+ id="25"
+ group="0"
+ name="Wide_Lip_Cleft"
+ label="Lip Cleft"
+ wearable="shape"
+ edit_group="shape_mouth"
+ edit_group_order="6"
+ label_min="Narrow"
+ label_max="Wide"
+ value_min="-.8"
+ value_max="1.5"
+ camera_elevation="0"
+ camera_distance=".28">
+ <param_morph />
+ </param>
+
+ <param
+ id="764"
+ group="0"
+ name="Lip_Cleft_Deep"
+ label="Lip Cleft Depth"
+ wearable="shape"
+ edit_group="shape_mouth"
+ edit_group_order="5.8"
+ label_min="Shallow"
+ label_max="Deep"
+ value_min="-.5"
+ value_max="1.2"
+ camera_elevation="0"
+ camera_distance=".28">
+ <param_morph />
+ </param>
+
+ <param
+ id="26"
+ group="1"
+ wearable="shape"
+ name="Lips_Thin"
+ edit_group="driven"
+ value_min="0"
+ value_max=".7">
+ <param_morph />
+ </param>
+
+ <param
+ id="27"
+ group="0"
+ name="Wide_Nose_Bridge"
+ label="Bridge Width"
+ wearable="shape"
+ edit_group="shape_nose"
+ edit_group_order="6"
+ label_min="Narrow"
+ label_max="Wide"
+ value_min="-1.3"
+ value_max="1.2"
+ camera_elevation=".1"
+ camera_distance=".3"
+ camera_angle="-20">
+ <param_morph />
+ </param>
+
+ <param
+ id="28"
+ group="1"
+ name="Lips_Fat"
+ wearable="shape"
+ edit_group="driven"
+ value_min="0"
+ value_max="2">
+ <param_morph />
+ </param>
+
+ <param
+ id="29"
+ group="1"
+ name="Wide_Upper_Lip"
+ wearable="shape"
+ edit_group="driven"
+ value_min="-.7"
+ value_max="1.3">
+ <param_morph />
+ </param>
+
+ <param
+ id="30"
+ group="1"
+ name="Wide_Lower_Lip"
+ wearable="shape"
+ edit_group="driven"
+ value_min="-.7"
+ value_max="1.3">
+ <param_morph />
+ </param>
+
+ <!--Arced eyebrows became a driver/driven param with new max value for backwards compatibility between 1.0 and 1.1-->
+ <param
+ id="872"
+ group="1"
+ name="Arced_Eyebrows"
+ label="Eyebrow Arc"
+ wearable="hair"
+ edit_group="hair_eyebrows"
+ edit_group_order="3"
+ label_min="Flat"
+ label_max="Arced"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <!--Lower eyebrows became a driver/driven param with new min value for backwards compatibility between 1.0 and 1.1-->
+ <param
+ id="871"
+ group="1"
+ name="Lower_Eyebrows"
+ label="Eyebrow Height"
+ show_simple="true"
+ wearable="hair"
+ edit_group="hair_eyebrows"
+ edit_group_order="2.5"
+ label_min="Higher"
+ label_max="Lower"
+ value_min="-2"
+ value_max="2">
+ <param_morph />
+ </param>
+
+ <param
+ id="35"
+ group="0"
+ name="Big_Ears"
+ label="Ear Size"
+ wearable="shape"
+ edit_group="shape_ears"
+ edit_group_order="1"
+ label_min="Small"
+ label_max="Large"
+ value_min="-1"
+ value_max="2"
+ camera_elevation=".1"
+ camera_distance=".3"
+ camera_angle="45">
+ <param_morph />
+ </param>
+
+ <param
+ id="796"
+ group="0"
+ name="Pointy_Ears"
+ label="Ear Tips"
+ wearable="shape"
+ edit_group="shape_ears"
+ edit_group_order="4"
+ label_min="Flat"
+ label_max="Pointy"
+ value_min="-.4"
+ value_max="3"
+ camera_elevation=".1"
+ camera_distance=".3"
+ camera_angle="45">
+ <param_morph />
+ </param>
+
+ <param
+ id="185"
+ group="0"
+ name="Deep_Chin"
+ label="Chin Depth"
+ wearable="shape"
+ edit_group="shape_chin"
+ edit_group_order="3"
+ label_min="Shallow"
+ label_max="Deep"
+ value_min="-1"
+ value_max="1"
+ camera_elevation=".1"
+ camera_distance=".4"
+ camera_angle="30">
+ <param_morph />
+ </param>
+
+ <param
+ id="186"
+ group="1"
+ name="Egg_Head"
+ label="Egg Head"
+ wearable="shape"
+ edit_group="shape_head"
+ label_min="Chin Heavy"
+ label_max="Forehead Heavy"
+ value_min="-1.3"
+ value_max="1"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="20">
+ <param_morph />
+ </param>
+
+ <param
+ id="187"
+ group="1"
+ name="Squash_Stretch_Head"
+ label="Squash/Stretch Head"
+ wearable="shape"
+ edit_group="shape_head"
+ label_min="Squash Head"
+ label_max="Stretch Head"
+ value_min="-.5"
+ value_max="1"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="20">
+ <param_morph>
+ <volume_morph
+ name="HEAD"
+ scale="-0.008 -0.006 0.015"/>
+ </param_morph>
+ </param>
+
+ <param
+ id="188"
+ group="1"
+ name="Square_Head"
+ wearable="shape"
+ label_min="Less Square"
+ label_max="More Square"
+ value_min="0"
+ value_max=".7"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="20">
+ <param_morph />
+ </param>
+
+ <param
+ id="189"
+ group="1"
+ wearable="shape"
+ name="Round_Head"
+ label_min="Less Round"
+ label_max="More Round"
+ value_min="0"
+ value_max="1"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="20">
+ <param_morph />
+ </param>
+
+ <param
+ id="194"
+ group="1"
+ name="Eye_Spread"
+ wearable="shape"
+ edit_group="shape_eyes"
+ label_min="Eyes Together"
+ label_max="Eyes Spread"
+ value_min="-2"
+ value_max="2">
+ <param_morph />
+ </param>
+
+ <param
+ id="400"
+ sex="male"
+ group="1"
+ name="Displace_Hair_Facial"
+ label="Hair Thickess"
+ wearable="hair"
+ edit_group="hair_facial"
+ label_min="Cropped Hair"
+ label_max="Bushy Hair"
+ value_min="0"
+ value_max="2">
+ <param_morph />
+ </param>
+
+ <param
+ id="506"
+ group="0"
+ name="Mouth_Height"
+ wearable="shape"
+ label="Mouth Position"
+ show_simple="true"
+ edit_group="shape_mouth"
+ edit_group_order="4"
+ label_min="High"
+ label_max="Low"
+ value_min="-2"
+ value_max="2"
+ camera_distance=".3"
+ camera_elevation=".04">
+ <param_morph />
+ </param>
+
+ <param
+ id="633"
+ group="1"
+ name="Fat_Head"
+ label="Fat Head"
+ wearable="shape"
+ edit_group="shape_body"
+ label_min="Skinny"
+ label_max="Fat"
+ value_min="0"
+ value_max="1"
+ camera_elevation=".3">
+ <param_morph/>
+ </param>
+
+ <param
+ id="630"
+ group="1"
+ name="Forehead_Round"
+ label="Round Forehead"
+ wearable="shape"
+ label_min="Less"
+ label_max="More"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="631"
+ group="1"
+ name="Forehead_Slant"
+ label="Slanted Forehead"
+ wearable="shape"
+ label_min="Less"
+ label_max="More"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="650"
+ group="0"
+ name="Eyelid_Corner_Up"
+ label="Outer Eye Corner"
+ wearable="shape"
+ edit_group="shape_eyes"
+ edit_group_order="4"
+ label_min="Corner Down"
+ label_max="Corner Up"
+ value_min="-1.3"
+ value_max="1.2"
+ camera_elevation=".1"
+ camera_distance=".30">
+ <param_morph />
+ </param>
+
+ <param
+ id="880"
+ group="0"
+ name="Eyelid_Inner_Corner_Up"
+ label="Inner Eye Corner"
+ wearable="shape"
+ edit_group="shape_eyes"
+ edit_group_order="4.2"
+ label_min="Corner Down"
+ label_max="Corner Up"
+ value_min="-1.3"
+ value_max="1.2"
+ camera_elevation=".1"
+ camera_distance=".30">
+ <param_morph />
+ </param>
+
+
+ <param
+ id="653"
+ group="0"
+ name="Tall_Lips"
+ wearable="shape"
+ label="Lip Fullness"
+ show_simple="true"
+ edit_group="shape_mouth"
+ edit_group_order="2"
+ label_min="Less Full"
+ label_max="More Full"
+ value_min="-1"
+ value_max="2"
+ camera_distance=".3"
+ camera_elevation=".04">
+ <param_morph />
+ </param>
+
+ <param
+ id="656"
+ group="0"
+ name="Crooked_Nose"
+ wearable="shape"
+ label="Crooked Nose"
+ edit_group="shape_nose"
+ edit_group_order="9"
+ label_min="Nose Left"
+ label_max="Nose Right"
+ value_min="-2"
+ value_max="2"
+ camera_distance=".3"
+ camera_elevation=".04"
+ camera_angle="-20">
+ <param_morph />
+ </param>
+
+ <param
+ id="657"
+ group="1"
+ name="Smile_Mouth"
+ wearable="shape"
+ label="Mouth Corner"
+ edit_group="shape_mouth"
+ label_min="Corner Normal"
+ label_max="Corner Up"
+ value_min="0"
+ value_max="1.4"
+ camera_distance=".3"
+ camera_elevation=".04">
+ <param_morph />
+ </param>
+
+ <param
+ id="658"
+ group="1"
+ name="Frown_Mouth"
+ wearable="shape"
+ label="Mouth Corner"
+ edit_group="shape_mouth"
+ label_min="Corner Normal"
+ label_max="Corner Down"
+ value_min="0"
+ value_max="1.2"
+ camera_distance=".3"
+ camera_elevation=".04">
+ <param_morph />
+ </param>
+
+ <param
+ id="797"
+ group="1"
+ name="Fat_Upper_Lip"
+ wearable="shape"
+ label="Fat Upper Lip"
+ edit_group="shape_mouth"
+ label_min="Normal Upper"
+ label_max="Fat Upper"
+ value_min="0"
+ value_max="1.5"
+ camera_distance=".3"
+ camera_elevation=".04">
+ <param_morph />
+ </param>
+
+ <param
+ id="798"
+ group="1"
+ name="Fat_Lower_Lip"
+ wearable="shape"
+ label="Fat Lower Lip"
+ edit_group="shape_mouth"
+ label_min="Normal Lower"
+ label_max="Fat Lower"
+ value_min="0"
+ value_max="1.5"
+ camera_distance=".3"
+ camera_elevation=".04">
+ <param_morph />
+ </param>
+
+ <param
+ id="660"
+ group="1"
+ name="Shear_Head"
+ wearable="shape"
+ label="Shear Face"
+ edit_group="shape_head"
+ label_min="Shear Left"
+ label_max="Shear Right"
+ value_min="-2"
+ value_max="2"
+ value_default="0"
+ camera_distance=".5"
+ camera_elevation=".04">
+ <param_morph />
+ </param>
+
+ <param
+ id="770"
+ group="1"
+ name="Elongate_Head"
+ wearable="shape"
+ label="Shear Face"
+ edit_group="shape_head"
+ label_min="Flat Head"
+ label_max="Long Head"
+ value_min="-1"
+ value_max="1"
+ value_default="0"
+ camera_distance=".5"
+ camera_elevation=".04">
+ <param_morph>
+ <volume_morph
+ name="HEAD"
+ scale="0.02 0.0 0.0"/>
+ </param_morph>
+ </param>
+
+ <param
+ id="663"
+ group="0"
+ name="Shift_Mouth"
+ wearable="shape"
+ label="Shift Mouth"
+ edit_group="shape_mouth"
+ edit_group_order="7"
+ label_min="Shift Left"
+ label_max="Shift Right"
+ value_min="-2"
+ value_max="2"
+ value_default="0"
+ camera_distance=".35"
+ camera_elevation=".04"
+ camera_angle="-20">
+ <param_morph />
+ </param>
+
+ <param
+ id="664"
+ group="0"
+ name="Pop_Eye"
+ wearable="shape"
+ label="Eye Pop"
+ edit_group="shape_eyes"
+ edit_group_order="8"
+ label_min="Pop Right Eye"
+ label_max="Pop Left Eye"
+ value_min="-1.3"
+ value_max="1.3"
+ value_default="0"
+ camera_elevation=".1"
+ camera_distance=".35">
+ <param_morph />
+ </param>
+
+ <param
+ id="760"
+ group="0"
+ name="Jaw_Angle"
+ wearable="shape"
+ label="Jaw Angle"
+ edit_group="shape_chin"
+ edit_group_order="3.5"
+ label_min="Low Jaw"
+ label_max="High Jaw"
+ value_min="-1.2"
+ value_max="2"
+ value_default="0"
+ camera_distance=".5"
+ camera_elevation=".04"
+ camera_angle="70">
+ <param_morph />
+ </param>
+
+ <param
+ id="665"
+ group="0"
+ name="Jaw_Jut"
+ wearable="shape"
+ label="Jaw Jut"
+ edit_group="shape_chin"
+ edit_group_order="4"
+ label_min="Overbite"
+ label_max="Underbite"
+ value_min="-2"
+ value_max="2"
+ value_default="0"
+ camera_distance=".5"
+ camera_elevation=".04"
+ camera_angle="70">
+ <param_morph />
+ </param>
+
+ <param
+ id="686"
+ group="1"
+ name="Head_Eyes_Big"
+ wearable="shape"
+ label="Eye Size"
+ edit_group="shape_eyes"
+ label_min="Beady Eyes"
+ label_max="Anime Eyes"
+ show_simple="true"
+ value_min="-2"
+ value_max="2"
+ value_default="0">
+ <param_morph />
+ </param>
+
+ <param
+ id="767"
+ group="1"
+ name="Bug_Eyed_Head"
+ wearable="shape"
+ label="Eye Depth"
+ edit_group="shape_eyes"
+ edit_group_order="4.5"
+ label_min="Sunken Eyes"
+ label_max="Bug Eyes"
+ value_min="-2"
+ value_max="2"
+ value_default="0">
+ <param_morph />
+ </param>
+
+ <!--
+ #Fat_Lips = Fat_Lips 34 1 0 1
+ #Wide_Lips = Wide_Lips 35 1 0 1
+ #Wide_Nose = Wide_Nose 36 1 0 1
+ -->
+ <!--
+ ##############
+ # Facial Expression morphs
+ ##############
+ -->
+ <param
+ id="300"
+ group="1"
+ name="Express_Closed_Mouth"
+ value_default="1"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="301"
+ group="1"
+ name="Express_Tongue_Out"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="302"
+ group="1"
+ name="Express_Surprise_Emote"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="303"
+ group="1"
+ name="Express_Wink_Emote"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="304"
+ group="1"
+ name="Express_Embarrassed_Emote"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="305"
+ group="1"
+ name="Express_Shrug_Emote"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="306"
+ group="1"
+ name="Express_Kiss"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="307"
+ group="1"
+ name="Express_Bored_Emote"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="308"
+ group="1"
+ name="Express_Repulsed_Emote"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="309"
+ group="1"
+ name="Express_Disdain"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="310"
+ group="1"
+ name="Express_Afraid_Emote"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="311"
+ group="1"
+ name="Express_Worry_Emote"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="312"
+ group="1"
+ name="Express_Cry_Emote"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="313"
+ group="1"
+ name="Express_Sad_Emote"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="314"
+ group="1"
+ name="Express_Anger_Emote"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="315"
+ group="1"
+ name="Express_Frown"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="316"
+ group="1"
+ name="Express_Laugh_Emote"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="317"
+ group="1"
+ name="Express_Toothsmile"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="318"
+ group="1"
+ name="Express_Smile"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="632"
+ group="1"
+ name="Express_Open_Mouth"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <!--
+ ##############
+ # Lipsync morphs
+ ##############
+ -->
+
+ <param
+ id="70"
+ group="1"
+ name="Lipsync_Aah"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="71"
+ group="1"
+ name="Lipsync_Ooh"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <!--
+ ##############
+ # other morphs (not user controlled)
+ ##############
+ -->
+ <param
+ id="40"
+ group="1"
+ name="Male_Head"
+ wearable="shape"
+ edit_group="driven"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="41"
+ group="1"
+ name="Old"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <!--
+ ##############
+ # animatable morphs
+ ##############
+ -->
+ <param
+ id="51"
+ group="1"
+ name="Furrowed_Eyebrows"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="53"
+ group="1"
+ name="Surprised_Eyebrows"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="54"
+ group="1"
+ name="Worried_Eyebrows"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="55"
+ group="1"
+ name="Frown_Mouth"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="57"
+ group="1"
+ name="Smile_Mouth"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="58"
+ group="1"
+ name="Blink_Left"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="59"
+ group="1"
+ name="Blink_Right"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <!--
+ #end morph targets
+ -->
+ </mesh>
+
+ <mesh
+ type="headMesh"
+ lod="1"
+ file_name="avatar_head_1.llm"
+ min_pixel_width="160"
+ reference="avatar_head.llm">
+ </mesh>
+
+ <mesh
+ type="headMesh"
+ lod="2"
+ file_name="avatar_head_2.llm"
+ min_pixel_width="80"
+ reference="avatar_head.llm">
+ </mesh>
+
+ <mesh
+ type="headMesh"
+ lod="3"
+ file_name="avatar_head_3.llm"
+ min_pixel_width="40"
+ reference="avatar_head.llm">
+ </mesh>
+
+ <mesh
+ type="headMesh"
+ lod="4"
+ file_name="avatar_head_4.llm"
+ min_pixel_width="0"
+ reference="avatar_head.llm">
+ </mesh>
+
+ <mesh
+ type="eyelashMesh"
+ lod="0"
+ file_name="avatar_eyelashes.llm"
+ min_pixel_width="320">
+ <param
+ shared="1"
+ id="660"
+ group="1"
+ name="Shear_Head"
+ wearable="shape"
+ label="Shear Face"
+ edit_group="shape_head"
+ label_min="Shear Left"
+ label_max="Shear Right"
+ value_min="-2"
+ value_max="2"
+ value_default="0"
+ camera_distance=".5"
+ camera_elevation=".04">
+ <param_morph />
+ </param>
+
+ <param
+ shared="1"
+ id="770"
+ group="1"
+ name="Elongate_Head"
+ wearable="shape"
+ label="Shear Face"
+ edit_group="shape_head"
+ label_min="Flat Head"
+ label_max="Long Head"
+ value_min="-1"
+ value_max="1"
+ value_default="0"
+ camera_distance=".5"
+ camera_elevation=".04">
+ <param_morph />
+ </param>
+
+ <param
+ shared="1"
+ id="664"
+ group="0"
+ name="Pop_Eye"
+ wearable="shape"
+ label="Eye Pop"
+ edit_group="shape_eyes"
+ edit_group_order="8"
+ label_min="Pop Right Eye"
+ label_max="Pop Left Eye"
+ value_min="-2"
+ value_max="2"
+ value_default="0"
+ camera_distance=".5"
+ camera_elevation=".04"
+ camera_angle="-20">
+ <param_morph />
+ </param>
+
+ <param
+ shared="1"
+ id="21"
+ group="0"
+ name="Upper_Eyelid_Fold"
+ label="Upper Eyelid Fold"
+ wearable="shape"
+ edit_group="shape_eyes"
+ label_min="Uncreased"
+ label_max="Creased"
+ value_min="-0.2"
+ value_max="1.3"
+ camera_elevation=".1"
+ camera_distance=".35">
+ <param_morph />
+ </param>
+
+ <param
+ shared="1"
+ id="24"
+ group="0"
+ name="Wide_Eyes"
+ label="Eye Opening"
+ wearable="shape"
+ edit_group="shape_eyes"
+ label_min="Narrow"
+ label_max="Wide"
+ show_simple="true"
+ value_min="-1.5"
+ value_max="2"
+ camera_elevation=".1"
+ camera_distance=".3">
+ <param_morph />
+ </param>
+
+ <param
+ shared="1"
+ id="186"
+ group="1"
+ name="Egg_Head"
+ label="Egg Head"
+ wearable="shape"
+ edit_group="shape_head"
+ label_min="Chin Heavy"
+ label_max="Forehead Heavy"
+ value_min="-1.3"
+ value_max="1"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="20">
+ <param_morph />
+ </param>
+
+ <param
+ shared="1"
+ id="187"
+ group="1"
+ name="Squash_Stretch_Head"
+ label="Squash/Stretch Head"
+ wearable="shape"
+ edit_group="shape_head"
+ label_min="Squash Head"
+ label_max="Stretch Head"
+ value_min="-.5"
+ value_max="1"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="20">
+ <param_morph />
+ </param>
+
+ <param
+ shared="1"
+ id="194"
+ group="1"
+ name="Eye_Spread"
+ edit_group="shape_eyes"
+ label_min="Eyes Together"
+ label_max="Eyes Spread"
+ value_min="-2"
+ value_max="2">
+ <param_morph />
+ </param>
+
+ <param
+ id="518"
+ group="0"
+ name="Eyelashes_Long"
+ wearable="shape"
+ label="Eyelash Length"
+ edit_group="shape_eyes"
+ edit_group_order="7"
+ label_min="Short"
+ label_max="Long"
+ value_min="-.3"
+ value_max="1.5"
+ camera_elevation=".1"
+ camera_distance=".30"
+ camera_angle="-20">
+ <param_morph />
+ </param>
+
+ <param
+ shared="1"
+ id="650"
+ group="0"
+ name="Eyelid_Corner_Up"
+ label="Outer Eye Corner"
+ wearable="shape"
+ edit_group="shape_eyes"
+ label_min="Corner Down"
+ label_max="Corner Up"
+ value_min="-1.3"
+ value_max="1.2"
+ camera_elevation=".1"
+ camera_distance=".3">
+ <param_morph />
+ </param>
+
+
+ <param
+ shared="1"
+ id="880"
+ group="0"
+ name="Eyelid_Inner_Corner_Up"
+ label="Inner Eye Corner"
+ wearable="shape"
+ edit_group="shape_eyes"
+ label_min="Corner Down"
+ label_max="Corner Up"
+ value_min="-1.3"
+ value_max="1.2"
+ camera_elevation=".1"
+ camera_distance=".3">
+ <param_morph />
+ </param>
+
+ <param
+ shared="1"
+ id="686"
+ group="1"
+ name="Head_Eyes_Big"
+ wearable="shape"
+ label="Eye Size"
+ edit_group="shape_eyes"
+ label_min="Beady Eyes"
+ label_max="Anime Eyes"
+ value_min="-2"
+ value_max="2"
+ show_simple="true"
+ value_default="0">
+ <param_morph />
+ </param>
+
+ <param
+ shared="1"
+ id="767"
+ group="1"
+ name="Bug_Eyed_Head"
+ wearable="shape"
+ label="Eye Depth"
+ edit_group="shape_eyes"
+ edit_group_order="4.5"
+ label_min="Sunken Eyes"
+ label_max="Bug Eyes"
+ value_min="-2"
+ value_max="2"
+ value_default="0">
+ <param_morph />
+ </param>
+
+ <!--
+ ##############
+ # Facial Expression morphs
+ ##############
+ -->
+ <param
+ shared="1"
+ id="301"
+ group="1"
+ name="Express_Tongue_Out"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ shared="1"
+ id="302"
+ group="1"
+ name="Express_Surprise_Emote"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ shared="1"
+ id="303"
+ group="1"
+ name="Express_Wink_Emote"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ shared="1"
+ id="304"
+ group="1"
+ name="Express_Embarrassed_Emote"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ shared="1"
+ id="305"
+ group="1"
+ name="Express_Shrug_Emote"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ shared="1"
+ id="306"
+ group="1"
+ name="Express_Kiss"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ shared="1"
+ id="307"
+ group="1"
+ name="Express_Bored_Emote"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ shared="1"
+ id="308"
+ group="1"
+ name="Express_Repulsed_Emote"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ shared="1"
+ id="309"
+ group="1"
+ name="Express_Disdain"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ shared="1"
+ id="310"
+ group="1"
+ name="Express_Afraid_Emote"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ shared="1"
+ id="312"
+ group="1"
+ name="Express_Cry_Emote"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ shared="1"
+ id="313"
+ group="1"
+ name="Express_Sad_Emote"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ shared="1"
+ id="314"
+ group="1"
+ name="Express_Anger_Emote"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ shared="1"
+ id="315"
+ group="1"
+ name="Express_Frown"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ shared="1"
+ id="316"
+ group="1"
+ name="Express_Laugh_Emote"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ shared="1"
+ id="317"
+ group="1"
+ name="Express_Toothsmile"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ shared="1"
+ id="318"
+ group="1"
+ name="Express_Smile"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <!--
+ ##############
+ # other morphs (not user controlled)
+ ##############
+ -->
+ <param
+ shared="1"
+ id="41"
+ group="1"
+ name="Old"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <!--
+ ##############
+ # animatable morphs
+ ##############
+ -->
+ <param
+ shared="1"
+ id="58"
+ group="1"
+ name="Blink_Left"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ shared="1"
+ id="59"
+ group="1"
+ name="Blink_Right"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+ </mesh>
+
+ <!--
+ #headMesh2 =
+ #headMesh3 =
+ -->
+ <mesh
+ type="upperBodyMesh"
+ lod="0"
+ file_name="avatar_upper_body.llm"
+ min_pixel_width="320">
+ <!--
+ #begin morph targets
+ #############
+ # tweakable morphs
+ #############
+ -->
+ <param
+ id="104"
+ group="1"
+ name="Big_Belly_Torso"
+ wearable="shape"
+ edit_group="driven"
+ value_min="0"
+ value_max="1">
+ <param_morph>
+ <volume_morph
+ name="BELLY"
+ scale="0.075 0.04 0.03"
+ pos="0.07 0 -0.07"/>
+ <volume_morph
+ name="PELVIS"
+ scale="0.075 0.04 0.03"
+ pos="0.07 0 -0.02"/>
+ </param_morph>
+ </param>
+
+ <param
+ id="626"
+ sex="female"
+ group="1"
+ name="Big_Chest"
+ label="Chest Size"
+ wearable="shape"
+ edit_group="shape_torso"
+ label_min="Small"
+ label_max="Large"
+ value_min="0"
+ value_max="1"
+ camera_elevation=".1"
+ camera_distance="1"
+ camera_angle="15">
+ <param_morph>
+ <volume_morph
+ name="LEFT_PEC"
+ scale="0.0273 0.0273 0.0273"
+ pos="0.038 0.024 -0.016"/>
+ <volume_morph
+ name="RIGHT_PEC"
+ scale="0.0273 0.0273 0.0273"
+ pos="0.038 -0.024 -0.016"/>
+ </param_morph>
+ </param>
+
+ <param
+ id="627"
+ sex="female"
+ group="1"
+ name="Small_Chest"
+ label="Chest Size"
+ wearable="shape"
+ edit_group="shape_torso"
+ label_min="Large"
+ label_max="Small"
+ value_min="0"
+ value_max="1"
+ camera_elevation="0"
+ camera_distance=".28">
+ <param_morph>
+ <volume_morph
+ name="LEFT_PEC"
+ scale="-0.05 0.0 0.0"
+ pos="-0.01 -0.01 -0.02"/>
+ <volume_morph
+ name="RIGHT_PEC"
+ scale="-0.05 0.0 0.0"
+ pos="-0.01 -0.01 -0.02"/>
+ </param_morph>
+ </param>
+
+ <param
+ id="843"
+ sex="female"
+ group="1"
+ name="No_Chest"
+ label="Chest Size"
+ wearable="shape"
+ edit_group="shape_torso"
+ label_min="Some"
+ label_max="None"
+ value_min="0"
+ value_max="1"
+ camera_elevation="0"
+ camera_distance=".28">
+ <param_morph>
+ <volume_morph
+ name="LEFT_PEC"
+ scale="-0.051 0.0 0.0"
+ pos="-0.02 -0.01 -0.03"/>
+ <volume_morph
+ name="RIGHT_PEC"
+ scale="-0.051 0.0 0.0"
+ pos="-0.02 -0.01 -0.03"/>
+ </param_morph>
+ </param>
+
+ <param
+ id="106"
+ group="1"
+ name="Muscular_Torso"
+ label="Torso Muscles"
+ show_simple="true"
+ wearable="shape"
+ edit_group="shape_torso"
+ label_min="Regular"
+ label_max="Muscular"
+ value_min="0"
+ value_max="1.4"
+ camera_elevation=".3"
+ camera_distance="1.2">
+ <param_morph>
+ <volume_morph
+ name="L_CLAVICLE"
+ scale="0.02 0.0 0.005"
+ pos="0.0 0 0.005"/>
+ <volume_morph
+ name="L_UPPER_ARM"
+ scale="0.015 0.0 0.005"
+ pos="0.015 0 0"/>
+ <volume_morph
+ name="L_LOWER_ARM"
+ scale="0.005 0.0 0.005"
+ pos="0.005 0 0"/>
+ <volume_morph
+ name="R_CLAVICLE"
+ scale="0.02 0.0 0.005"
+ pos="0.0 0 0.005"/>
+ <volume_morph
+ name="R_UPPER_ARM"
+ scale="0.015 0.0 0.005"
+ pos="0.015 0 0"/>
+ <volume_morph
+ name="R_LOWER_ARM"
+ scale="0.005 0.0 0.005"
+ pos="0.005 0 0"/>
+ </param_morph>
+ </param>
+
+ <param
+ id="648"
+ group="1"
+ sex="female"
+ name="Scrawny_Torso"
+ label="Torso Muscles"
+ show_simple="true"
+ wearable="shape"
+ edit_group="shape_torso"
+ label_min="Regular"
+ label_max="Scrawny"
+ value_min="0"
+ value_max="1.3"
+ camera_elevation=".3"
+ camera_distance="1.2">
+ <param_morph>
+ <volume_morph
+ name="BELLY"
+ scale="0.0 -0.01 0.0"
+ pos="0.0 0.0 0"/>
+ <volume_morph
+ name="UPPER_BACK"
+ scale="-0.01 -0.01 0.0"
+ pos="0.0 0.0 0"/>
+ <volume_morph
+ name="CHEST"
+ scale="-0.01 -0.01 0.0"
+ pos="0.01 0.0 0"/>
+ <volume_morph
+ name="L_CLAVICLE"
+ scale="0.0 -0.03 -0.005"
+ pos="0.0 0 -0.005"/>
+ <volume_morph
+ name="L_UPPER_ARM"
+ scale="-0.01 -0.01 -0.02"
+ pos="0 0 0"/>
+ <volume_morph
+ name="L_LOWER_ARM"
+ scale="-0.005 0.0 -0.01"
+ pos="-0.005 0 0"/>
+ <volume_morph
+ name="R_CLAVICLE"
+ scale="0.0 -0.03 -0.005"
+ pos="0.0 0 -0.005"/>
+ <volume_morph
+ name="R_UPPER_ARM"
+ scale="-0.01 -0.01 -0.02"
+ pos="0 0 0"/>
+ <volume_morph
+ name="R_LOWER_ARM"
+ scale="-0.005 0.0 -0.01"
+ pos="-0.005 0 0"/>
+ </param_morph>
+ </param>
+
+ <param
+ id="677"
+ group="1"
+ sex="male"
+ name="Scrawny_Torso_Male"
+ label="Torso Scrawny"
+ wearable="shape"
+ edit_group="shape_torso"
+ label_min="Regular"
+ label_max="Scrawny"
+ value_min="0"
+ value_max="1.3"
+ camera_elevation=".3"
+ camera_distance="1.2">
+ <param_morph>
+ <volume_morph
+ name="BELLY"
+ scale="-0.01 -0.01 0.0"
+ pos="0.01 0.0 0"/>
+ <volume_morph
+ name="UPPER_BACK"
+ scale="-0.01 -0.01 0.0"
+ pos="0.0 0.0 0"/>
+ <volume_morph
+ name="CHEST"
+ scale="-0.02 -0.02 0.0"
+ pos="0.01 0.0 0"/>
+ <volume_morph
+ name="L_CLAVICLE"
+ scale="0.0 -0.03 -0.005"
+ pos="0.0 0 -0.005"/>
+ <volume_morph
+ name="L_UPPER_ARM"
+ scale="-0.01 -0.01 -0.02"
+ pos="0 0 0"/>
+ <volume_morph
+ name="L_LOWER_ARM"
+ scale="-0.005 0.0 -0.01"
+ pos="-0.005 0 0"/>
+ <volume_morph
+ name="R_CLAVICLE"
+ scale="0.0 -0.03 -0.005"
+ pos="0.0 0 -0.005"/>
+ <volume_morph
+ name="R_UPPER_ARM"
+ scale="-0.01 -0.01 -0.02"
+ pos="0 0 0"/>
+ <volume_morph
+ name="R_LOWER_ARM"
+ scale="-0.005 0.0 -0.01"
+ pos="-0.005 0 0"/>
+ </param_morph>
+ </param>
+
+ <param
+ id="634"
+ group="1"
+ name="Fat_Torso"
+ label="Fat Torso"
+ wearable="shape"
+ edit_group="shape_body"
+ label_min="skinny"
+ label_max="fat"
+ value_min="0"
+ value_max="1"
+ camera_elevation=".3">
+ <param_morph>
+ <volume_morph
+ name="CHEST"
+ scale="0.02 0.03 0.03"
+ pos="0 0 -0.03"/>
+ <volume_morph
+ name="PELVIS"
+ scale="0.02 0.03 0.03"
+ pos="0 0 -0.03"/>
+ <volume_morph
+ name="UPPER_BACK"
+ scale="0.01 0.03 0.0"
+ pos="-0.03 0 0"/>
+ <volume_morph
+ name="LOWER_BACK"
+ scale="0.04 0.06 0.0"
+ pos="-0.06 0 0"/>
+ <volume_morph
+ name="LEFT_HANDLE"
+ pos="0.0 0.08 0.0"/>
+ <volume_morph
+ name="RIGHT_HANDLE"
+ pos="0.0 -0.08 0.0"/>
+ <volume_morph
+ name="LEFT_PEC"
+ scale="0.0367 0.0367 0.016"
+ pos="0.00 -0.005 -0.013"/>
+ <volume_morph
+ name="RIGHT_PEC"
+ scale="0.0367 0.0367 0.016"
+ pos="0.00 0.005 -0.013"/>
+ <volume_morph
+ name="BELLY"
+ scale="0.09 0.08 0.07"
+ pos="0 0 -0.05"/>
+ <volume_morph
+ name="L_CLAVICLE"
+ scale="0.0 0.0 0.015"/>
+ <volume_morph
+ name="L_UPPER_ARM"
+ scale="0.02 0.0 0.02"
+ pos="0.0 0.0 -0.02"/>
+ <volume_morph
+ name="L_LOWER_ARM"
+ scale="0.01 0.0 0.01"
+ pos="0.0 0.0 -0.01"/>
+ <volume_morph
+ name="R_CLAVICLE"
+ scale="0.0 0.0 0.015"/>
+ <volume_morph
+ name="R_UPPER_ARM"
+ scale="0.02 0.0 0.02"
+ pos="0.0 0.0 -0.02"/>
+ <volume_morph
+ name="R_LOWER_ARM"
+ scale="0.01 0.0 0.01"
+ pos="0.0 0.0 -0.01"/>
+ <volume_morph
+ name="NECK"
+ scale="0.015 0.01 0.0"/>
+ <volume_morph
+ name="HEAD"
+ scale="0.0 0.0 0.01"
+ pos="0 0 -0.01"/>
+ </param_morph>
+ </param>
+
+ <param
+ id="507"
+ group="0"
+ sex="female"
+ name="Breast_Gravity"
+ label="Breast Buoyancy"
+ wearable="shape"
+ edit_group="shape_torso"
+ edit_group_order="7"
+ label_min="Less Gravity"
+ label_max="More Gravity"
+ value_default="0"
+ value_min="-1.5"
+ value_max="2"
+ camera_elevation=".3"
+ camera_distance=".8">
+ <param_morph>
+ <volume_morph
+ name="LEFT_PEC"
+ scale="0.0 0.0 0.0"
+ pos="0.004 0.0 -0.01"/>
+ <volume_morph
+ name="RIGHT_PEC"
+ scale="0.0 0.0 0.0"
+ pos="0.004 0.0 -0.01"/>
+ </param_morph>
+ </param>
+
+ <param
+ id="628"
+ group="1"
+ name="Displace_Loose_Upperbody"
+ label="Shirt Fit"
+ wearable="shirt"
+ edit_group="driven"
+ clothing_morph="true"
+ value_min="0"
+ value_max="1"
+ value_default="0">
+ <param_morph />
+ </param>
+
+ <param
+ id="840"
+ group="0"
+ name="Shirtsleeve_flair"
+ label="Sleeve Looseness"
+ show_simple="true"
+ wearable="shirt"
+ edit_group="shirt"
+ edit_group_order="6"
+ clothing_morph="true"
+ label_min="Tight Sleeves"
+ label_max="Loose Sleeves"
+ value_min="0"
+ value_max="1.5"
+ camera_distance="1.8"
+ camera_angle="30"
+ camera_elevation="-.3">
+ <param_morph />
+ </param>
+
+ <param
+ id="855"
+ group="1"
+ name="Love_Handles"
+ wearable="shape"
+ edit_group="driven"
+ value_default="0"
+ value_min="-1"
+ value_max="2">
+ <param_morph>
+ <volume_morph
+ name="BELLY"
+ scale="0.0 0.02 0.0"/>
+ <volume_morph
+ name="LOWER_BACK"
+ scale="0.0 0.02 0.0"/>
+ <volume_morph
+ name="LEFT_HANDLE"
+ pos="0.0 0.025 0.0"/>
+ <volume_morph
+ name="RIGHT_HANDLE"
+ pos="0.0 -0.025 0.0"/>
+ </param_morph>
+ </param>
+
+ <param
+ id="684"
+ group="0"
+ sex="female"
+ name="Breast_Female_Cleavage"
+ label="Breast Cleavage"
+ wearable="shape"
+ edit_group="shape_torso"
+ edit_group_order="8"
+ label_min="Separate"
+ label_max="Join"
+ value_default="0"
+ value_min="-.3"
+ value_max="1.3"
+ camera_elevation=".3"
+ camera_distance=".8">
+ <param_morph>
+ <volume_morph
+ name="LEFT_PEC"
+ scale="0.0 0.0 0.0"
+ pos="0.0 -0.026 0.0"/>
+ <volume_morph
+ name="RIGHT_PEC"
+ scale="0.0 0.0 0.0"
+ pos="0.0 0.026 0.0"/>
+ </param_morph>
+ </param>
+
+ <param
+ id="685"
+ group="0"
+ sex="male"
+ name="Chest_Male_No_Pecs"
+ label="Pectorals"
+ wearable="shape"
+ edit_group="shape_torso"
+ edit_group_order="5"
+ label_min="Big Pectorals"
+ label_max="Sunken Chest"
+ value_default="0"
+ value_min="-0.5"
+ value_max="1.1"
+ camera_elevation=".3"
+ camera_distance="1.2">
+ <param_morph>
+ <volume_morph
+ name="LEFT_PEC"
+ scale="0.0 0.0 0.0"
+ pos="-0.03 -0.024 -0.01"/>
+ <volume_morph
+ name="RIGHT_PEC"
+ scale="0.0 0.0 0.0"
+ pos="-0.03 0.024 -0.01"/>
+ </param_morph>
+ </param>
+
+ <!-- ############# #
+ other morphs (not user controlled)
+ ############# -->
+ <param
+ id="100"
+ group="1"
+ name="Male_Torso"
+ wearable="shape"
+ edit_group="driven"
+ label_min="Male_Torso"
+ value_min="0"
+ value_max="1">
+ <param_morph>
+ <volume_morph
+ name="CHEST"
+ scale="0.03 0.04 0.02"
+ pos="-0.03 0 -0.01"/>
+ <volume_morph
+ name="BELLY"
+ scale="0.03 0.03 0.0"
+ pos="-0.03 0 0.02"/>
+ <volume_morph
+ name="LEFT_PEC"
+ scale="0.0 0.0 0.0"
+ pos="0.008 -0.03 0.01"/>
+ <volume_morph
+ name="RIGHT_PEC"
+ scale="0.0 0.0 0.0"
+ pos="0.008 0.03 0.01"/>
+ <volume_morph
+ name="L_CLAVICLE"
+ scale="0.02 0.0 0.01"
+ pos="-0.02 0 0"/>
+ <volume_morph
+ name="L_UPPER_ARM"
+ scale="0.01 0.0 0.01"
+ pos="0.0 0.0 -0.01"/>
+ <volume_morph
+ name="L_LOWER_ARM"
+ scale="0.005 0.0 0.005"
+ pos="0.0 0.0 -0.005"/>
+ <volume_morph
+ name="R_CLAVICLE"
+ scale="0.02 0.0 0.01"
+ pos="-0.02 0 0"/>
+ <volume_morph
+ name="R_UPPER_ARM"
+ scale="0.01 0.0 0.01"
+ pos="0.0 0.0 -0.01"/>
+ <volume_morph
+ name="R_LOWER_ARM"
+ scale="0.005 0.0 0.005"
+ pos="0.0 0.0 -0.005"/>
+ <volume_morph
+ name="NECK"
+ scale="0.015 0.01 0.0"/>
+ <volume_morph
+ name="HEAD"
+ scale="0.0 0.0 0.01"
+ pos="0 0 -0.01"/>
+ </param_morph>
+ </param>
+
+ <!--
+ ##############
+ # animatable morphs
+ ##############
+ -->
+ <param
+ id="101"
+ group="1"
+ name="Hands_Relaxed"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="102"
+ group="1"
+ name="Hands_Point"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="103"
+ group="1"
+ name="Hands_Fist"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="666"
+ group="1"
+ name="Hands_Relaxed_L"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="667"
+ group="1"
+ name="Hands_Point_L"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="668"
+ group="1"
+ name="Hands_Fist_L"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="669"
+ group="1"
+ name="Hands_Relaxed_R"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="670"
+ group="1"
+ name="Hands_Point_R"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="671"
+ group="1"
+ name="Hands_Fist_R"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="672"
+ group="1"
+ name="Hands_Typing"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="766"
+ group="1"
+ name="Hands_Salute_R"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="791"
+ group="1"
+ name="Hands_Peace_R"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="792"
+ group="1"
+ name="Hands_Spread_R"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <!--
+ #############
+ # physics morphs (not user controlled)
+ #############
+ -->
+ <param
+ id="1200"
+ group="1"
+ sex="female"
+ name="Breast_Physics_UpDown_Driven"
+ wearable="physics"
+ edit_group="driven"
+ value_default="0"
+ value_min="-3"
+ value_max="3">
+ <param_morph>
+ <volume_morph
+ name="LEFT_PEC"
+ scale="0.0 0.0 0.0"
+ pos="0.0 0.0 -0.01"/>
+ <volume_morph
+ name="RIGHT_PEC"
+ scale="0.0 0.0 0.0"
+ pos="0.0 0.0 -0.01"/>
+ </param_morph>
+ </param>
+
+ <param
+ id="1201"
+ group="1"
+ sex="female"
+ name="Breast_Physics_InOut_Driven"
+ wearable="physics"
+ edit_group="driven"
+ value_default="0"
+ value_min="-1.25"
+ value_max="1.25">
+ <param_morph>
+ <volume_morph
+ name="LEFT_PEC"
+ scale="0.0 0.0 0.0"
+ pos="0.0 -0.026 0.0"/>
+ <volume_morph
+ name="RIGHT_PEC"
+ scale="0.0 0.0 0.0"
+ pos="0.0 0.026 -0.0"/>
+ </param_morph>
+ </param>
+
+ <param
+ id="1204"
+ group="1"
+ name="Belly_Physics_Torso_UpDown_Driven"
+ wearable="physics"
+ edit_group="driven"
+ value_default="0"
+ value_min="-1"
+ value_max="1">
+ <param_morph>
+ <volume_morph
+ name="BELLY"
+ scale="0.0 0.0 0.0"
+ pos="0.0 0.0 0.05"/>
+ </param_morph>
+ </param>
+
+ <param
+ id="1207"
+ group="1"
+ name="Breast_Physics_LeftRight_Driven"
+ wearable="physics"
+ edit_group="driven"
+ value_default="0"
+ value_min="-2"
+ value_max="2">
+ <param_morph>
+ <volume_morph
+ name="LEFT_PEC"
+ scale="0.0 0.0 0.0"
+ pos="0.0 0.03 0.0"/>
+ <volume_morph
+ name="RIGHT_PEC"
+ scale="0.0 0.0 0.0"
+ pos="0.0 0.03 0.0"/>
+ </param_morph>
+ </param>
+
+ <!--
+ #end morph targets
+ -->
+
+ </mesh>
+
+ <mesh
+ type="upperBodyMesh"
+ lod="1"
+ file_name="avatar_upper_body_1.llm"
+ min_pixel_width="160"
+ reference="avatar_upper_body.llm">
+ </mesh>
+
+ <mesh
+ type="upperBodyMesh"
+ lod="2"
+ file_name="avatar_upper_body_2.llm"
+ min_pixel_width="80"
+ reference="avatar_upper_body.llm">
+ </mesh>
+
+ <mesh
+ type="upperBodyMesh"
+ lod="3"
+ file_name="avatar_upper_body_3.llm"
+ min_pixel_width="40"
+ reference="avatar_upper_body.llm">
+ </mesh>
+
+ <mesh
+ type="upperBodyMesh"
+ lod="4"
+ file_name="avatar_upper_body_4.llm"
+ min_pixel_width="0"
+ reference="avatar_upper_body.llm">
+ </mesh>
+
+ <!--
+ #upperBodyMesh2 =
+ #upperBodyMesh3 =
+ -->
+ <mesh
+ type="lowerBodyMesh"
+ lod="0"
+ file_name="avatar_lower_body.llm"
+ min_pixel_width="320">
+ <!--
+ #begin morph targets
+ #############
+ # tweakable morphs
+ #############
+ -->
+ <param
+ id="156"
+ group="1"
+ name="Big_Belly_Legs"
+ wearable="shape"
+ edit_group="driven"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+
+ <param
+ id="151"
+ group="1"
+ name="Big_Butt_Legs"
+ label="Butt Size"
+ wearable="shape"
+ edit_group="shape_legs"
+ label_min="Regular"
+ label_max="Large"
+ value_min="0"
+ value_max="1">
+ <param_morph>
+ <volume_morph
+ name="PELVIS"
+ scale="0.03 0.0 0.02"
+ pos="-0.03 0 -0.025"/>
+ </param_morph>
+ </param>
+
+ <param
+ id="794"
+ group="1"
+ name="Small_Butt"
+ label="Butt Size"
+ wearable="shape"
+ edit_group="shape_legs"
+ label_min="Regular"
+ label_max="Small"
+ value_min="0"
+ value_max="1">
+ <param_morph>
+ <volume_morph
+ name="PELVIS"
+ scale="-0.01 0.0 0.0"
+ pos="0.01 0 0.0"/>
+ <volume_morph
+ name="BUTT"
+ scale="0.0 0.0886 0.0"
+ pos="0.03 0 0.0"/>
+ </param_morph>
+ </param>
+
+ <param
+ id="152"
+ group="1"
+ name="Muscular_Legs"
+ label="Leg Muscles"
+ show_simple="true"
+ wearable="shape"
+ edit_group="shape_legs"
+ label_min="Regular Muscles"
+ label_max="More Muscles"
+ value_min="0"
+ value_max="1.5"
+ camera_distance="1.3"
+ camera_elevation="-.5">
+ <param_morph>
+ <volume_morph
+ name="L_UPPER_LEG"
+ scale="0.015 0.015 0.0"
+ pos="0.0 0 0.0"/>
+ <volume_morph
+ name="L_LOWER_LEG"
+ scale="0.01 0.01 0.0"
+ pos="0.0 0 0.0"/>
+ <volume_morph
+ name="R_UPPER_LEG"
+ scale="0.015 0.015 0.0"
+ pos="0.0 0 0.0"/>
+ <volume_morph
+ name="R_LOWER_LEG"
+ scale="0.01 0.01 0.0"
+ pos="0.0 0 0.0"/>
+ </param_morph>
+ </param>
+
+ <param
+ id="651"
+ group="1"
+ name="Scrawny_Legs"
+ label="Scrawny Leg"
+ wearable="shape"
+ edit_group="shape_legs"
+ label_min="Regular Muscles"
+ label_max="Less Muscles"
+ value_min="0"
+ value_max="1.5"
+ camera_distance="1.3"
+ camera_elevation="-.5">
+ <param_morph>
+ <volume_morph
+ name="L_UPPER_LEG"
+ scale="-0.03 -0.03 0.0"
+ pos="0.0 0 0.0"/>
+ <volume_morph
+ name="L_LOWER_LEG"
+ scale="-0.015 -0.015 0.0"
+ pos="0.0 0 0.0"/>
+ <volume_morph
+ name="R_UPPER_LEG"
+ scale="-0.03 -0.03 0.0"
+ pos="0.0 0 0.0"/>
+ <volume_morph
+ name="R_LOWER_LEG"
+ scale="-0.015 -0.015 0.0"
+ pos="0.0 0 0.0"/>
+ </param_morph>
+ </param>
+
+ <param
+ id="853"
+ group="1"
+ name="Bowed_Legs"
+ label="Knee Angle"
+ wearable="shape"
+ value_min="-1"
+ value_max="1">
+ <param_morph>
+ <volume_morph
+ name="L_UPPER_LEG"
+ pos="0.0 0.03 0.0"/>
+ <volume_morph
+ name="L_LOWER_LEG"
+ pos="0.0 0.03 0.0"/>
+ <volume_morph
+ name="R_UPPER_LEG"
+ pos="0.0 -0.03 0.0"/>
+ <volume_morph
+ name="R_LOWER_LEG"
+ pos="0.0 -0.03 0.0"/>
+ </param_morph>
+ </param>
+
+ <param
+ id="500"
+ group="1"
+ name="Shoe_Heel_Height"
+ label="Heel Height"
+ wearable="shoes"
+ edit_group="shoes"
+ label_min="Low Heels"
+ label_max="High Heels"
+ value_min="0"
+ value_max="1"
+ camera_distance="1.5"
+ camera_elevation="-.5">
+ <param_morph />
+ </param>
+
+ <param
+ id="501"
+ group="1"
+ name="Shoe_Platform_Height"
+ label="Platform Height"
+ wearable="shoes"
+ edit_group="shoes"
+ label_min="Low Platforms"
+ label_max="High Platforms"
+ value_min="0"
+ value_max="1"
+ camera_distance="1.5"
+ camera_elevation="-.5">
+ <param_morph />
+ </param>
+
+ <param
+ id="508"
+ group="0"
+ name="Shoe_Platform_Width"
+ label="Platform Width"
+ wearable="shoes"
+ edit_group="shoes"
+ edit_group_order="7"
+ label_min="Narrow"
+ label_max="Wide"
+ value_min="-1"
+ value_max="2"
+ camera_angle="15"
+ camera_distance="1.5"
+ camera_elevation="-1">
+ <param_morph />
+ </param>
+
+ <param
+ id="509"
+ group="1"
+ name="Shoe_Heel_Point"
+ label="Heel Shape"
+ wearable="shoes"
+ edit_group="shoes"
+ label_min="Default Heels"
+ label_max="Pointy Heels"
+ value_min="0"
+ value_max="1"
+ camera_distance="1.3"
+ camera_elevation="-.5">
+ <param_morph />
+ </param>
+
+ <param
+ id="510"
+ group="1"
+ name="Shoe_Heel_Thick"
+ label="Heel Shape"
+ wearable="shoes"
+ edit_group="shoes"
+ label_min="default Heels"
+ label_max="Thick Heels"
+ value_min="0"
+ value_max="1"
+ camera_distance="1.3"
+ camera_elevation="-.5">
+ <param_morph />
+ </param>
+
+ <param
+ id="511"
+ group="1"
+ name="Shoe_Toe_Point"
+ label="Toe Shape"
+ wearable="shoes"
+ edit_group="shoes"
+ label_min="Default Toe"
+ label_max="Pointy Toe"
+ value_min="0"
+ value_max="1"
+ camera_distance="1.3"
+ camera_elevation="-.5">
+ <param_morph />
+ </param>
+
+ <param
+ id="512"
+ group="1"
+ name="Shoe_Toe_Square"
+ label="Toe Shape"
+ wearable="shoes"
+ edit_group="shoes"
+ label_min="Default Toe"
+ label_max="Square Toe"
+ value_min="0"
+ value_max="1"
+ camera_distance="1.5"
+ camera_elevation="-.5">
+ <param_morph />
+ </param>
+
+ <param
+ id="654"
+ group="0"
+ name="Shoe_Toe_Thick"
+ label="Toe Thickness"
+ wearable="shoes"
+ edit_group="shoes"
+ edit_group_order="5"
+ label_min="Flat Toe"
+ label_max="Thick Toe"
+ value_min="0"
+ value_max="2"
+ camera_angle="15"
+ camera_distance="1.5"
+ camera_elevation="-1">
+ <param_morph />
+ </param>
+
+ <param
+ id="515"
+ group="0"
+ name="Foot_Size"
+ label="Foot Size"
+ wearable="shape"
+ edit_group="shape_legs"
+ edit_group_order="6"
+ label_min="Small"
+ label_max="Big"
+ value_min="-1"
+ value_max="3"
+ camera_angle="45"
+ camera_distance="1.1"
+ camera_elevation="-1">
+ <param_morph>
+ <volume_morph
+ name="L_FOOT"
+ scale="0.02 0.01 0.0"
+ pos="0.01 0 0"/>
+ <volume_morph
+ name="R_FOOT"
+ scale="0.02 0.01 0.0"
+ pos="0.01 0 0"/>
+ </param_morph>
+ </param>
+
+ <param
+ id="516"
+ group="1"
+ name="Displace_Loose_Lowerbody"
+ label="Pants Fit"
+ wearable="pants"
+ edit_group="driven"
+ clothing_morph="true"
+ value_min="0"
+ value_max="1"
+ value_default="0">
+ <param_morph />
+ </param>
+
+ <param
+ id="625"
+ group="0"
+ name="Leg_Pantflair"
+ label="Cuff Flare"
+ show_simple="true"
+ wearable="pants"
+ edit_group="pants"
+ edit_group_order="3"
+ clothing_morph="true"
+ label_min="Tight Cuffs"
+ label_max="Flared Cuffs"
+ value_min="0"
+ value_max="1.5"
+ camera_distance="1.8"
+ camera_angle="30"
+ camera_elevation="-.3">
+ <param_morph />
+ </param>
+
+ <param
+ id="793"
+ group="1"
+ name="Leg_Longcuffs"
+ label="Longcuffs"
+ wearable="pants"
+ edit_group="driven"
+ clothing_morph="true"
+ value_min="0"
+ value_max="3"
+ value_default="0">
+ <param_morph />
+ </param>
+
+ <param
+ id="638"
+ group="0"
+ name="Low_Crotch"
+ label="Pants Crotch"
+ wearable="pants"
+ clothing_morph="true"
+ edit_group="pants"
+ edit_group_order="4"
+ label_min="High and Tight"
+ label_max="Low and Loose"
+ value_min="0"
+ value_max="1.3"
+ camera_distance="1.2"
+ camera_angle="-20"
+ camera_elevation="-.3">
+ <param_morph />
+ </param>
+
+ <param
+ id="635"
+ group="1"
+ name="Fat_Legs"
+ label="Fat Torso"
+ wearable="shape"
+ edit_group="shape_body"
+ label_min="skinny"
+ label_max="fat"
+ value_min="0"
+ value_max="1">
+ <param_morph>
+ <volume_morph
+ name="PELVIS"
+ scale="0.03 0.06 0.0"/>
+ <volume_morph
+ name="R_UPPER_LEG"
+ scale="0.02 0.02 0.0"
+ pos="0.0 -0.02 0.0"/>
+ <volume_morph
+ name="R_LOWER_LEG"
+ scale="0.01 0.01 0.0"/>
+ <volume_morph
+ name="L_UPPER_LEG"
+ scale="0.02 0.02 0.0"
+ pos="0.0 0.02 0.0"/>
+ <volume_morph
+ name="L_LOWER_LEG"
+ scale="0.01 0.01 0.0"/>
+ </param_morph>
+ </param>
+
+ <param
+ id="854"
+ group="1"
+ name="Saddlebags"
+ wearable="shape"
+ edit_group="driven"
+ value_min="-.5"
+ value_max="3">
+ <param_morph>
+ <volume_morph
+ name="PELVIS"
+ scale="0.0 0.025 0.0"/>
+ </param_morph>
+
+ </param>
+
+ <param
+ id="879"
+ group="0"
+ sex="male"
+ name="Male_Package"
+ label="Package"
+ wearable="shape"
+ edit_group="shape_legs"
+ edit_group_order="4.6"
+ label_min="Coin Purse"
+ label_max="Duffle Bag"
+ value_default="0"
+ value_min="-.5"
+ value_max="2"
+ camera_angle="60"
+ camera_distance=".6">
+ <param_morph />
+ </param>
+
+ <!--
+ #############
+ # other morphs (not user controlled)
+ #############
+ -->
+ <param
+ id="153"
+ group="1"
+ name="Male_Legs"
+ wearable="shape"
+ edit_group="driven"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <!--
+ #############
+ # physics morphs (not user controlled)
+ #############
+ -->
+ <param
+ id="1202"
+ group="1"
+ name="Belly_Physics_Legs_UpDown_Driven"
+ wearable="physics"
+ cross_wearable="true"
+ edit_group="driven"
+ value_min="-1"
+ value_max="1">
+ <param_morph />
+ </param>
+
+
+ <param
+ id="1205"
+ group="1"
+ name="Butt_Physics_UpDown_Driven"
+ wearable="physics"
+ cross_wearable="true"
+ edit_group="driven"
+ value_default="0"
+ value_min="-1"
+ value_max="1">
+ <param_morph>
+ <volume_morph
+ name="BUTT"
+ pos="0.0 0.0 0.05"/>
+ </param_morph>
+ </param>
+
+ <param
+ id="1206"
+ group="1"
+ name="Butt_Physics_LeftRight_Driven"
+ wearable="physics"
+ cross_wearable="true"
+ edit_group="driven"
+ value_default="0"
+ value_min="-1"
+ value_max="1">
+ <param_morph>
+ <volume_morph
+ name="BUTT"
+ pos="0.0 0.05 0.0"/>
+ </param_morph>
+ </param>
+
+ <!--
+ #end morph targets
+ -->
+
+ </mesh>
+
+ <mesh
+ type="lowerBodyMesh"
+ lod="1"
+ file_name="avatar_lower_body_1.llm"
+ min_pixel_width="160"
+ reference="avatar_lower_body.llm">
+ </mesh>
+
+ <mesh
+ type="lowerBodyMesh"
+ lod="2"
+ file_name="avatar_lower_body_2.llm"
+ min_pixel_width="80"
+ reference="avatar_lower_body.llm">
+ </mesh>
+
+ <mesh
+ type="lowerBodyMesh"
+ lod="3"
+ file_name="avatar_lower_body_3.llm"
+ min_pixel_width="40"
+ reference="avatar_lower_body.llm">
+ </mesh>
+
+ <mesh
+ type="lowerBodyMesh"
+ lod="4"
+ file_name="avatar_lower_body_4.llm"
+ min_pixel_width="0"
+ reference="avatar_lower_body.llm">
+ </mesh>
+
+ <!--
+ #lowerBodyMesh2 =
+ #lowerBodyMesh3 =
+ -->
+ <!--
+ #eyeLidLeftMesh =
+ -->
+ <mesh
+ type="eyeBallLeftMesh"
+ lod="0"
+ file_name="avatar_eye.llm"
+ min_pixel_width="320">
+ <!-- begin morph_params -->
+ <param
+ id="679"
+ group="1"
+ name="Eyeball_Size"
+ label="Eyeball Size"
+ wearable="shape"
+ edit_group="shape_eyes"
+ label_min="small eye"
+ label_max="big eye"
+ value_min="-.25"
+ value_max=".10">
+ <param_morph />
+ </param>
+
+ <param
+ id="687"
+ group="1"
+ name="Eyeball_Size"
+ label="Big Eyeball"
+ wearable="shape"
+ edit_group="shape_eyes"
+ label_min="small eye"
+ label_max="big eye"
+ value_min="-.25"
+ value_max=".25">
+ <param_morph />
+ </param>
+ </mesh>
+
+ <mesh
+ type="eyeBallLeftMesh"
+ lod="1"
+ file_name="avatar_eye_1.llm"
+ min_pixel_width="80">
+ <!-- begin morph_params -->
+ <param
+ id="694"
+ group="1"
+ name="Eyeball_Size"
+ label="Eyeball Size"
+ wearable="shape"
+ edit_group="shape_eyes"
+ label_min="small eye"
+ label_max="big eye"
+ value_min="-.25"
+ value_max=".10">
+ <param_morph />
+ </param>
+
+ <param
+ id="695"
+ group="1"
+ name="Eyeball_Size"
+ label="Big Eyeball"
+ wearable="shape"
+ edit_group="shape_eyes"
+ label_min="small eye"
+ label_max="big eye"
+ value_min="-.25"
+ value_max=".25">
+ <param_morph />
+ </param>
+ </mesh>
+
+ <!--
+ #eyeLidRightMesh =
+ -->
+ <mesh
+ type="eyeBallRightMesh"
+ lod="0"
+ file_name="avatar_eye.llm"
+ min_pixel_width="320">
+ <!-- begin morph_params -->
+ <param
+ id="680"
+ group="1"
+ name="Eyeball_Size"
+ label="Eyeball Size"
+ wearable="shape"
+ label_min="small eye"
+ label_max="big eye"
+ value_min="-.25"
+ value_max=".10">
+ <param_morph />
+ </param>
+
+ <param
+ id="688"
+ group="1"
+ name="Eyeball_Size"
+ label="Big Eyeball"
+ wearable="shape"
+ label_min="small eye"
+ label_max="big eye"
+ value_min="-.25"
+ value_max=".25">
+ <param_morph />
+ </param>
+ </mesh>
+
+ <mesh
+ type="eyeBallRightMesh"
+ lod="1"
+ file_name="avatar_eye_1.llm"
+ min_pixel_width="80">
+ <!-- begin morph_params -->
+ <param
+ id="681"
+ group="1"
+ name="Eyeball_Size"
+ label="Eyeball Size"
+ wearable="shape"
+ edit_group="shape_eyes"
+ label_min="small eye"
+ label_max="big eye"
+ value_min="-.25"
+ value_max=".10">
+ <param_morph />
+ </param>
+
+ <param
+ id="691"
+ group="1"
+ name="Eyeball_Size"
+ label="Big Eyeball"
+ wearable="shape"
+ edit_group="shape_eyes"
+ label_min="small eye"
+ label_max="big eye"
+ value_min="-.25"
+ value_max=".25">
+ <param_morph />
+ </param>
+ </mesh>
+
+ <mesh
+ type="skirtMesh"
+ lod="0"
+ file_name="avatar_skirt.llm"
+ min_pixel_width="320">
+ <param
+ id="845"
+ group="1"
+ name="skirt_poofy"
+ label="poofy skirt"
+ clothing_morph="true"
+ wearable="skirt"
+ edit_group="skirt"
+ label_min="less poofy"
+ label_max="more poofy"
+ value_min="0"
+ value_max="1.5">
+ <param_morph />
+ </param>
+
+ <param
+ id="846"
+ group="1"
+ name="skirt_loose"
+ label="loose skirt"
+ clothing_morph="true"
+ wearable="skirt"
+ edit_group="skirt"
+ label_min="form fitting"
+ label_max="loose"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="866"
+ group="1"
+ name="skirt_tight"
+ label="tight skirt"
+ clothing_morph="true"
+ wearable="skirt"
+ edit_group="skirt"
+ label_min="form fitting"
+ label_max="loose"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="867"
+ group="1"
+ name="skirt_smallbutt"
+ label="tight skirt"
+ clothing_morph="false"
+ wearable="skirt"
+ edit_group="skirt"
+ cross_wearable="true"
+ label_min="form fitting"
+ label_max="loose"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="848"
+ group="0"
+ name="skirt_bustle"
+ label="bustle skirt"
+ clothing_morph="true"
+ wearable="skirt"
+ edit_group_order="3"
+ edit_group="skirt"
+ label_min="no bustle"
+ label_max="more bustle"
+ value_min="0"
+ value_max="2"
+ value_default=".2"
+ camera_angle="100"
+ camera_distance="1.3"
+ camera_elevation="-.5">
+ <param_morph />
+ </param>
+
+ <param
+ id="847"
+ group="1"
+ name="skirt_bowlegs"
+ label="legs skirt"
+ wearable="skirt"
+ edit_group="driven"
+ cross_wearable="true"
+ value_min="-1"
+ value_max="1"
+ value_default="0">
+ <param_morph />
+ </param>
+
+ <param
+ id="852"
+ group="1"
+ name="skirt_bigbutt"
+ wearable="skirt"
+ edit_group="driven"
+ cross_wearable="true"
+ label="bigbutt skirt"
+ label_min="less"
+ label_max="more"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="849"
+ group="1"
+ name="skirt_belly"
+ wearable="skirt"
+ edit_group="driven"
+ cross_wearable="true"
+ label="big belly skirt"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <param
+ id="850"
+ group="1"
+ wearable="skirt"
+ edit_group="driven"
+ cross_wearable="true"
+ name="skirt_saddlebags"
+ value_min="-.5"
+ value_max="3">
+ <param_morph />
+ </param>
+
+ <param
+ id="851"
+ group="1"
+ name="skirt_chubby"
+ wearable="skirt"
+ edit_group="driven"
+ cross_wearable="true"
+ label_min="less"
+ label_max="more"
+ value_min="0"
+ value_max="1"
+ value_default="0">
+ <param_morph />
+ </param>
+
+ <param
+ id="856"
+ group="1"
+ name="skirt_lovehandles"
+ wearable="skirt"
+ edit_group="driven"
+ cross_wearable="true"
+ label_min="less"
+ label_max="more"
+ value_min="-1"
+ value_max="2"
+ value_default="0">
+ <param_morph />
+ </param>
+
+ <!--
+ #############
+ # other morphs (not user controlled)
+ #############
+ -->
+ <param
+ id="857"
+ group="1"
+ name="skirt_male"
+ wearable="skirt"
+ edit_group="driven"
+ cross_wearable="true"
+ value_min="0"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ <!--
+ #############
+ # physics morphs (not user controlled)
+ #############
+ -->
+ <param
+ id="1203"
+ group="1"
+ name="Belly_Physics_Skirt_UpDown_Driven"
+ wearable="physics"
+ cross_wearable="true"
+ edit_group="driven"
+ value_default="0"
+ value_min="-1"
+ value_max="1">
+ <param_morph />
+ </param>
+
+ </mesh>
+
+ <mesh
+ type="skirtMesh"
+ lod="1"
+ file_name="avatar_skirt_1.llm"
+ min_pixel_width="160"
+ reference="avatar_skirt.llm">
+ </mesh>
+
+ <mesh
+ type="skirtMesh"
+ lod="2"
+ file_name="avatar_skirt_2.llm"
+ min_pixel_width="80"
+ reference="avatar_skirt.llm">
+ </mesh>
+
+ <mesh
+ type="skirtMesh"
+ lod="3"
+ file_name="avatar_skirt_3.llm"
+ min_pixel_width="40"
+ reference="avatar_skirt.llm">
+ </mesh>
+
+ <mesh
+ type="skirtMesh"
+ lod="4"
+ file_name="avatar_skirt_4.llm"
+ min_pixel_width="0"
+ reference="avatar_skirt.llm">
+ </mesh>
+
+ <!-- =========================================================== -->
+ <global_color
+ name="skin_color">
+ <param
+ id="111"
+ group="0"
+ wearable="skin"
+ edit_group="skin_color"
+ edit_group_order="1"
+ name="Pigment"
+ show_simple="true"
+ label_min="Light"
+ label_max="Dark"
+ value_min="0"
+ value_max="1"
+ value_default=".5">
+ <param_color>
+ <value
+ color="252, 215, 200, 255" />
+
+ <value
+ color="240, 177, 112, 255" />
+
+ <value
+ color="90, 40, 16, 255" />
+
+ <value
+ color="29, 9, 6, 255" />
+ </param_color>
+ </param>
+
+ <param
+ id="110"
+ group="0"
+ wearable="skin"
+ edit_group="skin_color"
+ edit_group_order="2"
+ name="Red Skin"
+ label="Ruddiness"
+ label_min="Pale"
+ label_max="Ruddy"
+ value_min="0"
+ value_max="0.1">
+ <param_color
+ operation="blend">
+ <value
+ color="218, 41, 37, 255" />
+ </param_color>
+ </param>
+
+ <param
+ id="108"
+ group="0"
+ wearable="skin"
+ edit_group="skin_color"
+ edit_group_order="3"
+ name="Rainbow Color"
+ show_simple="true"
+ label_min="None"
+ label_max="Wild"
+ value_min="0"
+ value_max="1"
+ camera_elevation=".1"
+ camera_distance=".5">
+ <param_color>
+ <value
+ color=" 0, 0, 0, 255" />
+
+ <value
+ color="255, 0, 255, 255" />
+
+ <value
+ color="255, 0, 0, 255" />
+
+ <value
+ color="255, 255, 0, 255" />
+
+ <value
+ color=" 0, 255, 0, 255" />
+
+ <value
+ color=" 0, 255, 255, 255" />
+
+ <value
+ color=" 0, 0, 255, 255" />
+
+ <value
+ color="255, 0, 255, 255" />
+ </param_color>
+ </param>
+ </global_color>
+
+ <!-- =========================================================== -->
+ <global_color
+ name="hair_color">
+ <param
+ id="114"
+ group="0"
+ wearable="hair"
+ edit_group="hair_color"
+ edit_group_order="3"
+ name="Blonde Hair"
+ show_simple="true"
+ label_min="Black"
+ label_max="Blonde"
+ value_min="0"
+ value_max="1"
+ value_default=".5"
+ camera_elevation=".1"
+ camera_distance=".5">
+ <param_color>
+ <value
+ color="0, 0, 0, 255" />
+
+ <value
+ color="22, 6, 6, 255" />
+
+ <value
+ color="29, 9, 6, 255" />
+
+ <value
+ color="45, 21, 11, 255" />
+
+ <value
+ color="78, 39, 11, 255" />
+
+ <value
+ color="90, 53, 16, 255" />
+
+ <value
+ color="136, 92, 21, 255" />
+
+ <value
+ color="150, 106, 33, 255" />
+
+ <value
+ color="198, 156, 74, 255" />
+
+ <value
+ color="233, 192, 103, 255" />
+
+ <value
+ color="238, 205, 136, 255" />
+ </param_color>
+ </param>
+
+ <param
+ id="113"
+ group="0"
+ wearable="hair"
+ edit_group="hair_color"
+ edit_group_order="4"
+ name="Red Hair"
+ show_simple="true"
+ label_min="No Red"
+ label_max="Very Red"
+ value_min="0"
+ value_max="1"
+ camera_elevation=".1"
+ camera_distance=".5">
+ <param_color>
+ <value
+ color="0, 0, 0, 255" />
+
+ <value
+ color="118, 47, 19, 255" />
+ </param_color>
+ </param>
+
+ <param
+ id="115"
+ group="0"
+ wearable="hair"
+ edit_group="hair_color"
+ edit_group_order="1"
+ name="White Hair"
+ show_simple="true"
+ label_min="No White"
+ label_max="All White"
+ value_min="0"
+ value_max="1"
+ camera_elevation=".1"
+ camera_distance=".5">
+ <param_color>
+ <value
+ color="0, 0, 0, 255" />
+
+ <value
+ color="255, 255, 255, 255" />
+ </param_color>
+ </param>
+
+ <param
+ id="112"
+ group="0"
+ wearable="hair"
+ edit_group="hair_color"
+ edit_group_order="2"
+ name="Rainbow Color"
+ show_simple="true"
+ label_min="None"
+ label_max="Wild"
+ value_min="0"
+ value_max="1"
+ camera_elevation=".1"
+ camera_distance=".5">
+ <param_color>
+ <value
+ color=" 0, 0, 0, 255" />
+
+ <value
+ color="255, 0, 255, 255" />
+
+ <value
+ color="255, 0, 0, 255" />
+
+ <value
+ color="255, 255, 0, 255" />
+
+ <value
+ color=" 0, 255, 0, 255" />
+
+ <value
+ color=" 0, 255, 255, 255" />
+
+ <value
+ color=" 0, 0, 255, 255" />
+
+ <value
+ color="255, 0, 255, 255" />
+ </param_color>
+ </param>
+ </global_color>
+
+ <!-- =========================================================== -->
+ <global_color
+ name="eye_color">
+ <param
+ id="99"
+ group="0"
+ wearable="eyes"
+ edit_group="eyes"
+ edit_group_order="1"
+ name="Eye Color"
+ show_simple="true"
+ label_min="Natural"
+ label_max="Unnatural"
+ value_min="0"
+ value_max="1"
+ value_default="0"
+ camera_elevation=".1"
+ camera_distance=".3">
+ <!-- default to natural brown eyes-->
+ <param_color>
+ <value
+ color="50, 25, 5, 255" />
+
+ <!-- natural dark brown eyes-->
+ <value
+ color="109, 55, 15, 255" />
+
+ <!-- natural brown eyes-->
+ <value
+ color="150, 93, 49, 255" />
+
+ <!-- natural light brown eyes-->
+ <value
+ color="152, 118, 25, 255" />
+
+ <!--natural hazel eyes-->
+ <value
+ color="95, 179, 107, 255" />
+
+ <!--natural green eyes-->
+ <value
+ color="87, 192, 191, 255" />
+
+ <!--natural aqua eyes-->
+ <value
+ color="95, 172, 179, 255" />
+
+ <!--natural blue eyes-->
+ <value
+ color="128, 128, 128, 255" />
+
+ <!--natural grey eyes-->
+ <value
+ color="0, 0, 0, 255" />
+
+ <!--black eyes-->
+ <value
+ color="255, 255, 0, 255" />
+
+ <!--bright yellow eyes-->
+ <value
+ color=" 0, 255, 0, 255" />
+
+ <!-- bright green eyes-->
+ <value
+ color=" 0, 255, 255, 255" />
+
+ <!-- bright cyan eyes-->
+ <value
+ color=" 0, 0, 255, 255" />
+
+ <!--bright blue eyes-->
+ <value
+ color="255, 0, 255, 255" />
+
+ <!-- bright violet eyes-->
+ <value
+ color="255, 0, 0, 255" />
+
+ <!--bright red eyes-->
+ </param_color>
+ </param>
+
+ <param
+ id="98"
+ group="0"
+ wearable="eyes"
+ edit_group="eyes"
+ edit_group_order="2"
+ name="Eye Lightness"
+ show_simple="true"
+ label_min="Darker"
+ label_max="Lighter"
+ value_min="0"
+ value_max="1"
+ camera_elevation=".1"
+ camera_distance=".3">
+ <param_color>
+ <value
+ color="0, 0, 0, 0" />
+
+ <value
+ color="255, 255, 255, 255" />
+ </param_color>
+ </param>
+ </global_color>
+
+ <!-- =========================================================== -->
+ <layer_set
+ body_region="hair"
+ width="512"
+ height="512"
+ clear_alpha="false">
+ <layer
+ name="base"
+ global_color="hair_color"
+ write_all_channels="true">
+ <texture
+ local_texture="hair_grain" />
+ </layer>
+
+ <layer
+ name="hair texture alpha layer"
+ visibility_mask="TRUE">
+ <texture
+ local_texture="hair_grain" />
+ </layer>
+
+ <layer
+ name="hair alpha"
+ visibility_mask="TRUE">
+ <texture
+ local_texture="hair_alpha" />
+ </layer>
+
+ </layer_set>
+ <!-- =========================================================== -->
+
+ <layer_set
+ body_region="head"
+ width="512"
+ height="512">
+ <layer
+ name="head bump base"
+ fixed_color = "128,128,128,255"
+ render_pass="bump">
+ </layer>
+
+ <layer
+ name="head bump definition"
+ render_pass="bump">
+
+
+ <texture
+ tga_file="bump_head_base.tga"
+ file_is_mask="FALSE"/>
+
+ <param
+ id="873"
+ group="1"
+ wearable="skin"
+ edit_group="driven"
+ edit_group_order="12"
+ name="Bump base"
+ value_min="0"
+ value_max="1">
+ <param_alpha
+ domain="0" />
+ </param>
+ </layer>
+
+ <layer
+ name="base"
+ global_color="skin_color">
+ <texture
+ tga_file="head_skingrain.tga" />
+ </layer>
+
+ <layer
+ name="headcolor">
+ <texture
+ tga_file="head_color.tga" />
+ </layer>
+
+ <layer
+ name="shadow">
+ <texture
+ tga_file="head_shading_alpha.tga"
+ file_is_mask="TRUE" />
+
+ <param
+ id="158"
+ group="1"
+ wearable="skin"
+ name="Shading"
+ value_min="0"
+ value_max="1">
+ <param_color>
+ <value
+ color="0, 0, 0, 0" />
+
+ <value
+ color="0, 0, 0, 128" />
+ </param_color>
+ </param>
+ </layer>
+
+ <layer
+ name="highlight">
+ <texture
+ tga_file="head_highlights_alpha.tga"
+file_is_mask="TRUE" />
+
+
+ <param
+ id="159"
+ group="1"
+ name="Shading"
+ wearable="skin"
+ value_min="0"
+ value_max="1">
+ <param_color>
+ <value
+color="255, 255, 255, 0" />
+
+
+ <value
+ color="255, 255, 255, 64" />
+ </param_color>
+ </param>
+ </layer>
+ <layer
+ name="rosyface">
+ <texture
+ tga_file="rosyface_alpha.tga"
+ file_is_mask="true" />
+
+ <param
+ id="116"
+ group="0"
+ wearable="skin"
+ edit_group="skin_facedetail"
+ edit_group_order="4"
+ name="Rosy Complexion"
+ label_min="Less Rosy"
+ label_max="More Rosy"
+ value_min="0"
+ value_max="1"
+ camera_distance=".3"
+ camera_elevation=".07">
+ <param_color>
+ <value
+ color="198, 71, 71, 0" />
+
+ <value
+ color="198, 71, 71, 255" />
+ </param_color>
+ </param>
+ </layer>
+
+ <layer
+ name="lips">
+ <texture
+ tga_file="lips_mask.tga"
+ file_is_mask="true" />
+
+ <param
+ id="117"
+ group="0"
+ wearable="skin"
+ edit_group="skin_facedetail"
+ edit_group_order="5"
+ name="Lip Pinkness"
+ label_min="Darker"
+ label_max="Pinker"
+ value_min="0"
+ value_max="1"
+ camera_distance=".25">
+ <param_color>
+ <value
+ color="220, 115, 115, 0" />
+
+ <value
+ color="220, 115, 115, 128" />
+ </param_color>
+ </param>
+ </layer>
+
+ <layer
+ name="wrinkles_shading"
+ render_pass="bump"
+ fixed_color="0,0,0,100">
+ <param
+ id="118"
+ group="1"
+ wearable="skin"
+ name="Wrinkles"
+ value_min="0"
+ value_max="1">
+ <param_alpha
+ tga_file="bump_face_wrinkles.tga"
+ skip_if_zero="true"
+ domain="0.3" />
+ </param>
+ </layer>
+
+ <!--<layer
+ name="wrinkles_highlights"
+ fixed_color="255,255,255,64">
+ <param
+ id="128"
+ group="1"
+ name="Wrinkles"
+ value_min="0"
+ value_max="1">
+ <param_alpha
+ tga_file="head_wrinkles_highlights_alpha.tga"
+ skip_if_zero="true"
+ domain="0.3" />
+ </param>
+ </layer>-->
+ <layer
+ name="freckles"
+ fixed_color="120,47,20,128">
+ <param
+ id="165"
+ group="0"
+ wearable="skin"
+ edit_group="skin_facedetail"
+ edit_group_order="2"
+ name="Freckles"
+ label_min="Less"
+ label_max="More"
+ value_min="0"
+ value_max="1"
+ camera_distance=".3"
+camera_elevation=".07">
+ <param_alpha
+ tga_file="freckles_alpha.tga"
+ skip_if_zero="true"
+domain="0.5" />
+ </param>
+ </layer>
+ <layer
+name="eyebrowsbump"
+render_pass="bump">
+ <texture
+ tga_file="head_hair.tga"
+ file_is_mask="false" />
+
+ <param
+ id="1000"
+ group="1"
+ wearable="hair"
+ edit_group="driven"
+ name="Eyebrow Size Bump"
+ value_min="0"
+ value_max="1">
+ <param_alpha
+ tga_file="eyebrows_alpha.tga"
+ domain="0.1" />
+ </param>
+
+ <param
+ id="1002"
+ group="1"
+ wearable="hair"
+ edit_group="driven"
+ name="Eyebrow Density Bump"
+ value_min="0"
+ value_max="1">
+ <param_color>
+ <value
+ color="255,255,255,0" />
+
+ <value
+ color="255,255,255,255" />
+ </param_color>
+ </param>
+ </layer>
+
+ <layer
+ name="eyebrows"
+ global_color="hair_color">
+ <texture
+ tga_file="head_hair.tga"
+ file_is_mask="false" />
+
+ <param
+ id="1001"
+ group="1"
+ wearable="hair"
+ edit_group="hair_eyebrows"
+ name="Eyebrow Size"
+ show_simple="true"
+ value_min="0"
+ value_max="1"
+ value_default="0.5">
+ <param_alpha
+ tga_file="eyebrows_alpha.tga"
+ domain="0.1" />
+ </param>
+
+ <param
+ id="1003"
+ group="1"
+ wearable="hair"
+ edit_group="driven"
+ name="Eyebrow Density"
+ value_min="0"
+ value_max="1">
+ <param_color
+ operation="multiply">
+ <value
+ color="255,255,255,0" />
+
+ <value
+ color="255,255,255,255" />
+ </param_color>
+ </param>
+ </layer>
+
+ <layer
+ name="lipstick">
+ <param
+ id="700"
+ group="0"
+ wearable="skin"
+ edit_group="skin_makeup"
+ edit_group_order="2"
+ name="Lipstick Color"
+ label_min="Pink"
+ label_max="Black"
+ value_min="0"
+ value_max="1"
+ value_default=".25"
+ camera_distance=".25">
+ <param_color>
+ <value
+ color="245,161,177,200" />
+
+ <value
+ color="216,37,67,200" />
+
+ <value
+ color="178,48,76,200" />
+
+ <value
+ color="68,0,11,200" />
+
+ <value
+ color="252,207,184,200" />
+
+ <value
+ color="241,136,106,200" />
+
+ <value
+ color="208,110,85,200" />
+
+ <value
+ color="106,28,18,200" />
+
+ <value
+ color="58,26,49,200" />
+
+ <value
+ color="14,14,14,200" />
+ </param_color>
+ </param>
+
+ <param
+ id="701"
+ group="0"
+ wearable="skin"
+ edit_group="skin_makeup"
+ edit_group_order="1"
+ name="Lipstick"
+ label_min="No Lipstick"
+ label_max="More Lipstick"
+ value_min="0"
+ value_max=".9"
+ value_default="0.0"
+ camera_distance=".25">
+ <param_alpha
+ tga_file="lipstick_alpha.tga"
+ skip_if_zero="true"
+ domain="0.05" />
+ </param>
+ </layer>
+
+ <layer
+ name="lipgloss"
+ fixed_color="255,255,255,190">
+ <param
+ id="702"
+ name="Lipgloss"
+ label_min="No Lipgloss"
+ label_max="Glossy"
+ wearable="skin"
+ edit_group="skin_makeup"
+ edit_group_order="3"
+ group="0"
+ value_min="0"
+ value_max="1"
+ camera_distance=".25">
+ <param_alpha
+ tga_file="lipgloss_alpha.tga"
+ skip_if_zero="true"
+ domain="0.2" />
+ </param>
+ </layer>
+
+ <layer
+ name="blush">
+ <param
+ id="704"
+ group="0"
+ wearable="skin"
+ edit_group="skin_makeup"
+ edit_group_order="4"
+ name="Blush"
+ label_min="No Blush"
+ label_max="More Blush"
+ value_min="0"
+ value_max=".9"
+ value_default="0"
+ camera_distance=".3"
+ camera_elevation=".07"
+ camera_angle="20">
+ <param_alpha
+ tga_file="blush_alpha.tga"
+ skip_if_zero="true"
+ domain="0.3" />
+ </param>
+
+ <param
+ id="705"
+ group="0"
+ wearable="skin"
+ edit_group="skin_makeup"
+ edit_group_order="5"
+ name="Blush Color"
+ label_min="Pink"
+ label_max="Orange"
+ value_min="0"
+ value_max="1"
+ value_default=".5"
+ camera_distance=".3"
+ camera_elevation=".07"
+ camera_angle="20">
+ <param_color>
+ <value
+ color="253,162,193,200" />
+
+ <value
+ color="247,131,152,200" />
+
+ <value
+ color="213,122,140,200" />
+
+ <value
+ color="253,152,144,200" />
+
+ <value
+ color="236,138,103,200" />
+
+ <value
+ color="195,128,122,200" />
+
+ <value
+ color="148,103,100,200" />
+
+ <value
+ color="168,95,62,200" />
+ </param_color>
+ </param>
+
+ <param
+ id="711"
+ group="0"
+ wearable="skin"
+ edit_group="skin_makeup"
+ edit_group_order="6"
+ name="Blush Opacity"
+ label_min="Clear"
+ label_max="Opaque"
+ value_min="0"
+ value_max="1"
+ value_default=".5"
+ camera_distance=".3"
+ camera_elevation=".07"
+ camera_angle="20">
+ <param_color
+ operation="multiply">
+ <value
+ color="255,255,255,0" />
+
+ <value
+ color="255,255,255,255" />
+ </param_color>
+ </param>
+ </layer>
+
+ <layer
+ name="Outer Eye Shadow">
+ <param
+ id="708"
+ group="0"
+ wearable="skin"
+ edit_group="skin_makeup"
+ edit_group_order="11"
+ name="Out Shdw Color"
+ label_min="Light"
+ label_max="Dark"
+ value_min="0"
+ value_max="1"
+ camera_distance=".3"
+ camera_elevation=".14">
+ <param_color>
+ <value
+ color="252,247,246,255" />
+
+ <value
+ color="255,206,206,255" />
+
+ <value
+ color="233,135,149,255" />
+
+ <value
+ color="220,168,192,255" />
+
+ <value
+ color="228,203,232,255" />
+
+ <value
+ color="255,234,195,255" />
+
+ <value
+ color="230,157,101,255" />
+
+ <value
+ color="255,147,86,255" />
+
+ <value
+ color="228,110,89,255" />
+
+ <value
+ color="228,150,120,255" />
+
+ <value
+ color="223,227,213,255" />
+
+ <value
+ color="96,116,87,255" />
+
+ <value
+ color="88,143,107,255" />
+
+ <value
+ color="194,231,223,255" />
+
+ <value
+ color="207,227,234,255" />
+
+ <value
+ color="41,171,212,255" />
+
+ <value
+ color="180,137,130,255" />
+
+ <value
+ color="173,125,105,255" />
+
+ <value
+ color="144,95,98,255" />
+
+ <value
+ color="115,70,77,255" />
+
+ <value
+ color="155,78,47,255" />
+
+ <value
+ color="239,239,239,255" />
+
+ <value
+ color="194,194,194,255" />
+
+ <value
+ color="120,120,120,255" />
+
+ <value
+ color="10,10,10,255" />
+ </param_color>
+ </param>
+
+ <param
+ id="706"
+ group="0"
+ wearable="skin"
+ edit_group="skin_makeup"
+ edit_group_order="12"
+ name="Out Shdw Opacity"
+ label_min="Clear"
+ label_max="Opaque"
+ value_min=".2"
+ value_max="1"
+ value_default=".6"
+ camera_distance=".3"
+ camera_elevation=".14">
+ <param_color
+ operation="multiply">
+ <value
+ color="255,255,255,0" />
+
+ <value
+ color="255,255,255,255" />
+ </param_color>
+ </param>
+
+ <param
+ id="707"
+ group="0"
+ wearable="skin"
+ edit_group="skin_makeup"
+ edit_group_order="10"
+ name="Outer Shadow"
+ label_min="No Eyeshadow"
+ label_max="More Eyeshadow"
+ value_min="0"
+ value_max=".7"
+ camera_distance=".3"
+ camera_elevation=".14">
+ <param_alpha
+ tga_file="eyeshadow_outer_alpha.tga"
+ skip_if_zero="true"
+ domain="0.05" />
+ </param>
+ </layer>
+
+ <layer
+ name="Inner Eye Shadow">
+ <param
+ id="712"
+ group="0"
+ wearable="skin"
+ edit_group="skin_makeup"
+ edit_group_order="8"
+ name="In Shdw Color"
+ label_min="Light"
+ label_max="Dark"
+ value_min="0"
+ value_max="1"
+ camera_distance=".3"
+ camera_elevation=".14">
+ <param_color>
+ <value
+ color="252,247,246,255" />
+
+ <value
+ color="255,206,206,255" />
+
+ <value
+ color="233,135,149,255" />
+
+ <value
+ color="220,168,192,255" />
+
+ <value
+ color="228,203,232,255" />
+
+ <value
+ color="255,234,195,255" />
+
+ <value
+ color="230,157,101,255" />
+
+ <value
+ color="255,147,86,255" />
+
+ <value
+ color="228,110,89,255" />
+
+ <value
+ color="228,150,120,255" />
+
+ <value
+ color="223,227,213,255" />
+
+ <value
+ color="96,116,87,255" />
+
+ <value
+ color="88,143,107,255" />
+
+ <value
+ color="194,231,223,255" />
+
+ <value
+ color="207,227,234,255" />
+
+ <value
+ color="41,171,212,255" />
+
+ <value
+ color="180,137,130,255" />
+
+ <value
+ color="173,125,105,255" />
+
+ <value
+ color="144,95,98,255" />
+
+ <value
+ color="115,70,77,255" />
+
+ <value
+ color="155,78,47,255" />
+
+ <value
+ color="239,239,239,255" />
+
+ <value
+ color="194,194,194,255" />
+
+ <value
+ color="120,120,120,255" />
+
+ <value
+ color="10,10,10,255" />
+ </param_color>
+ </param>
+
+ <param
+ id="713"
+ group="0"
+ wearable="skin"
+ edit_group="skin_makeup"
+ edit_group_order="9"
+ name="In Shdw Opacity"
+ label_min="Clear"
+ label_max="Opaque"
+ value_min=".2"
+ value_max="1"
+ value_default=".7"
+ camera_distance=".3"
+ camera_elevation=".14">
+ <param_color
+ operation="multiply">
+ <value
+ color="255,255,255,0" />
+
+ <value
+ color="255,255,255,255" />
+ </param_color>
+ </param>
+
+ <param
+ id="709"
+ group="0"
+ wearable="skin"
+ edit_group="skin_makeup"
+ edit_group_order="7"
+ name="Inner Shadow"
+ label_min="No Eyeshadow"
+ label_max="More Eyeshadow"
+ value_min="0"
+ value_max="1"
+ value_default="0"
+ camera_distance=".3"
+ camera_elevation=".14">
+ <param_alpha
+ tga_file="eyeshadow_inner_alpha.tga"
+ skip_if_zero="true"
+ domain="0.2" />
+ </param>
+ </layer>
+
+ <layer
+ name="eyeliner"
+ fixed_color="0,0,0,200">
+ <param
+ id="703"
+ group="0"
+ wearable="skin"
+ edit_group="skin_makeup"
+ edit_group_order="13"
+ name="Eyeliner"
+ label_min="No Eyeliner"
+ label_max="Full Eyeliner"
+ value_min="0"
+ value_max="1"
+ value_default="0.0"
+ camera_distance=".3"
+ camera_elevation=".14">
+ <param_alpha
+ tga_file="eyeliner_alpha.tga"
+ skip_if_zero="true"
+ domain="0.1" />
+ </param>
+
+ <param
+ id="714"
+ group="0"
+ wearable="skin"
+ edit_group="skin_makeup"
+ edit_group_order="14"
+ name="Eyeliner Color"
+ label_min="Dark Green"
+ label_max="Black"
+ value_min="0"
+ value_max="1"
+ camera_distance=".3"
+ camera_elevation=".14">
+ <param_color>
+ <value
+ color="24,98,40,250" />
+
+ <!-- dark green -->
+ <value
+ color="9,100,127,250" />
+
+ <!-- lt.aqua blue -->
+ <value
+ color="61,93,134,250" />
+
+ <!-- aqua -->
+ <value
+ color="70,29,27,250" />
+
+ <!-- dark brown -->
+ <value
+ color="115,75,65,250" />
+
+ <!-- lt. brown blue -->
+ <value
+ color="100,100,100,250" />
+
+ <!-- grey -->
+ <value
+ color="91,80,74,250" />
+
+ <!-- grey/brown -->
+ <value
+ color="112,42,76,250" />
+
+ <!-- plum -->
+ <value
+ color="14,14,14,250" />
+
+ <!-- black -->
+ </param_color>
+ </param>
+ </layer>
+
+ <layer
+ name="facialhair bump"
+ render_pass="bump">
+ <texture
+ tga_file="head_hair.tga"
+ file_is_mask="false" />
+
+ <param
+ id="1004"
+ sex="male"
+ group="1"
+ wearable="hair"
+ edit_group="driven"
+ name="Sideburns bump"
+ value_min="0"
+ value_max="1">
+ <param_alpha
+ tga_file="facehair_sideburns_alpha.tga"
+ skip_if_zero="true"
+ domain="0.05" />
+ </param>
+
+ <param
+ id="1006"
+ sex="male"
+ group="1"
+ wearable="hair"
+ edit_group="driven"
+ name="Moustache bump"
+ value_min="0"
+ value_max="1">
+ <param_alpha
+ tga_file="facehair_moustache_alpha.tga"
+ skip_if_zero="true"
+ domain="0.05" />
+ </param>
+
+ <param
+ id="1008"
+ sex="male"
+ group="1"
+ wearable="hair"
+ edit_group="driven"
+ name="Soulpatch bump"
+ value_min="0"
+ value_max="1">
+ <param_alpha
+ tga_file="facehair_soulpatch_alpha.tga"
+ skip_if_zero="true"
+ domain="0.1" />
+ </param>
+
+ <param
+ id="1010"
+ sex="male"
+ group="1"
+ edit_group="driven"
+ wearable="hair"
+ name="Chin Curtains bump"
+ value_min="0"
+ value_max="1">
+ <param_alpha
+ tga_file="facehair_chincurtains_alpha.tga"
+ skip_if_zero="true"
+ domain="0.03" />
+ </param>
+
+ <param
+ id="1012"
+ group="1"
+ sex="male"
+ wearable="hair"
+ edit_group="driven"
+ name="5 O'Clock Shadow bump"
+ value_min="0"
+ value_max="1">
+ <param_color>
+ <value
+ color="255,255,255,255" />
+
+ <value
+ color="255,255,255,0" />
+ </param_color>
+ </param>
+ </layer>
+
+ <layer
+ name="facialhair"
+ global_color="hair_color">
+
+ <texture
+ tga_file="head_hair.tga"
+ file_is_mask="false" />
+
+ <param
+ id="1005"
+ sex="male"
+ group="1"
+ wearable="hair"
+ edit_group="driven"
+ name="Sideburns"
+ value_min="0"
+ value_max="1">
+ <param_alpha
+ tga_file="facehair_sideburns_alpha.tga"
+ skip_if_zero="true"
+ domain="0.05" />
+ </param>
+
+ <param
+ id="1007"
+ sex="male"
+ group="1"
+ wearable="hair"
+ edit_group="driven"
+ name="Moustache"
+ value_min="0"
+ value_max="1">
+ <param_alpha
+ tga_file="facehair_moustache_alpha.tga"
+ skip_if_zero="true"
+ domain="0.05" />
+ </param>
+
+ <param
+ id="1009"
+ sex="male"
+ group="1"
+ wearable="hair"
+ edit_group="driven"
+ name="Soulpatch"
+ value_min="0"
+ value_max="1">
+ <param_alpha
+ tga_file="facehair_soulpatch_alpha.tga"
+ skip_if_zero="true"
+ domain="0.1" />
+ </param>
+
+ <param
+ id="1011"
+ sex="male"
+ group="1"
+ wearable="hair"
+ edit_group="driven"
+ name="Chin Curtains"
+ value_min="0"
+ value_max="1">
+ <param_alpha
+ tga_file="facehair_chincurtains_alpha.tga"
+ skip_if_zero="true"
+ domain="0.03" />
+ </param>
+
+ <param
+ id="751"
+ group="1"
+ wearable="hair"
+ sex="male"
+ edit_group="hair_facial"
+ name="5 O'Clock Shadow"
+ label_min="Dense hair"
+ label_max="Shadow hair"
+ value_min="0"
+ value_max="1"
+ value_default="0.7"
+ camera_elevation=".1"
+ camera_distance=".3">
+ <param_color
+ operation="multiply">
+ <value
+ color="255,255,255,255" />
+
+ <value
+ color="255,255,255,30" />
+ </param_color>
+ </param>
+ </layer>
+
+ <layer
+ name="head_bodypaint">
+ <texture
+ local_texture="head_bodypaint" />
+ </layer>
+ <layer
+ name="eyelash alpha"
+ visibility_mask="TRUE">
+ <texture
+ tga_file="head_alpha.tga"
+ file_is_mask="TRUE" />
+ </layer>
+ <layer
+ name="head alpha"
+ visibility_mask="TRUE">
+ <texture
+ local_texture="head_alpha" />
+ </layer>
+ <layer
+ name="head_tattoo">
+ <texture
+ local_texture="head_tattoo" />
+ <param
+ id="1062"
+ group="1"
+ edit_group="colorpicker_driven"
+ wearable="tattoo"
+ name="tattoo_head_red"
+ value_min="0"
+ value_max="1"
+ value_default="1">
+ <param_color>
+ <value
+ color="0, 0, 0, 255" />
+
+ <value
+ color="255, 0, 0, 255" />
+ </param_color>
+ </param>
+
+ <param
+ id="1063"
+ group="1"
+ edit_group="colorpicker_driven"
+ wearable="tattoo"
+ name="tattoo_head_green"
+ value_min="0"
+ value_max="1"
+ value_default="1">
+ <param_color>
+ <value
+ color="0, 0, 0, 255" />
+
+ <value
+ color="0, 255, 0, 255" />
+ </param_color>
+ </param>
+
+ <param
+ id="1064"
+ group="1"
+ edit_group="colorpicker_driven"
+ wearable="tattoo"
+ name="tattoo_head_blue"
+ value_min="0"
+ value_max="1"
+ value_default="1">
+ <param_color>
+ <value
+ color="0, 0, 0, 255" />
+
+ <value
+ color="0, 0, 255, 255" />
+ </param_color>
+ </param>
+
+ </layer>
+
+
+ </layer_set>
+
+ <!-- =========================================================== -->
+ <layer_set
+ body_region="upper_body"
+ width="512"
+ height="512">
+ <layer
+ name="base_upperbody bump"
+ render_pass="bump"
+ fixed_color="128,128,128,255">
+ </layer>
+ <layer
+ name="upperbody bump definition"
+ render_pass="bump">
+ <texture
+ tga_file="bump_upperbody_base.tga"
+ file_is_mask="FALSE"/>
+
+ <param
+ id="874"
+ group="1"
+ wearable="skin"
+ edit_group="driven"
+ edit_group_order="20"
+ name="Bump upperdef"
+ value_min="0"
+ value_max="1">
+ <param_alpha
+ domain="0" />
+ </param>
+ </layer>
+
+ <layer
+ name="base"
+ global_color="skin_color">
+ <texture
+ tga_file="body_skingrain.tga" />
+ </layer>
+
+ <layer
+ name="nipples">
+ <texture
+ tga_file="upperbody_color.tga" />
+ </layer>
+
+ <layer
+ name="shadow">
+ <texture
+ tga_file="upperbody_shading_alpha.tga"
+ file_is_mask="TRUE" />
+
+ <param
+ id="125"
+ group="1"
+ name="Shading"
+ wearable="skin"
+ value_min="0"
+ value_max="1">
+ <param_color>
+ <value
+ color="0, 0, 0, 0" />
+
+ <value
+ color="0, 0, 0, 128" />
+ </param_color>
+ </param>
+ </layer>
+
+ <layer
+ name="highlight">
+ <texture
+ tga_file="upperbody_highlights_alpha.tga"
+ file_is_mask="TRUE" />
+
+ <param
+ id="126"
+ group="1"
+ wearable="skin"
+ name="Shading"
+ value_min="0"
+ value_max="1">
+ <param_color>
+ <value
+ color="255, 255, 255, 0" />
+
+ <value
+ color="255, 255, 255, 64" />
+ </param_color>
+ </param>
+ </layer>
+
+ <layer
+ name="upper_bodypaint">
+ <texture
+ local_texture="upper_bodypaint" />
+ </layer>
+
+ <layer
+ name="freckles upper"
+ fixed_color="120,47,20,128">
+ <param
+ id="776"
+ group="1"
+ name="freckles upper"
+ wearable="skin"
+ value_min="0"
+ value_max="1">
+ <param_alpha
+ tga_file="upperbodyfreckles_alpha.tga"
+ skip_if_zero="true"
+ domain="0.6" />
+ </param>
+ </layer>
+
+ <layer
+ name="upper_tattoo">
+ <texture
+ local_texture="upper_tattoo" />
+
+ <param
+ id="1065"
+ group="1"
+ edit_group="colorpicker_driven"
+ wearable="tattoo"
+ name="tattoo_upper_red"
+ value_min="0"
+ value_max="1"
+ value_default="1">
+ <param_color>
+ <value
+ color="0, 0, 0, 255" />
+
+ <value
+ color="255, 0, 0, 255" />
+ </param_color>
+ </param>
+
+ <param
+ id="1066"
+ group="1"
+ edit_group="colorpicker_driven"
+ wearable="tattoo"
+ name="tattoo_upper_green"
+ value_min="0"
+ value_max="1"
+ value_default="1">
+ <param_color>
+ <value
+ color="0, 0, 0, 255" />
+
+ <value
+ color="0, 255, 0, 255" />
+ </param_color>
+ </param>
+
+ <param
+ id="1067"
+ group="1"
+ edit_group="colorpicker_driven"
+ wearable="tattoo"
+ name="tattoo_upper_blue"
+ value_min="0"
+ value_max="1"
+ value_default="1">
+ <param_color>
+ <value
+ color="0, 0, 0, 255" />
+
+ <value
+ color="0, 0, 255, 255" />
+ </param_color>
+ </param>
+
+ </layer>
+
+
+ <layer
+ name="upper_undershirt bump"
+ render_pass="bump"
+ fixed_color="128,128,128,255">
+ <texture
+ local_texture="upper_undershirt"
+ local_texture_alpha_only="true" />
+
+ <param
+ id="1043"
+ group="1"
+ wearable="undershirt"
+ edit_group="driven"
+ name="Sleeve Length bump"
+ value_min=".01"
+ value_max="1"
+ value_default=".4">
+ <param_alpha
+ tga_file="shirt_sleeve_alpha.tga"
+ multiply_blend="false"
+ domain="0.01" />
+ </param>
+
+ <param
+ id="1045"
+ group="1"
+ wearable="undershirt"
+ edit_group="undershirt"
+ edit_group_order="2"
+ name="Bottom bump"
+ value_min="0"
+ value_max="1"
+ value_default=".8">
+ <param_alpha
+ tga_file="shirt_bottom_alpha.tga"
+ multiply_blend="true"
+ domain="0.05" />
+ </param>
+
+ <param
+ id="1047"
+ group="1"
+ wearable="undershirt"
+ edit_group="driven"
+ name="Collar Front bump"
+ value_min="0"
+ value_max="1"
+ value_default=".8">
+ <param_alpha
+ tga_file="shirt_collar_alpha.tga"
+ multiply_blend="true"
+ domain="0.05" />
+ </param>
+
+ <param
+ id="1049"
+ group="1"
+ wearable="undershirt"
+ edit_group="driven"
+ name="Collar Back bump"
+ value_min="0"
+ value_max="1"
+ value_default=".8">
+ <param_alpha
+ tga_file="shirt_collar_back_alpha.tga"
+ multiply_blend="true"
+ domain="0.05" />
+ </param>
+ </layer>
+
+ <layer
+ name="upper_undershirt">
+ <texture
+ local_texture="upper_undershirt" />
+
+ <param
+ id="821"
+ group="0"
+ wearable="undershirt"
+ edit_group="colorpicker"
+ name="undershirt_red"
+ value_min="0"
+ value_max="1"
+ value_default="1">
+ <param_color>
+ <value
+ color="0, 0, 0, 255" />
+
+ <value
+ color="255, 0, 0, 255" />
+ </param_color>
+ </param>
+
+ <param
+ id="822"
+ group="0"
+ wearable="undershirt"
+ edit_group="colorpicker"
+ name="undershirt_green"
+ value_min="0"
+ value_max="1"
+ value_default="1">
+ <param_color>
+ <value
+ color="0, 0, 0, 255" />
+
+ <value
+ color="0, 255, 0, 255" />
+ </param_color>
+ </param>
+
+ <param
+ id="823"
+ group="0"
+ wearable="undershirt"
+ edit_group="colorpicker"
+ name="undershirt_blue"
+ value_min="0"
+ value_max="1"
+ value_default="1">
+ <param_color>
+ <value
+ color="0, 0, 0, 255" />
+
+ <value
+ color="0, 0, 255, 255" />
+ </param_color>
+ </param>
+
+ <param
+ id="1042"
+ group="1"
+ wearable="undershirt"
+ edit_group="driven"
+ name="Sleeve Length"
+ value_min=".01"
+ value_max="1"
+ value_default=".4">
+ <param_alpha
+ tga_file="shirt_sleeve_alpha.tga"
+ multiply_blend="false"
+ domain="0.01" />
+ </param>
+
+ <param
+ id="1044"
+ group="1"
+ wearable="undershirt"
+ edit_group="driven"
+ name="Bottom"
+ value_min="0"
+ value_max="1"
+ value_default=".8">
+ <param_alpha
+ tga_file="shirt_bottom_alpha.tga"
+ multiply_blend="true"
+ domain="0.05" />
+ </param>
+
+ <param
+ id="1046"
+ group="1"
+ wearable="undershirt"
+ edit_group="driven"
+ name="Collar Front"
+ value_min="0"
+ value_max="1"
+ value_default=".8">
+ <param_alpha
+ tga_file="shirt_collar_alpha.tga"
+ multiply_blend="true"
+ domain="0.05" />
+ </param>
+
+ <param
+ id="1048"
+ group="1"
+ wearable="undershirt"
+ edit_group="driven"
+ name="Collar Back"
+ label_min="Low"
+ label_max="High"
+ value_min="0"
+ value_max="1"
+ value_default=".8">
+ <param_alpha
+ tga_file="shirt_collar_back_alpha.tga"
+ multiply_blend="true"
+ domain="0.05" />
+ </param>
+ </layer>
+
+ <layer
+ name="Nail Polish">
+ <param
+ id="710"
+ group="0"
+ wearable="skin"
+ edit_group="skin_makeup"
+ edit_group_order="15"
+ name="Nail Polish"
+ label_min="No Polish"
+ label_max="Painted Nails"
+ value_min="0"
+ value_max="1"
+ value_default="0.0"
+ camera_distance="1.6"
+ camera_elevation="-.4"
+ camera_angle="70">
+ <param_alpha
+ tga_file="nailpolish_alpha.tga"
+ skip_if_zero="true"
+ domain="0.1" />
+ </param>
+
+ <param
+ id="715"
+ group="0"
+ wearable="skin"
+ edit_group="skin_makeup"
+ edit_group_order="16"
+ name="Nail Polish Color"
+ label_min="Pink"
+ label_max="Black"
+ value_min="0"
+ value_max="1"
+ camera_distance="1.6"
+ camera_elevation="-.4"
+ camera_angle="70">
+ <param_color>
+ <value
+ color="255,187,200,255" />
+
+ <value
+ color="194,102,127,255" />
+
+ <value
+ color="227,34,99,255" />
+
+ <value
+ color="168,41,60,255" />
+
+ <value
+ color="97,28,59,255" />
+
+ <value
+ color="234,115,93,255" />
+
+ <value
+ color="142,58,47,255" />
+
+ <value
+ color="114,30,46,255" />
+
+ <value
+ color="14,14,14,255" />
+ </param_color>
+ </param>
+ </layer>
+
+ <layer
+ name="upper_gloves bump"
+ render_pass="bump"
+ fixed_color="128,128,128,255">
+ <texture
+ local_texture="upper_gloves"
+ local_texture_alpha_only="true" />
+
+ <param
+ id="1059"
+ group="1"
+ wearable="gloves"
+ edit_group="driven"
+ name="Glove Length bump"
+ value_min=".01"
+ value_max="1"
+ value_default=".8">
+ <param_alpha
+ tga_file="glove_length_alpha.tga"
+ domain="0.01" />
+ </param>
+
+ <param
+ id="1061"
+ group="1"
+ wearable="gloves"
+ edit_group="driven"
+ name="Glove Fingers bump"
+ value_min=".01"
+ value_max="1"
+ value_default="1">
+ <param_alpha
+ tga_file="gloves_fingers_alpha.tga"
+ multiply_blend="true"
+ domain="0.01" />
+ </param>
+ </layer>
+
+ <layer
+ name="upper_gloves">
+ <texture
+ local_texture="upper_gloves" />
+
+ <param
+ id="827"
+ group="0"
+ wearable="gloves"
+ edit_group="colorpicker"
+ name="gloves_red"
+ value_min="0"
+ value_max="1"
+ value_default="1">
+ <param_color>
+ <value
+ color="0, 0, 0, 255" />
+
+ <value
+ color="255, 0, 0, 255" />
+ </param_color>
+ </param>
+
+ <param
+ id="829"
+ group="0"
+ wearable="gloves"
+ edit_group="colorpicker"
+ name="gloves_green"
+ value_min="0"
+ value_max="1"
+ value_default="1">
+ <param_color>
+ <value
+ color="0, 0, 0, 255" />
+
+ <value
+ color="0, 255, 0, 255" />
+ </param_color>
+ </param>
+
+ <param
+ id="830"
+ group="0"
+ wearable="gloves"
+ edit_group="colorpicker"
+ name="gloves_blue"
+ value_min="0"
+ value_max="1"
+ value_default="1">
+ <param_color>
+ <value
+ color="0, 0, 0, 255" />
+
+ <value
+ color="0, 0, 255, 255" />
+ </param_color>
+ </param>
+
+ <param
+ id="1058"
+ group="1"
+ wearable="gloves"
+ edit_group="driven"
+ name="Glove Length"
+ value_min=".01"
+ value_max="1"
+ value_default=".8">
+ <param_alpha
+ tga_file="glove_length_alpha.tga"
+ domain="0.01" />
+ </param>
+
+ <param
+ id="1060"
+ group="1"
+ wearable="gloves"
+ edit_group="driven"
+ name="Glove Fingers"
+ value_min=".01"
+ value_max="1"
+ value_default="1">
+ <param_alpha
+ tga_file="gloves_fingers_alpha.tga"
+ multiply_blend="true"
+ domain="0.01" />
+ </param>
+ </layer>
+
+ <layer
+ name="upper_clothes_shadow">
+ <texture
+ local_texture="upper_shirt" />
+
+ <param
+ id="899"
+ group="1"
+ edit_group="driven"
+ wearable="shirt"
+ name="Upper Clothes Shading"
+ value_min="0"
+ value_max="1"
+ value_default="0">
+ <param_color>
+ <value
+ color="0, 0, 0, 0" />
+
+ <value
+ color="0, 0, 0, 80" />
+ </param_color>
+ </param>
+
+ <param
+ id="900"
+ group="1"
+ wearable="shirt"
+ edit_group="driven"
+ name="Sleeve Length Shadow"
+ value_min="0.02"
+ value_max=".87"
+ value_default="0.02">
+ <param_alpha
+ multiply_blend="false"
+ tga_file="shirt_sleeve_alpha.tga"
+ skip_if_zero="true"
+ domain="0.03" />
+ </param>
+
+ <param
+ id="901"
+ group="1"
+ wearable="shirt"
+ edit_group="driven"
+ name="Shirt Shadow Bottom"
+ value_min="0.02"
+ value_max="1">
+ <param_alpha
+ multiply_blend="true"
+ tga_file="shirt_bottom_alpha.tga"
+ skip_if_zero="true"
+ domain="0.05" />
+ </param>
+
+ <param
+ id="902"
+ group="1"
+ wearable="shirt"
+ edit_group="driven"
+ name="Collar Front Shadow Height"
+ value_min="0.02"
+ value_max="1">
+ <param_alpha
+ multiply_blend="true"
+ tga_file="shirt_collar_alpha.tga"
+ skip_if_zero="true"
+ domain="0.02" />
+ </param>
+
+ <param
+ id="903"
+ group="1"
+ wearable="shirt"
+ edit_group="driven"
+ name="Collar Back Shadow Height"
+ value_min="0.02"
+ value_max="1">
+ <param_alpha
+ multiply_blend="true"
+ tga_file="shirt_collar_back_alpha.tga"
+ skip_if_zero="true"
+ domain="0.02" />
+ </param>
+ </layer>
+
+ <layer
+ name="upper_shirt base bump"
+ render_pass="bump"
+ fixed_color="128,128,128,255">
+ <texture
+ local_texture="upper_shirt"
+ local_texture_alpha_only="true" />
+
+ <param
+ id="1029"
+ group="1"
+ wearable="shirt"
+ edit_group="driven"
+ name="Sleeve Length Cloth"
+ value_min="0"
+ value_max="0.85">
+ <param_alpha
+ multiply_blend="false"
+ tga_file="shirt_sleeve_alpha.tga"
+ domain="0.01" />
+ </param>
+
+ <param
+ id="1030"
+ group="1"
+ wearable="shirt"
+ edit_group="driven"
+ name="Shirt Bottom Cloth"
+ value_min="0"
+ value_max="1">
+ <param_alpha
+ multiply_blend="true"
+ tga_file="shirt_bottom_alpha.tga"
+ domain="0.05" />
+ </param>
+
+ <param
+ id="1031"
+ group="1"
+ wearable="shirt"
+ edit_group="driven"
+ name="Collar Front Height Cloth"
+ value_min="0"
+ value_max="1">
+ <param_alpha
+ multiply_blend="true"
+ tga_file="shirt_collar_alpha.tga"
+ domain="0.05" />
+ </param>
+
+ <param
+ id="1032"
+ group="1"
+ wearable="shirt"
+ edit_group="driven"
+ name="Collar Back Height Cloth"
+ value_min="0"
+ value_max="1">
+ <param_alpha
+ multiply_blend="true"
+ tga_file="shirt_collar_back_alpha.tga"
+ domain="0.05" />
+ </param>
+ </layer>
+
+ <layer
+ name="upper_clothes bump"
+ render_pass="bump">
+ <texture
+ tga_file="bump_shirt_wrinkles.tga" />
+
+ <texture
+ local_texture="upper_shirt"
+ local_texture_alpha_only="true" />
+
+ <param
+ id="868"
+ group="3"
+ wearable="shirt"
+ edit_group="shirt"
+ edit_group_order="8"
+ name="Shirt Wrinkles"
+ value_min="0"
+ value_max="1"
+ value_default="0">
+ <param_color>
+ <value
+ color="255, 255, 255, 0" />
+
+ <value
+ color="255, 255, 255, 255" />
+ </param_color>
+ </param>
+
+ <param
+ id="1013"
+ group="1"
+ wearable="shirt"
+ edit_group="driven"
+ name="Sleeve Length Cloth"
+ value_min="0"
+ value_max="0.85">
+ <param_alpha
+ multiply_blend="false"
+ tga_file="shirt_sleeve_alpha.tga"
+ domain="0.01" />
+ </param>
+
+ <param
+ id="1014"
+ group="1"
+ wearable="shirt"
+ edit_group="driven"
+ name="Shirt Bottom Cloth"
+ value_min="0"
+ value_max="1">
+ <param_alpha
+ multiply_blend="true"
+ tga_file="shirt_bottom_alpha.tga"
+ domain="0.05" />
+ </param>
+
+ <param
+ id="1015"
+ group="1"
+ wearable="shirt"
+ edit_group="driven"
+ name="Collar Front Height Cloth"
+ value_min="0"
+ value_max="1">
+ <param_alpha
+ multiply_blend="true"
+ tga_file="shirt_collar_alpha.tga"
+ domain="0.05" />
+ </param>
+
+ <param
+ id="1016"
+ group="1"
+ wearable="shirt"
+ edit_group="driven"
+ name="Collar Back Height Cloth"
+ value_min="0"
+ value_max="1">
+ <param_alpha
+ multiply_blend="true"
+ tga_file="shirt_collar_back_alpha.tga"
+ domain="0.05" />
+ </param>
+ </layer>
+
+ <layer
+ name="upper_clothes">
+ <texture
+ local_texture="upper_shirt" />
+
+ <param
+ id="803"
+ group="0"
+ wearable="shirt"
+ edit_group="colorpicker"
+ name="shirt_red"
+ value_min="0"
+ value_max="1"
+ value_default="1">
+ <param_color>
+ <value
+ color="0, 0, 0, 255" />
+
+ <value
+ color="255, 0, 0, 255" />
+ </param_color>
+ </param>
+
+ <param
+ id="804"
+ group="0"
+ wearable="shirt"
+ edit_group="colorpicker"
+ name="shirt_green"
+ value_min="0"
+ value_max="1"
+ value_default="1">
+ <param_color>
+ <value
+ color="0, 0, 0, 255" />
+
+ <value
+ color="0, 255, 0, 255" />
+ </param_color>
+ </param>
+
+ <param
+ id="805"
+ group="0"
+ wearable="shirt"
+ edit_group="colorpicker"
+ name="shirt_blue"
+ value_min="0"
+ value_max="1"
+ value_default="1">
+ <param_color>
+ <value
+ color="0, 0, 0, 255" />
+
+ <value
+ color="0, 0, 255, 255" />
+ </param_color>
+ </param>
+
+ <param
+ id="600"
+ group="1"
+ wearable="shirt"
+ edit_group="driven"
+ name="Sleeve Length Cloth"
+ value_min="0"
+ value_max="0.85"
+ value_default=".7">
+ <param_alpha
+ multiply_blend="false"
+ tga_file="shirt_sleeve_alpha.tga"
+ domain="0.01" />
+ </param>
+
+ <param
+ id="601"
+ group="1"
+ wearable="shirt"
+ edit_group="driven"
+ name="Shirt Bottom Cloth"
+ value_min="0"
+ value_max="1"
+ value_default=".8">
+ <param_alpha
+ multiply_blend="true"
+ tga_file="shirt_bottom_alpha.tga"
+ domain="0.05" />
+ </param>
+
+ <param
+ id="602"
+ group="1"
+ wearable="shirt"
+ edit_group="driven"
+ name="Collar Front Height Cloth"
+ value_min="0"
+ value_max="1"
+ value_default=".8">
+ <param_alpha
+ multiply_blend="true"
+ tga_file="shirt_collar_alpha.tga"
+ domain="0.05" />
+ </param>
+
+ <param
+ id="778"
+ group="1"
+ wearable="shirt"
+ edit_group="driven"
+ name="Collar Back Height Cloth"
+ value_min="0"
+ value_max="1"
+ value_default=".8">
+ <param_alpha
+ multiply_blend="true"
+ tga_file="shirt_collar_back_alpha.tga"
+ domain="0.05" />
+ </param>
+ </layer>
+
+ <layer
+ name="upper_jacket base bump"
+ render_pass="bump"
+ fixed_color="128,128,128,255">
+ <texture
+ local_texture="upper_jacket"
+ local_texture_alpha_only="true" />
+
+ <param
+ id="1039"
+ group="1"
+ wearable="jacket"
+ edit_group="driven"
+ edit_group_order="1"
+ name="Jacket Sleeve Length bump"
+ value_min="0"
+ value_max="1">
+ <param_alpha
+ multiply_blend="false"
+ tga_file="shirt_sleeve_alpha.tga"
+ domain="0.01" />
+ </param>
+
+ <param
+ id="1040"
+ group="1"
+ wearable="jacket"
+ edit_group="driven"
+ name="Jacket Collar Front bump"
+ value_min="0"
+ value_max="1">
+ <param_alpha
+ multiply_blend="true"
+ tga_file="shirt_collar_alpha.tga"
+ domain="0.05" />
+ </param>
+
+ <param
+ id="1041"
+ group="1"
+ wearable="jacket"
+ edit_group="driven"
+ edit_group_order="3.5"
+ name="Jacket Collar Back bump"
+ value_min="0"
+ value_max="1">
+ <param_alpha
+ multiply_blend="true"
+ tga_file="shirt_collar_back_alpha.tga"
+ domain="0.05" />
+ </param>
+
+ <param
+ id="1037"
+ group="1"
+ wearable="jacket"
+ edit_group="driven"
+ name="jacket bottom length upper bump"
+ value_min="0"
+ value_max="1">
+ <param_alpha
+ multiply_blend="true"
+ tga_file="jacket_length_upper_alpha.tga"
+ domain="0.01" />
+ </param>
+
+ <param
+ id="1038"
+ group="1"
+ wearable="jacket"
+ edit_group="driven"
+ name="jacket open upper bump"
+ value_min="0"
+ value_max="1">
+ <param_alpha
+ multiply_blend="true"
+ tga_file="jacket_open_upper_alpha.tga"
+ domain="0.01" />
+ </param>
+ </layer>
+
+ <layer
+ name="upper_jacket bump"
+ render_pass="bump">
+ <texture
+ tga_file="bump_shirt_wrinkles.tga" />
+
+ <texture
+ local_texture="upper_jacket"
+ local_texture_alpha_only="true" />
+
+
+ <param
+ id="875"
+ group="1"
+ wearable="jacket"
+ name="jacket upper Wrinkles"
+ value_min="0"
+ value_max="1"
+ value_default="0">
+ <param_color>
+ <value
+ color="255, 255, 255, 0" />
+
+ <value
+ color="255, 255, 255, 255" />
+ </param_color>
+ </param>
+
+ <param
+ id="1019"
+ group="1"
+ wearable="jacket"
+ edit_group="driven"
+ edit_group_order="1"
+ name="Jacket Sleeve Length bump"
+ value_min="0"
+ value_max="1">
+ <param_alpha
+ multiply_blend="false"
+ tga_file="shirt_sleeve_alpha.tga"
+ domain="0.01" />
+ </param>
+
+ <param
+ id="1021"
+ group="1"
+ wearable="jacket"
+ edit_group="driven"
+ name="Jacket Collar Front bump"
+ value_min="0"
+ value_max="1">
+ <param_alpha
+ multiply_blend="true"
+ tga_file="shirt_collar_alpha.tga"
+ domain="0.05" />
+ </param>
+
+ <param
+ id="1023"
+ group="1"
+ wearable="jacket"
+ edit_group="driven"
+ edit_group_order="3.5"
+ name="Jacket Collar Back bump"
+ value_min="0"
+ value_max="1">
+ <param_alpha
+ multiply_blend="true"
+ tga_file="shirt_collar_back_alpha.tga"
+ domain="0.05" />
+ </param>
+
+ <param
+ id="1025"
+ group="1"
+ wearable="jacket"
+ edit_group="driven"
+ name="jacket bottom length upper bump"
+ value_min="0"
+ value_max="1">
+ <param_alpha
+ multiply_blend="true"
+ tga_file="jacket_length_upper_alpha.tga"
+ domain="0.01" />
+ </param>
+
+ <param
+ id="1026"
+ group="1"
+ wearable="jacket"
+ edit_group="driven"
+ name="jacket open upper bump"
+ value_min="0"
+ value_max="1">
+ <param_alpha
+ multiply_blend="true"
+ tga_file="jacket_open_upper_alpha.tga"
+ domain="0.01" />
+ </param>
+ </layer>
+
+ <layer
+ name="upper_jacket">
+ <texture
+ local_texture="upper_jacket" />
+
+ <param
+ id="831"
+ group="1"
+ edit_group="colorpicker_driven"
+ wearable="jacket"
+ name="upper_jacket_red"
+ value_min="0"
+ value_max="1"
+ value_default="1">
+ <param_color>
+ <value
+ color="0, 0, 0, 255" />
+
+ <value
+ color="255, 0, 0, 255" />
+ </param_color>
+ </param>
+
+ <param
+ id="832"
+ group="1"
+ edit_group="colorpicker_driven"
+ wearable="jacket"
+ name="upper_jacket_green"
+ value_min="0"
+ value_max="1"
+ value_default="1">
+ <param_color>
+ <value
+ color="0, 0, 0, 255" />
+
+ <value
+ color="0, 255, 0, 255" />
+ </param_color>
+ </param>
+
+ <param
+ id="833"
+ group="1"
+ edit_group="colorpicker_driven"
+ wearable="jacket"
+ name="upper_jacket_blue"
+ value_min="0"
+ value_max="1"
+ value_default="1">
+ <param_color>
+ <value
+ color="0, 0, 0, 255" />
+
+ <value
+ color="0, 0, 255, 255" />
+ </param_color>
+ </param>
+
+ <param
+ id="1020"
+ group="1"
+ edit_group="driven"
+ wearable="jacket"
+ name="jacket Sleeve Length" value_min="0"
+ value_max="1">
+ <param_alpha
+ multiply_blend="false"
+ tga_file="shirt_sleeve_alpha.tga"
+ domain="0.01" />
+ </param>
+
+ <param
+ id="1022"
+ group="1"
+ wearable="jacket"
+ edit_group="driven"
+ name="jacket Collar Front"
+ value_min="0"
+ value_max="1">
+ <param_alpha
+ multiply_blend="true"
+ tga_file="shirt_collar_alpha.tga"
+ domain="0.05" />
+ </param>
+
+ <param
+ id="1024"
+ group="1"
+ wearable="jacket"
+ edit_group="driven"
+ edit_group_order="3.5"
+ name="jacket Collar Back"
+ value_min="0"
+ value_max="1">
+ <param_alpha
+ multiply_blend="true"
+ tga_file="shirt_collar_back_alpha.tga"
+ domain="0.05" />
+ </param>
+
+ <param
+ id="620"
+ group="1"
+ wearable="jacket"
+ edit_group="jacket"
+ name="bottom length upper"
+ label_min="hi cut"
+ label_max="low cut"
+ value_min="0"
+ value_max="1"
+ value_default=".8"
+ camera_distance="1.2"
+ camera_angle="30"
+ camera_elevation=".2">
+ <param_alpha
+ multiply_blend="true"
+ tga_file="jacket_length_upper_alpha.tga"
+ domain="0.01" />
+ </param>
+
+ <param
+ id="622"
+ group="1"
+ wearable="jacket"
+ edit_group="jacket"
+ name="open upper"
+ label_min="closed"
+ label_max="open"
+ value_min="0"
+ value_max="1"
+ value_default=".8"
+ camera_distance="1.2"
+ camera_angle="30"
+ camera_elevation=".2">
+ <param_alpha
+ multiply_blend="true"
+ tga_file="jacket_open_upper_alpha.tga"
+ domain="0.01" />
+ </param>
+ </layer>
+
+ <layer
+ name="upper alpha"
+ visibility_mask="TRUE">
+ <texture
+ local_texture="upper_alpha" />
+ </layer>
+
+ </layer_set>
+
+ <!-- =========================================================== -->
+ <layer_set
+ body_region="lower_body"
+ width="512"
+ height="512">
+ <layer
+ name="lower body bump base"
+ fixed_color = "128,128,128,255"
+ render_pass="bump">
+ </layer>
+ <layer
+ name="base_lowerbody bump"
+ render_pass="bump">
+ <texture
+ tga_file="bump_lowerbody_base.tga"
+ file_is_mask="FALSE" />
+
+ <param
+ id="878"
+ group="1"
+ wearable="skin"
+ edit_group="driven"
+ edit_group_order="20"
+ name="Bump upperdef"
+ value_min="0"
+ value_max="1">
+ <param_alpha
+ domain="0" />
+ </param>
+ </layer>
+
+ <layer
+ name="base"
+ global_color="skin_color">
+ <texture
+ tga_file="body_skingrain.tga" />
+ </layer>
+
+ <layer
+ name="shadow">
+ <texture
+ tga_file="lowerbody_shading_alpha.tga"
+ file_is_mask="TRUE" />
+
+ <param
+ id="160"
+ group="1"
+ name="Shading"
+ wearable="pants"
+ cross_wearable="true"
+ value_min="0"
+ value_max="1">
+ <param_color>
+ <value
+ color="0, 0, 0, 0" />
+
+ <value
+ color="0, 0, 0, 128" />
+ </param_color>
+ </param>
+ </layer>
+
+ <layer
+ name="highlight">
+ <texture
+ tga_file="lowerbody_highlights_alpha.tga"
+ file_is_mask="TRUE" />
+
+ <param
+ id="161"
+ group="1"
+ name="Shading"
+ wearable="skin"
+ value_min="0"
+ value_max="1">
+ <param_color>
+ <value
+ color="255, 255, 255, 0" />
+
+ <value
+ color="255, 255, 255, 64" />
+ </param_color>
+ </param>
+ </layer>
+
+ <layer
+ name="toenails">
+ <texture
+ tga_file="lowerbody_color.tga" />
+ </layer>
+
+ <layer
+ name="lower_bodypaint">
+ <texture
+ local_texture="lower_bodypaint" />
+ </layer>
+
+ <layer
+ name="freckles lower"
+ fixed_color="120,47,20,128">
+ <param
+ id="777"
+ group="1"
+ name="freckles lower"
+ wearable="skin"
+ value_min="0"
+ value_max="1">
+ <param_alpha
+ tga_file="bodyfreckles_alpha.tga"
+ skip_if_zero="true"
+ domain="0.6" />
+ </param>
+ </layer>
+
+ <layer
+ name="lower_tattoo">
+ <texture
+ local_texture="lower_tattoo" />
+
+ <param
+ id="1068"
+ group="1"
+ edit_group="colorpicker_driven"
+ wearable="tattoo"
+ name="tattoo_lower_red"
+ value_min="0"
+ value_max="1"
+ value_default="1">
+ <param_color>
+ <value
+ color="0, 0, 0, 255" />
+
+ <value
+ color="255, 0, 0, 255" />
+ </param_color>
+ </param>
+
+ <param
+ id="1069"
+ group="1"
+ edit_group="colorpicker_driven"
+ wearable="tattoo"
+ name="tattoo_lower_green"
+ value_min="0"
+ value_max="1"
+ value_default="1">
+ <param_color>
+ <value
+ color="0, 0, 0, 255" />
+
+ <value
+ color="0, 255, 0, 255" />
+ </param_color>
+ </param>
+
+ <param
+ id="1070"
+ group="1"
+ edit_group="colorpicker_driven"
+ wearable="tattoo"
+ name="tattoo_lower_blue"
+ value_min="0"
+ value_max="1"
+ value_default="1">
+ <param_color>
+ <value
+ color="0, 0, 0, 255" />
+
+ <value
+ color="0, 0, 255, 255" />
+ </param_color>
+ </param>
+
+ </layer>
+
+ <layer
+ name="lower_underpants bump"
+ render_pass="bump"
+ fixed_color="128,128,128,255">
+ <texture
+ local_texture="lower_underpants"
+ local_texture_alpha_only="true" />
+
+ <param
+ id="1055"
+ group="1"
+ wearable="underpants"
+ edit_group="underpants"
+ name="Pants Length"
+ value_min="0"
+ value_max="1"
+ value_default=".3">
+ <param_alpha
+ tga_file="pants_length_alpha.tga"
+ domain="0.01" />
+ </param>
+
+ <param
+ id="1057"
+ group="1"
+ wearable="underpants"
+ edit_group="underpants"
+ name="Pants Waist"
+ value_min="0"
+ value_max="1"
+ value_default=".8">
+ <param_alpha
+ tga_file="pants_waist_alpha.tga"
+ domain="0.05" />
+ </param>
+ </layer>
+
+ <layer
+ name="lower_underpants">
+ <texture
+ local_texture="lower_underpants" />
+
+ <param
+ id="824"
+ group="0"
+ wearable="underpants"
+ edit_group="colorpicker"
+ name="underpants_red"
+ value_min="0"
+ value_max="1"
+ value_default="1">
+ <param_color>
+ <value
+ color="0, 0, 0, 255" />
+
+ <value
+ color="255, 0, 0, 255" />
+ </param_color>
+ </param>
+
+ <param
+ id="825"
+ group="0"
+ wearable="underpants"
+ edit_group="colorpicker"
+ name="underpants_green"
+ value_min="0"
+ value_max="1"
+ value_default="1">
+ <param_color>
+ <value
+ color="0, 0, 0, 255" />
+
+ <value
+ color="0, 255, 0, 255" />
+ </param_color>
+ </param>
+
+ <param
+ id="826"
+ group="0"
+ wearable="underpants"
+ edit_group="colorpicker"
+ name="underpants_blue"
+ value_min="0"
+ value_max="1"
+ value_default="1">
+ <param_color>
+ <value
+ color="0, 0, 0, 255" />
+
+ <value
+ color="0, 0, 255, 255" />
+ </param_color>
+ </param>
+
+ <param
+ id="1054"
+ group="1"
+ wearable="underpants"
+ edit_group="driven"
+ name="Pants Length"
+ value_min="0"
+ value_max="1"
+ value_default=".3"
+ camera_distance="1.2"
+ camera_angle="30"
+ camera_elevation="-.3">
+ <param_alpha
+ tga_file="pants_length_alpha.tga"
+ domain="0.01" />
+ </param>
+
+ <param
+ id="1056"
+ group="1"
+ wearable="underpants"
+ edit_group="driven"
+ name="Pants Waist"
+ value_min="0"
+ value_max="1"
+ value_default=".8">
+ <param_alpha
+ tga_file="pants_waist_alpha.tga"
+ domain="0.05" />
+ </param>
+ </layer>
+
+ <layer
+ name="lower_socks bump"
+ render_pass="bump"
+ fixed_color="128,128,128,255">
+ <texture
+ local_texture="lower_socks"
+ local_texture_alpha_only="true" />
+
+ <param
+ id="1051"
+ group="1"
+ wearable="socks"
+ edit_group="driven"
+ name="Socks Length bump"
+ value_min="0"
+ value_max="1"
+ value_default="0.35">
+ <param_alpha
+ tga_file="shoe_height_alpha.tga"
+ domain="0.01" />
+ </param>
+ </layer>
+
+ <layer
+ name="lower_socks">
+ <texture
+ local_texture="lower_socks" />
+
+ <param
+ id="818"
+ group="0"
+ wearable="socks"
+ edit_group="colorpicker"
+ name="socks_red"
+ value_min="0"
+ value_max="1"
+ value_default="1">
+ <param_color>
+ <value
+ color="0, 0, 0, 255" />
+
+ <value
+ color="255, 0, 0, 255" />
+ </param_color>
+ </param>
+
+ <param
+ id="819"
+ group="0"
+ wearable="socks"
+ edit_group="colorpicker"
+ name="socks_green"
+ value_min="0"
+ value_max="1"
+ value_default="1">
+ <param_color>
+ <value
+ color="0, 0, 0, 255" />
+
+ <value
+ color="0, 255, 0, 255" />
+ </param_color>
+ </param>
+
+ <param
+ id="820"
+ group="0"
+ wearable="socks"
+ edit_group="colorpicker"
+ name="socks_blue"
+ value_min="0"
+ value_max="1"
+ value_default="1">
+ <param_color>
+ <value
+ color="0, 0, 0, 255" />
+
+ <value
+ color="0, 0, 255, 255" />
+ </param_color>
+ </param>
+
+ <param
+ id="1050"
+ group="1"
+ wearable="socks"
+ edit_group="driven"
+ name="Socks Length bump"
+ value_min="0"
+ value_max="1"
+ value_default="0.35">
+ <param_alpha
+ tga_file="shoe_height_alpha.tga"
+ domain="0.01" />
+ </param>
+ </layer>
+
+ <layer
+ name="lower_shoes bump"
+ render_pass="bump"
+ fixed_color="128,128,128,255">
+ <texture
+ local_texture="lower_shoes"
+ local_texture_alpha_only="true" />
+
+ <param
+ id="1053"
+ group="1"
+ wearable="shoes"
+ edit_group="driven"
+ name="Shoe Height bump"
+ value_min="0"
+ value_max="1"
+ value_default="0.1">
+ <param_alpha
+ tga_file="shoe_height_alpha.tga"
+ domain="0.01" />
+ </param>
+ </layer>
+
+ <layer
+ name="lower_shoes">
+ <texture
+ local_texture="lower_shoes" />
+
+ <param
+ id="812"
+ group="0"
+ wearable="shoes"
+ edit_group="colorpicker"
+ name="shoes_red"
+ value_min="0"
+ value_max="1"
+ value_default="1">
+ <param_color>
+ <value
+ color="0, 0, 0, 255" />
+
+ <value
+ color="255, 0, 0, 255" />
+ </param_color>
+ </param>
+
+ <param
+ id="813"
+ group="0"
+ wearable="shoes"
+ edit_group="colorpicker"
+ name="shoes_green"
+ value_min="0"
+ value_max="1"
+ value_default="1">
+ <param_color>
+ <value
+ color="0, 0, 0, 255" />
+
+ <value
+ color="0, 255, 0, 255" />
+ </param_color>
+ </param>
+
+ <param
+ id="817"
+ group="0"
+ wearable="shoes"
+ edit_group="colorpicker"
+ name="shoes_blue"
+ value_min="0"
+ value_max="1"
+ value_default="1">
+ <param_color>
+ <value
+ color="0, 0, 0, 255" />
+
+ <value
+ color="0, 0, 255, 255" />
+ </param_color>
+ </param>
+
+ <param
+ id="1052"
+ group="1"
+ wearable="shoes"
+ edit_group="driven"
+ name="Shoe Height"
+ value_min="0"
+ value_max="1"
+ value_default="0.1">
+ <param_alpha
+ tga_file="shoe_height_alpha.tga"
+ domain="0.01" />
+ </param>
+ </layer>
+
+ <layer
+ name="lower_clothes_shadow">
+ <texture
+ local_texture="lower_pants" />
+
+ <param
+ id="913"
+ group="1"
+ edit_group="driven"
+ wearable="pants"
+ name="Lower Clothes Shading"
+ value_min="0"
+ value_max="1"
+ value_default="0">
+ <param_color>
+ <value
+ color="0, 0, 0, 0" />
+
+ <value
+ color="0, 0, 0, 80" />
+ </param_color>
+ </param>
+
+ <param
+ id="914"
+ group="1"
+ edit_group="driven"
+ wearable="pants"
+ name="Waist Height Shadow"
+ value_min="0.02"
+ value_max="1">
+ <param_alpha
+ tga_file="pants_waist_alpha.tga"
+ skip_if_zero="true"
+ domain="0.04" />
+ </param>
+
+ <param
+ id="915"
+ group="1"
+ edit_group="driven"
+ wearable="pants"
+ name="Pants Length Shadow"
+ value_min="0.02"
+ value_max="1">
+ <param_alpha
+ tga_file="pants_length_alpha.tga"
+ skip_if_zero="true"
+ domain="0.03" />
+ </param>
+ </layer>
+
+ <layer
+ name="lower_pants base bump"
+ render_pass="bump"
+ fixed_color="128,128,128,255">
+ <texture
+ local_texture="lower_pants"
+ local_texture_alpha_only="true" />
+
+ <param
+ id="1035"
+ group="1"
+ edit_group="driven"
+ wearable="pants"
+ name="Waist Height Cloth"
+ value_min="0"
+ value_max="1">
+ <param_alpha
+ tga_file="pants_waist_alpha.tga"
+ domain="0.05" />
+ </param>
+
+ <param
+ id="1036"
+ group="1"
+ edit_group="driven"
+ wearable="pants"
+ name="Pants Length Cloth"
+ value_min="0"
+ value_max="1">
+ <param_alpha
+ tga_file="pants_length_alpha.tga"
+ domain="0.01" />
+ </param>
+ </layer>
+
+ <layer
+ name="lower_pants bump"
+ render_pass="bump">
+ <texture
+ tga_file="bump_pants_wrinkles.tga" />
+
+ <texture
+ local_texture="lower_pants"
+ local_texture_alpha_only="true" />
+
+ <param
+ id="869"
+ group="3"
+ wearable="pants"
+ edit_group="pants"
+ edit_group_order="6"
+ name="Pants Wrinkles"
+ value_min="0"
+ value_max="1"
+ value_default="0">
+ <param_color>
+ <value
+ color="255, 255, 255, 0" />
+
+ <value
+ color="255, 255, 255, 255" />
+ </param_color>
+ </param>
+
+ <param
+ id="1017"
+ group="1"
+ edit_group="driven"
+ wearable="pants"
+ name="Waist Height Cloth"
+ value_min="0"
+ value_max="1">
+ <param_alpha
+ tga_file="pants_waist_alpha.tga"
+ domain="0.05" />
+ </param>
+
+ <param
+ id="1018"
+ group="1"
+ edit_group="driven"
+ wearable="pants"
+ name="Pants Length Cloth"
+ value_min="0"
+ value_max="1">
+ <param_alpha
+ tga_file="pants_length_alpha.tga"
+ domain="0.01" />
+ </param>
+ </layer>
+
+ <layer
+ name="lower_pants">
+ <texture
+ local_texture="lower_pants" />
+
+ <param
+ id="806"
+ group="0"
+ wearable="pants"
+ edit_group="colorpicker"
+ name="pants_red"
+ value_min="0"
+ value_max="1"
+ value_default="1">
+ <param_color>
+ <value
+ color="0, 0, 0, 255" />
+
+ <value
+ color="255, 0, 0, 255" />
+ </param_color>
+ </param>
+
+ <param
+ id="807"
+ group="0"
+ wearable="pants"
+ edit_group="colorpicker"
+ name="pants_green"
+ value_min="0"
+ value_max="1"
+ value_default="1">
+ <param_color>
+ <value
+ color="0, 0, 0, 255" />
+
+ <value
+ color="0, 255, 0, 255" />
+ </param_color>
+ </param>
+
+ <param
+ id="808"
+ group="0"
+ wearable="pants"
+ edit_group="colorpicker"
+ name="pants_blue"
+ value_min="0"
+ value_max="1"
+ value_default="1">
+ <param_color>
+ <value
+ color="0, 0, 0, 255" />
+
+ <value
+ color="0, 0, 255, 255" />
+ </param_color>
+ </param>
+
+ <param
+ id="614"
+ group="1"
+ edit_group="driven"
+ wearable="pants"
+ name="Waist Height Cloth"
+ value_min="0"
+ value_max="1"
+ value_default=".8">
+ <param_alpha
+ tga_file="pants_waist_alpha.tga"
+ domain="0.05" />
+ </param>
+
+ <param
+ id="615"
+ group="1"
+ edit_group="driven"
+ wearable="pants"
+ name="Pants Length Cloth"
+ value_min="0"
+ value_max="1"
+ value_default=".8">
+ <param_alpha
+ tga_file="pants_length_alpha.tga"
+ domain="0.01" />
+ </param>
+ </layer>
+
+ <layer
+ name="lower_jacket base bump"
+ render_pass="bump"
+ fixed_color="128,128,128,255">
+ <texture
+ local_texture="lower_jacket"
+ local_texture_alpha_only="true" />
+
+ <param
+ id="1033"
+ group="1"
+ wearable="jacket"
+ edit_group="driven"
+ cross_wearable="true"
+ name="jacket bottom length lower bump"
+ value_min="0"
+ value_max="1">
+ <param_alpha
+ multiply_blend="false"
+ tga_file="jacket_length_lower_alpha.tga"
+ domain="0.01" />
+ </param>
+
+ <param
+ id="1034"
+ group="1"
+ wearable="jacket"
+ edit_group="driven"
+ name="jacket open lower bump"
+ value_min="0"
+ value_max="1">
+ <param_alpha
+ multiply_blend="true"
+ tga_file="jacket_open_lower_alpha.tga"
+ domain="0.01" />
+ </param>
+ </layer>
+
+ <layer
+ name="lower_jacket bump"
+ render_pass="bump">
+ <texture
+ tga_file="bump_pants_wrinkles.tga" />
+
+ <texture
+ local_texture="lower_jacket"
+ local_texture_alpha_only="true" />
+
+
+ <param
+ id="876"
+ group="1"
+ wearable="jacket"
+ name="jacket upper Wrinkles"
+ value_min="0"
+ value_max="1"
+ value_default="0">
+ <param_color>
+ <value
+ color="255, 255, 255, 0" />
+
+ <value
+ color="255, 255, 255, 255" />
+ </param_color>
+ </param>
+
+ <param
+ id="1027"
+ group="1"
+ wearable="jacket"
+ edit_group="driven"
+ name="jacket bottom length lower bump"
+ value_min="0"
+ value_max="1">
+ <param_alpha
+ multiply_blend="false"
+ tga_file="jacket_length_lower_alpha.tga"
+ domain="0.01" />
+ </param>
+
+ <param
+ id="1028"
+ group="1"
+ wearable="jacket"
+ edit_group="driven"
+ name="jacket open lower bump"
+ value_min="0"
+ value_max="1">
+ <param_alpha
+ multiply_blend="true"
+ tga_file="jacket_open_lower_alpha.tga"
+ domain="0.01" />
+ </param>
+ </layer>
+
+ <layer
+ name="lower_jacket">
+ <texture
+ local_texture="lower_jacket" />
+
+ <param
+ id="809"
+ group="1"
+ edit_group="colorpicker_driven"
+ wearable="jacket"
+ name="lower_jacket_red"
+ value_min="0"
+ value_max="1"
+ value_default="1">
+ <param_color>
+ <value
+ color="0, 0, 0, 255" />
+
+ <value
+ color="255, 0, 0, 255" />
+ </param_color>
+ </param>
+
+ <param
+ id="810"
+ group="1"
+ edit_group="colorpicker_driven"
+ wearable="jacket"
+ name="lower_jacket_green"
+ value_min="0"
+ value_max="1"
+ value_default="1">
+ <param_color>
+ <value
+ color="0, 0, 0, 255" />
+
+ <value
+ color="0, 255, 0, 255" />
+ </param_color>
+ </param>
+
+ <param
+ id="811"
+ group="1"
+ edit_group="colorpicker_driven"
+ wearable="jacket"
+ name="lower_jacket_blue"
+ value_min="0"
+ value_max="1"
+ value_default="1">
+ <param_color>
+ <value
+ color="0, 0, 0, 255" />
+
+ <value
+ color="0, 0, 255, 255" />
+ </param_color>
+ </param>
+
+ <param
+ id="621"
+ group="1"
+ wearable="jacket"
+ edit_group="jacket"
+ name="bottom length lower"
+ label_min="hi cut"
+ label_max="low cut"
+ value_min="0"
+ value_max="1"
+ value_default=".8"
+ camera_distance="1.2"
+ camera_angle="30"
+ camera_elevation=".2">
+ <param_alpha
+ multiply_blend="false"
+ tga_file="jacket_length_lower_alpha.tga"
+ domain="0.01" />
+ </param>
+
+ <param
+ id="623"
+ group="1"
+ wearable="jacket"
+ edit_group="jacket"
+ name="open lower"
+ label_min="open"
+ label_max="closed"
+ value_min="0"
+ value_max="1"
+ value_default=".8"
+ camera_distance="1.2"
+ camera_angle="30"
+ camera_elevation=".2">
+ <param_alpha
+ multiply_blend="true"
+ tga_file="jacket_open_lower_alpha.tga"
+ domain="0.01" />
+ </param>
+ </layer>
+
+ <layer
+ name="lower alpha"
+ visibility_mask="TRUE">
+ <texture
+ local_texture="lower_alpha" />
+ </layer>
+
+ </layer_set>
+
+ <!-- =========================================================== -->
+ <layer_set
+ body_region="eyes"
+ width="128"
+ height="128">
+ <layer
+ name="whites">
+ <texture
+ tga_file="eyewhite.tga" />
+ </layer>
+
+ <layer
+ name="iris"
+ global_color="eye_color">
+ <texture
+ local_texture="eyes_iris" />
+ </layer>
+
+ <layer
+ name="eyes alpha"
+ visibility_mask="TRUE">
+ <texture
+ local_texture="eyes_alpha" />
+ </layer>
+
+ </layer_set>
+
+ <!-- =========================================================== -->
+ <layer_set
+ body_region="skirt"
+ width="512"
+ height="512"
+ clear_alpha="false">
+ <layer
+ name="skirt_fabric"
+ write_all_channels="true">
+ <texture
+ local_texture="skirt" />
+
+ <param
+ id="921"
+ group="0"
+ wearable="skirt"
+ edit_group="colorpicker"
+ name="skirt_red"
+ value_min="0"
+ value_max="1"
+ value_default="1">
+ <param_color>
+ <value
+ color="0, 0, 0, 255" />
+
+ <value
+ color="255, 0, 0, 255" />
+ </param_color>
+ </param>
+
+ <param
+ id="922"
+ group="0"
+ wearable="skirt"
+ edit_group="colorpicker"
+ name="skirt_green"
+ value_min="0"
+ value_max="1"
+ value_default="1">
+ <param_color>
+ <value
+ color="0, 0, 0, 255" />
+
+ <value
+ color="0, 255, 0, 255" />
+ </param_color>
+ </param>
+
+ <param
+ id="923"
+ group="0"
+ wearable="skirt"
+ edit_group="colorpicker"
+ name="skirt_blue"
+ value_min="0"
+ value_max="1"
+ value_default="1">
+ <param_color>
+ <value
+ color="0, 0, 0, 255" />
+
+ <value
+ color="0, 0, 255, 255" />
+ </param_color>
+ </param>
+ </layer>
+
+ <layer
+ name="skirt_fabric_alpha">
+ <param
+ id="858"
+ group="0"
+ wearable="skirt"
+ edit_group="skirt"
+ edit_group_order="1"
+ name="Skirt Length"
+ show_simple="true"
+ label_min="Short"
+ label_max="Long"
+ value_min=".01"
+ value_max="1"
+ value_default=".4"
+ simple_percent_min="40"
+ simple_percent_max="100"
+ camera_distance="1.3"
+ camera_elevation="-.5"
+ camera_angle="30">
+ <param_alpha
+ tga_file="skirt_length_alpha.tga"
+ domain="0"
+ multiply_blend="true" />
+ </param>
+
+ <param
+ id="859"
+ group="0"
+ wearable="skirt"
+ edit_group="skirt"
+ edit_group_order="4"
+ name="Slit Front"
+ label_min="Open Front"
+ label_max="Closed Front"
+ value_min="0"
+ value_max="1"
+ value_default="1"
+ camera_distance="1.3"
+ camera_elevation="-.5"
+ camera_angle="30">
+ <param_alpha
+ tga_file="skirt_slit_front_alpha.tga"
+ multiply_blend="true"
+ domain="0" />
+ </param>
+
+ <param
+ id="860"
+ group="0"
+ wearable="skirt"
+ edit_group="skirt"
+ edit_group_order="5"
+ name="Slit Back"
+ label_min="Open Back"
+ label_max="Closed Back"
+ value_min="0"
+ value_max="1"
+ value_default="1"
+ camera_distance="1.3"
+ camera_elevation="-.5"
+ camera_angle="160">
+ <param_alpha
+ tga_file="skirt_slit_back_alpha.tga"
+ multiply_blend="true"
+ domain="0" />
+ </param>
+
+ <param
+ id="861"
+ group="0"
+ wearable="skirt"
+ edit_group="skirt"
+ edit_group_order="6"
+ name="Slit Left"
+ label_min="Open Left"
+ label_max="Closed Left"
+ value_min="0"
+ value_max="1"
+ value_default="1"
+ camera_distance="1.3"
+ camera_elevation="-.5"
+ camera_angle="30">
+ <param_alpha
+ tga_file="skirt_slit_left_alpha.tga"
+ multiply_blend="true"
+ domain="0" />
+ </param>
+
+ <param
+ id="862"
+ group="0"
+ wearable="skirt"
+ edit_group="skirt"
+ edit_group_order="7"
+ name="Slit Right"
+ label_min="Open Right"
+ label_max="Closed Right"
+ value_min="0"
+ value_max="1"
+ value_default="1"
+ camera_distance="1.3"
+ camera_elevation="-.5"
+ camera_angle="-30">
+ <param_alpha
+ tga_file="skirt_slit_right_alpha.tga"
+ multiply_blend="true"
+ domain="0" />
+ </param>
+ </layer>
+
+ </layer_set>
+
+ <!-- =========================================================== -->
+ <driver_parameters>
+
+ <param
+ id="828"
+ group="0"
+ name="Loose Upper Clothing"
+ label="Shirt Fit"
+ show_simple="true"
+ wearable="shirt"
+ edit_group="shirt"
+ edit_group_order="4"
+ label_min="Tight Shirt"
+ label_max="Loose Shirt"
+ value_min="0"
+ value_max="1"
+ camera_distance="1.2"
+ camera_angle="30"
+ camera_elevation=".2">
+ <param_driver>
+ <driven
+ id="628" />
+
+ <driven
+ id="899"
+ min1="0.1"
+ max1="0.5"
+ max2="1"
+ min2="1" />
+ </param_driver>
+ </param>
+
+ <param
+ id="816"
+ group="0"
+ name="Loose Lower Clothing"
+ label="Pants Fit"
+ show_simple="true"
+ wearable="pants"
+ edit_group="pants"
+ edit_group_order="2.5"
+ label_min="Tight Pants"
+ label_max="Loose Pants"
+ value_min="0"
+ value_max="1"
+ camera_distance="1.8"
+ camera_angle="30"
+ camera_elevation="-.3">
+ <param_driver>
+ <driven
+ id="516" />
+
+ <driven
+ id="913"
+ min1="0.1"
+ max1="0.5"
+ max2="1"
+ min2="1" />
+ </param_driver>
+ </param>
+
+ <param
+ id="814"
+ group="0"
+ wearable="pants"
+ edit_group="pants"
+ edit_group_order="2"
+ name="Waist Height"
+ label_min="Low"
+ label_max="High"
+ value_min="0"
+ value_max="1"
+ value_default="1"
+ camera_distance="1.2"
+ camera_angle="30"
+ camera_elevation="-.3">
+ <param_driver>
+ <driven
+ id="614" />
+
+ <driven
+ id="1017" />
+
+ <driven
+ id="1035" />
+
+ <driven
+ id="914"
+ min1="0"
+ max1=".98"
+ max2="1"
+ min2="1" />
+ </param_driver>
+ </param>
+
+ <param
+ id="815"
+ group="0"
+ wearable="pants"
+ edit_group="pants"
+ edit_group_order="1"
+ name="Pants Length"
+ show_simple="true"
+ label_min="Short"
+ label_max="Long"
+ value_min="0"
+ value_max="1"
+ value_default=".8"
+ simple_percent_min="20"
+ simple_percent_max="100"
+ camera_distance="1.8"
+ camera_angle="30"
+ camera_elevation="-.3">
+ <param_driver>
+ <driven
+ id="615"
+ min1="0"
+ max1=".9"
+ max2="1"
+ min2="1" />
+
+ <driven
+ id="1018"
+ min1="0"
+ max1=".9"
+ max2="1"
+ min2="1" />
+
+ <driven
+ id="1036"
+ min1="0"
+ max1=".9"
+ max2="1"
+ min2="1" />
+
+ <driven
+ id="793"
+ min1=".9"
+ max1="1"
+ max2="1"
+ min2="1" />
+
+ <driven
+ id="915"
+ min1="0"
+ max1=".882"
+ max2="1"
+ min2="1" />
+ </param_driver>
+ </param>
+
+ <param
+ id="800"
+ group="0"
+ wearable="shirt"
+ edit_group="shirt"
+ edit_group_order="1"
+ name="Sleeve Length"
+ show_simple="true"
+ label_min="Short"
+ label_max="Long"
+ value_min="0"
+ value_max="1"
+ value_default=".89"
+ simple_percent_min="15"
+ simple_percent_max="100"
+ camera_distance="1.2"
+ camera_angle="30"
+ camera_elevation=".2">
+ <param_driver>
+ <driven
+ id="600" />
+
+ <driven
+ id="1013" />
+
+ <driven
+ id="1029" />
+
+ <driven
+ id="900"
+ min1="0"
+ max1="1"
+ max2="1"
+ min2="1" />
+ </param_driver>
+ </param>
+
+ <param
+ id="801"
+ group="0"
+ wearable="shirt"
+ edit_group="shirt"
+ edit_group_order="2"
+ name="Shirt Bottom"
+ label_min="Short"
+ label_max="Long"
+ value_min="0"
+ value_max="1"
+ value_default="1"
+ camera_distance="1.2"
+ camera_angle="30"
+ camera_elevation=".2">
+ <param_driver>
+ <driven
+ id="601" />
+
+ <driven
+ id="1014" />
+
+ <driven
+ id="1030" />
+
+ <driven
+ id="901"
+ min1="0"
+ max1=".98"
+ max2="1"
+ min2="1" />
+ </param_driver>
+ </param>
+
+ <param
+ id="802"
+ group="0"
+ wearable="shirt"
+ edit_group="shirt"
+ edit_group_order="3"
+ name="Collar Front"
+ show_simple="true"
+ label_min="Low"
+ label_max="High"
+ value_min="0"
+ value_max="1"
+ value_default=".78"
+ simple_percent_min="40"
+ simple_percent_max="100"
+ camera_distance="1.2"
+ camera_angle="15"
+ camera_elevation=".2">
+ <param_driver>
+ <driven
+ id="602" />
+
+ <driven
+ id="1015" />
+
+ <driven
+ id="1031" />
+
+ <driven
+ id="902"
+ min1="0"
+ max1=".98"
+ max2="1"
+ min2="1" />
+ </param_driver>
+ </param>
+
+ <param
+ id="781"
+ group="0"
+ wearable="shirt"
+ edit_group="shirt"
+ edit_group_order="3.1"
+ name="Collar Back"
+ label_min="Low"
+ label_max="High"
+ value_min="0"
+ value_max="1"
+ value_default=".78"
+ camera_distance="1.2"
+ camera_angle="195"
+ camera_elevation=".2">
+ <param_driver>
+ <driven
+ id="778" />
+
+ <driven
+ id="1016" />
+
+ <driven
+ id="1032" />
+
+ <driven
+ id="903"
+ min1="0"
+ max1=".98"
+ max2="1"
+ min2="1" />
+ </param_driver>
+ </param>
+
+ <param
+ id="150"
+ group="0"
+ wearable="skin"
+ edit_group="skin_bodydetail"
+ name="Body Definition"
+ label_min="Less"
+ label_max="More"
+ value_min="0"
+ value_max="1"
+ value_default="0"
+ camera_distance="1.4"
+ camera_elevation="-.2">
+ <param_driver>
+ <driven
+ id="125" />
+
+ <driven
+ id="126" />
+
+ <driven
+ id="160" />
+
+ <driven
+ id="161" />
+
+ <driven
+ id="874" />
+
+ <driven
+ id="878" />
+
+ </param_driver>
+ </param>
+
+ <param
+ id="775"
+ group="0"
+ wearable="skin"
+ edit_group="skin_bodydetail"
+ name="Body Freckles"
+ label_min="Less Freckles"
+ label_max="More Freckles"
+ value_min="0"
+ value_max="1"
+ value_default="0"
+ camera_distance="1.4"
+ camera_elevation="-.2">
+ <param_driver>
+ <driven
+ id="776" />
+
+ <driven
+ id="777" />
+ </param_driver>
+ </param>
+
+ <param
+ id="162"
+ group="0"
+ wearable="skin"
+ edit_group="skin_facedetail"
+ edit_group_order="1"
+ name="Facial Definition"
+ label_min="Less"
+ label_max="More"
+ value_min="0"
+ value_max="1"
+ camera_distance=".3"
+ camera_elevation=".07"
+ value_default="0">
+ <param_driver>
+ <driven
+ id="158" />
+
+ <driven
+ id="159" />
+
+ <driven
+ id="873" />
+ </param_driver>
+ </param>
+
+ <param
+ id="163"
+ group="3"
+ wearable="skin"
+ edit_group="skin_facedetail"
+ edit_group_order="3"
+ name="Wrinkles"
+ label_min="Less"
+ label_max="More"
+ value_min="0"
+ value_max="1"
+ camera_distance=".3"
+ camera_elevation=".07"
+ value_default="0">
+ <param_driver>
+ <!--<driven
+ id="128" />-->
+ <driven
+ id="118" />
+ </param_driver>
+ </param>
+
+ <param
+ id="505"
+ group="0"
+ wearable="shape"
+ edit_group="shape_mouth"
+ edit_group_order="3"
+ name="Lip Thickness"
+ label_min="Thin Lips"
+ label_max="Fat Lips"
+ value_min="0"
+ value_max="1"
+ value_default=".5"
+ camera_distance=".3"
+ camera_elevation=".04"
+ camera_angle="20">
+ <param_driver>
+ <driven
+ id="26"
+ min1="0"
+ max1="0"
+ max2="0"
+ min2=".5" />
+
+ <driven
+ id="28"
+ min1=".5"
+ max1="1"
+ max2="1"
+ min2="1" />
+ </param_driver>
+ </param>
+
+ <param
+ id="799"
+ group="0"
+ wearable="shape"
+ edit_group="shape_mouth"
+ edit_group_order="3.2"
+ name="Lip Ratio"
+ label="Lip Ratio"
+ show_simple="true"
+ label_min="More Upper Lip"
+ label_max="More Lower Lip"
+ value_min="0"
+ value_max="1"
+ value_default=".5"
+ camera_distance=".3"
+ camera_elevation=".04"
+ camera_angle="20">
+ <param_driver>
+ <driven
+ id="797"
+ min1="0"
+ max1="0"
+ max2="0"
+ min2=".5" />
+
+ <driven
+ id="798"
+ min1=".5"
+ max1="1"
+ max2="1"
+ min2="1" />
+ </param_driver>
+ </param>
+
+ <param
+ id="155"
+ group="0"
+ wearable="shape"
+ edit_group="shape_mouth"
+ edit_group_order="1"
+ name="Lip Width"
+ label="Lip Width"
+ label_min="Narrow Lips"
+ label_max="Wide Lips"
+ show_simple="true"
+ value_min="-0.9"
+ value_max="1.3"
+ camera_distance=".3"
+ camera_elevation=".04"
+ value_default="0">
+ <param_driver>
+ <driven
+ id="29" />
+
+ <driven
+ id="30" />
+ </param_driver>
+ </param>
+
+ <param
+ id="196"
+ group="0"
+ wearable="shape"
+ edit_group="shape_eyes"
+ edit_group_order="2"
+ name="Eye Spacing"
+ label="Eye Spacing"
+ label_min="Close Set Eyes"
+ label_max="Far Set Eyes"
+ show_simple="true"
+ value_min="-2"
+ value_max="1"
+ value_default="0"
+ camera_elevation=".1"
+ camera_distance=".35"
+ camera_angle="5">
+ <param_driver>
+ <driven
+ id="194" />
+
+ <driven
+ id="195" />
+ </param_driver>
+ </param>
+
+ <param
+ id="769"
+ group="0"
+ wearable="shape"
+ edit_group="shape_eyes"
+ edit_group_order="4.5"
+ name="Eye Depth"
+ label_min="Sunken Eyes"
+ label_max="Bugged Eyes"
+ value_min="0"
+ value_max="1"
+ value_default=".5"
+ camera_elevation=".1"
+ camera_distance=".3"
+ camera_angle="75">
+ <param_driver>
+ <driven
+ id="767" />
+
+ <driven
+ id="768" />
+ </param_driver>
+ </param>
+
+ <param
+ id="198"
+ group="0"
+ wearable="shoes"
+ edit_group="shoes"
+ edit_group_order="2"
+ name="Heel Height"
+ label_min="Low Heels"
+ label_max="High Heels"
+ value_min="0"
+ value_max="1"
+ value_default="0"
+ camera_angle="45"
+ camera_distance=".8"
+ camera_elevation="-1">
+ <param_driver>
+ <driven
+ id="197" />
+
+ <driven
+ id="500" />
+ </param_driver>
+ </param>
+
+ <param
+ id="513"
+ group="0"
+ wearable="shoes"
+ edit_group="shoes"
+ edit_group_order="3"
+ name="Heel Shape"
+ label_min="Pointy Heels"
+ label_max="Thick Heels"
+ value_min="0"
+ value_max="1"
+ value_default=".5"
+ camera_angle="45"
+ camera_distance="1.5"
+ camera_elevation="-1">
+ <param_driver>
+ <driven
+ id="509"
+ min1="0"
+ max1="0"
+ max2="0"
+ min2=".5" />
+
+ <driven
+ id="510"
+ min1=".5"
+ max1="1"
+ max2="1"
+ min2="1" />
+ </param_driver>
+ </param>
+
+ <param
+ id="514"
+ group="0"
+ wearable="shoes"
+ edit_group="shoes"
+ edit_group_order="4"
+ name="Toe Shape"
+ label_min="Pointy"
+ label_max="Square"
+ value_min="0"
+ value_max="1"
+ value_default=".5"
+ camera_angle="5"
+ camera_distance=".8"
+ camera_elevation="-.8">
+ <param_driver>
+ <driven
+ id="511"
+ min1="0"
+ max1="0"
+ max2="0"
+ min2=".5" />
+
+ <driven
+ id="512"
+ min1=".5"
+ max1="1"
+ max2="1"
+ min2="1" />
+ </param_driver>
+ </param>
+
+ <param
+ id="503"
+ group="0"
+ wearable="shoes"
+ edit_group="shoes"
+ edit_group_order="6"
+ name="Platform Height"
+ label_min="Low Platforms"
+ label_max="High Platforms"
+ value_min="0"
+ value_max="1"
+ value_default="0"
+ camera_angle="45"
+ camera_distance=".5"
+ camera_elevation="-1">
+ <param_driver>
+ <driven
+ id="501" />
+
+ <driven
+ id="502" />
+ </param_driver>
+ </param>
+
+ <param
+ id="193"
+ group="0"
+ wearable="shape"
+ edit_group="shape_head"
+ edit_group_order="3"
+ name="Head Shape"
+ label="Head Shape"
+ label_min="More Square"
+ label_max="More Round"
+ show_simple="true"
+ value_min="0"
+ value_max="1"
+ value_default=".5"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="20">
+ <param_driver>
+ <driven
+ id="188"
+ min1="0"
+ max1="0"
+ max2="0"
+ min2=".5" />
+
+ <driven
+ id="642"
+ min1="0"
+ max1="0"
+ max2="0"
+ min2=".5" />
+
+ <driven
+ id="189"
+ min1=".5"
+ max1="1"
+ max2="1"
+ min2="1" />
+
+ <driven
+ id="643"
+ min1=".5"
+ max1="1"
+ max2="1"
+ min2="1" />
+ </param_driver>
+ </param>
+
+ <param
+ id="157"
+ group="0"
+ wearable="shape"
+ edit_group="shape_torso"
+ edit_group_order="13"
+ name="Belly Size"
+ label_min="Small"
+ label_max="Big"
+ value_min="0"
+ value_max="1"
+ value_default="0"
+ camera_distance="1.4"
+ camera_angle="30"
+ camera_elevation=".2">
+ <param_driver>
+ <driven
+ id="104" />
+
+ <driven
+ id="156" />
+
+ <driven
+ id="849" />
+ </param_driver>
+ </param>
+
+ <param
+ id="637"
+ group="0"
+ wearable="shape"
+ edit_group="shape_body"
+ edit_group_order="3"
+ name="Body Fat"
+ label_min="Less Body Fat"
+ label_max="More Body Fat"
+ value_min="0"
+ value_max="1"
+ value_default="0"
+ camera_distance="1.8">
+ <param_driver>
+ <driven
+ id="633" />
+
+ <driven
+ id="634" />
+
+ <driven
+ id="635" />
+
+ <driven
+ id="851" />
+ </param_driver>
+ </param>
+
+ <param
+ id="130"
+ group="0"
+ wearable="hair"
+ edit_group="hair_style"
+ edit_group_order="8"
+ name="Front Fringe"
+ label_min="Short"
+ label_max="Long"
+ value_min="0"
+ value_max="1"
+ value_default=".45"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="20">
+ <param_driver>
+ <driven
+ id="144"
+ min1="0"
+ max1="0"
+ max2="0"
+ min2=".5" />
+
+ <driven
+ id="145"
+ min1=".5"
+ max1="1"
+ max2="1"
+ min2="1" />
+ </param_driver>
+ </param>
+
+ <param
+ id="131"
+ group="0"
+ wearable="hair"
+ edit_group="hair_style"
+ edit_group_order="9"
+ name="Side Fringe"
+ label_min="Short"
+ label_max="Long"
+ value_min="0"
+ value_max="1"
+ value_default=".5"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="90">
+ <param_driver>
+ <driven
+ id="146"
+ min1="0"
+ max1="0"
+ max2="0"
+ min2=".5" />
+
+ <driven
+ id="147"
+ min1=".5"
+ max1="1"
+ max2="1"
+ min2="1" />
+ </param_driver>
+ </param>
+
+ <param
+ id="132"
+ group="0"
+ wearable="hair"
+ edit_group="hair_style"
+ edit_group_order="10"
+ name="Back Fringe"
+ label_min="Short"
+ label_max="Long"
+ value_min="0"
+ value_max="1"
+ value_default=".39"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="160">
+ <param_driver>
+ <driven
+ id="148"
+ min1="0"
+ max1="0"
+ max2="0"
+ min2=".5" />
+
+ <driven
+ id="149"
+ min1=".5"
+ max1="1"
+ max2="1"
+ min2="1" />
+ </param_driver>
+ </param>
+
+ <param
+ id="133"
+ group="0"
+ wearable="hair"
+ edit_group="hair_style"
+ edit_group_order="2"
+ name="Hair Front"
+ label_min="Short"
+ label_max="Long"
+ value_min="0"
+ value_max="1"
+ value_default=".25"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="20">
+ <param_driver>
+ <driven
+ id="172"
+ min1="0"
+ max1="0"
+ max2="0"
+ min2=".5" />
+
+ <driven
+ id="171"
+ min1=".5"
+ max1="1"
+ max2="1"
+ min2="1" />
+ </param_driver>
+ </param>
+
+ <param
+ id="134"
+ group="0"
+ wearable="hair"
+ edit_group="hair_style"
+ edit_group_order="3"
+ name="Hair Sides"
+ label_min="Short"
+ label_max="Long"
+ value_min="0"
+ value_max="1"
+ value_default=".5"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="90">
+ <param_driver>
+ <driven
+ id="174"
+ min1="0"
+ max1="0"
+ max2="0"
+ min2=".5" />
+
+ <driven
+ id="173"
+ min1=".5"
+ max1="1"
+ max2="1"
+ min2="1" />
+ </param_driver>
+ </param>
+
+ <param
+ id="135"
+ group="0"
+ wearable="hair"
+ edit_group="hair_style"
+ edit_group_order="4"
+ name="Hair Back"
+ show_simple="true"
+ label_min="Short"
+ label_max="Long"
+ value_min="0"
+ value_max="1"
+ value_default=".55"
+ camera_elevation="-.1"
+ camera_distance=".8"
+ camera_angle="160">
+ <param_driver>
+ <driven
+ id="176"
+ min1="0"
+ max1="0"
+ max2="0"
+ min2=".5" />
+
+ <driven
+ id="175"
+ min1=".5"
+ max1="1"
+ max2="1"
+ min2="1" />
+ </param_driver>
+ </param>
+
+ <param
+ id="136"
+ group="0"
+ wearable="hair"
+ edit_group="hair_style"
+ edit_group_order="11.5"
+ name="Hair Sweep"
+ label_min="Sweep Forward"
+ label_max="Sweep Back"
+ value_min="0"
+ value_max="1"
+ value_default=".5"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="90">
+ <param_driver>
+ <driven
+ id="179"
+ min1="0"
+ max1="0"
+ max2="0"
+ min2=".5" />
+
+ <driven
+ id="178"
+ min1=".5"
+ max1="1"
+ max2="1"
+ min2="1" />
+ </param_driver>
+ </param>
+
+ <param
+ id="137"
+ group="0"
+ wearable="hair"
+ edit_group="hair_style"
+ edit_group_order="16"
+ name="Hair Tilt"
+ label_min="Left"
+ label_max="Right"
+ value_min="0"
+ value_max="1"
+ value_default=".5"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="0">
+ <param_driver>
+ <driven
+ id="190"
+ min1="0"
+ max1="0"
+ max2="0"
+ min2=".5" />
+
+ <driven
+ id="191"
+ min1=".5"
+ max1="1"
+ max2="1"
+ min2="1" />
+ </param_driver>
+ </param>
+
+ <param
+ id="608"
+ group="0"
+ wearable="jacket"
+ edit_group="jacket"
+ edit_group_order="2"
+ name="bottom length lower"
+ label="Jacket Length"
+ label_min="Short"
+ label_max="Long"
+ value_min="0"
+ value_max="1"
+ value_default=".8"
+ camera_distance="1.4"
+ camera_angle="30"
+ camera_elevation=".2">
+ <param_driver>
+ <driven
+ id="620" />
+
+ <driven
+ id="1025" />
+
+ <driven
+ id="1037" />
+
+ <driven
+ id="621" />
+
+ <driven
+ id="1027" />
+
+ <driven
+ id="1033" />
+ </param_driver>
+ </param>
+
+ <param
+ id="609"
+ group="0"
+ wearable="jacket"
+ edit_group="jacket"
+ edit_group_order="4"
+ name="open jacket"
+ label="Open Front"
+ label_min="Open"
+ label_max="Closed"
+ value_min="0"
+ value_max="1"
+ value_default=".2"
+ camera_distance="1.4"
+ camera_angle="30"
+ camera_elevation=".2">
+ <param_driver>
+ <driven
+ id="622" />
+
+ <driven
+ id="1026" />
+
+ <driven
+ id="1038" />
+
+ <driven
+ id="623" />
+
+ <driven
+ id="1028" />
+
+ <driven
+ id="1034" />
+ </param_driver>
+ </param>
+
+ <param
+ id="105"
+ group="0"
+ sex="female"
+ wearable="shape"
+ edit_group="shape_torso"
+ edit_group_order="6"
+ name="Breast Size"
+ label_min="Small"
+ label_max="Large"
+ value_min="0"
+ value_max="1"
+ value_default=".5"
+ camera_elevation=".3"
+ camera_distance="1.2"
+ camera_angle="30">
+ <param_driver>
+ <driven
+ id="843"
+ min1="0"
+ max1="0"
+ max2="0"
+ min2=".01" />
+
+ <driven
+ id="627"
+ min1="0"
+ max1="0.01"
+ max2="0.01"
+ min2=".5" />
+
+ <driven
+ id="626"
+ min1=".5"
+ max1="1"
+ max2="1"
+ min2="1" />
+ </param_driver>
+ </param>
+
+ <param
+ id="629"
+ group="0"
+ wearable="shape"
+ edit_group="shape_head"
+ edit_group_order="6"
+ name="Forehead Angle"
+ label_min="More Vertical"
+ label_max="More Sloped"
+ value_min="0"
+ value_max="1"
+ value_default=".5"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="70">
+ <param_driver>
+ <driven
+ id="630"
+ min1="0"
+ max1="0"
+ max2="0"
+ min2=".5" />
+
+ <driven
+ id="644"
+ min1="0"
+ max1="0"
+ max2="0"
+ min2=".5" />
+
+ <driven
+ id="631"
+ min1=".5"
+ max1="1"
+ max2="1"
+ min2="1" />
+
+ <driven
+ id="645"
+ min1=".5"
+ max1="1"
+ max2="1"
+ min2="1" />
+ </param_driver>
+ </param>
+
+ <param
+ id="646"
+ group="0"
+ name="Egg_Head"
+ label="Egg Head"
+ wearable="shape"
+ edit_group="shape_head"
+ edit_group_order="4"
+ label_min="Chin Heavy"
+ label_max="Forehead Heavy"
+ show_simple="true"
+ value_min="-1.3"
+ value_max="1"
+ value_default="0"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="20">
+ <param_driver>
+ <driven
+ id="640" />
+
+ <driven
+ id="186" />
+ </param_driver>
+ </param>
+
+ <param
+ id="647"
+ group="0"
+ name="Squash_Stretch_Head"
+ label="Head Stretch"
+ wearable="shape"
+ edit_group="shape_head"
+ edit_group_order="2"
+ show_simple="true"
+ label_min="Squash Head"
+ label_max="Stretch Head"
+ value_min="-0.5"
+ value_max="1"
+ value_default="0"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="20">
+ <param_driver>
+ <driven
+ id="641" />
+
+ <driven
+ id="187" />
+ </param_driver>
+ </param>
+
+ <param
+ id="649"
+ group="0"
+ sex="female"
+ wearable="shape"
+ edit_group="shape_torso"
+ edit_group_order="1.1"
+ name="Torso Muscles"
+ label="Torso Muscles"
+ show_simple="true"
+ label_min="Less Muscular"
+ label_max="More Muscular"
+ value_min="0"
+ value_max="1"
+ value_default=".5"
+ camera_elevation=".1"
+ camera_distance="1"
+ camera_angle="15">
+ <param_driver>
+ <driven
+ id="648"
+ min1="0"
+ max1="0"
+ max2="0"
+ min2=".5" />
+
+ <driven
+ id="106"
+ min1=".5"
+ max1="1"
+ max2="1"
+ min2="1" />
+ </param_driver>
+ </param>
+
+ <param
+ id="678"
+ group="0"
+ sex="male"
+ wearable="shape"
+ edit_group="shape_torso"
+ edit_group_order="1"
+ name="Torso Muscles"
+ show_simple="true"
+ label_min="Less Muscular"
+ label_max="More Muscular"
+ value_min="0"
+ value_max="1"
+ value_default=".5"
+ camera_elevation=".1"
+ camera_distance="1.2"
+ camera_angle="0">
+ <param_driver>
+ <driven
+ id="677"
+ min1="0"
+ max1="0"
+ max2="0"
+ min2=".5" />
+
+ <driven
+ id="106"
+ min1=".5"
+ max1="1"
+ max2="1"
+ min2="1" />
+ </param_driver>
+ </param>
+
+ <param
+ id="652"
+ group="0"
+ wearable="shape"
+ edit_group="shape_legs"
+ edit_group_order="1"
+ name="Leg Muscles"
+ label_min="Less Muscular"
+ label_max="More Muscular"
+ show_simple="true"
+ value_min="0"
+ value_max="1"
+ value_default=".5"
+ camera_distance="1.3"
+ camera_elevation="-.5"
+ camera_angle="15">
+ <param_driver>
+ <driven
+ id="651"
+ min1="0"
+ max1="0"
+ max2="0"
+ min2=".5" />
+
+ <driven
+ id="152"
+ min1=".5"
+ max1="1"
+ max2="1"
+ min2="1" />
+ </param_driver>
+ </param>
+
+ <param
+ id="80"
+ name="male"
+ group="0"
+ edit_group="dummy"
+ wearable="shape"
+ value_min="0"
+ value_max="1">
+ <param_driver>
+ <driven
+ id="32" />
+
+ <driven
+ id="153" />
+
+ <driven
+ id="40" />
+
+ <driven
+ id="100" />
+
+ <driven
+ id="857" />
+ </param_driver>
+ </param>
+
+ <param
+ id="659"
+ group="0"
+ wearable="shape"
+ edit_group="shape_mouth"
+ edit_group_order="5"
+ name="Mouth Corner"
+ label_min="Corner Down"
+ label_max="Corner Up"
+ value_min="0"
+ value_max="1"
+ value_default=".5"
+ camera_elevation="0"
+ camera_distance=".28">
+ <param_driver>
+ <driven
+ id="658"
+ min1="0"
+ max1="0"
+ max2="0"
+ min2=".5" />
+
+ <driven
+ id="657"
+ min1=".5"
+ max1="1"
+ max2="1"
+ min2="1" />
+ </param_driver>
+ </param>
+
+ <param
+ id="662"
+ group="0"
+ wearable="shape"
+ edit_group="shape_head"
+ edit_group_order="5"
+ name="Face Shear"
+ label_min="Shear Right Up"
+ label_max="Shear Left Up"
+ value_min="0"
+ value_max="1"
+ value_default=".5"
+ camera_elevation=".1"
+ camera_distance=".5">
+ <param_driver>
+ <driven
+ id="660" />
+
+ <driven
+ id="661" />
+
+ <driven
+ id="774" />
+ </param_driver>
+ </param>
+
+ <param
+ id="773"
+ group="0"
+ wearable="shape"
+ edit_group="shape_head"
+ edit_group_order="4.5"
+ name="Head Length"
+ label_min="Flat Head"
+ label_max="Long Head"
+ value_min="0"
+ value_max="1"
+ value_default=".5"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="75">
+ <param_driver>
+ <driven
+ id="770" />
+
+ <driven
+ id="771" />
+
+ <driven
+ id="772" />
+ </param_driver>
+ </param>
+
+ <param
+ id="682"
+ group="0"
+ wearable="shape"
+ edit_group="shape_head"
+ edit_group_order="1"
+ name="Head Size"
+ label="Head Size"
+ label_min="Small Head"
+ label_max="Big Head"
+ show_simple="true"
+ value_min="0"
+ value_max="1"
+ value_default=".5"
+ camera_elevation=".1"
+ camera_distance=".5">
+ <param_driver>
+ <driven
+ id="679" />
+
+ <driven
+ id="694" />
+
+ <driven
+ id="680" />
+
+ <driven
+ id="681" />
+
+ <driven
+ id="655" />
+ </param_driver>
+ </param>
+
+ <param
+ id="690"
+ group="0"
+ wearable="shape"
+ edit_group="shape_eyes"
+ edit_group_order="1"
+ name="Eye Size"
+ label="Eye Size"
+ label_min="Beady Eyes"
+ label_max="Anime Eyes"
+ value_min="0"
+ value_max="1"
+ value_default=".5"
+ show_simple="true"
+ camera_elevation=".1"
+ camera_distance=".35">
+ <param_driver>
+ <driven
+ id="686" />
+
+ <driven
+ id="687" />
+
+ <driven
+ id="695" />
+
+ <driven
+ id="688" />
+
+ <driven
+ id="691" />
+
+ <driven
+ id="689" />
+ </param_driver>
+ </param>
+
+ <param
+ id="752"
+ group="0"
+ sex="male"
+ wearable="hair"
+ edit_group="hair_facial"
+ edit_group_order="1"
+ name="Hair Thickness"
+ label_min="5 O'Clock Shadow"
+ label_max="Bushy Hair"
+ value_min="0"
+ value_max="1"
+ value_default=".5"
+ camera_elevation="0"
+ camera_distance=".28">
+ <param_driver>
+ <driven
+ id="751"
+ min1="0"
+ max1="0"
+ max2="0"
+ min2=".2" />
+
+ <driven
+ id="1012"
+ min1="0"
+ max1="0"
+ max2=".2"
+ min2=".6" />
+
+ <driven
+ id="400"
+ min1=".2"
+ max1="1"
+ max2="1"
+ min2="1" />
+ </param_driver>
+ </param>
+
+ <param
+ id="763"
+ group="0"
+ wearable="hair"
+ edit_group="hair_style"
+ edit_group_order="1"
+ name="Hair Volume"
+ show_simple="true"
+ label_min="Less Volume"
+ label_max="More Volume"
+ value_min="0"
+ value_max="1"
+ value_default=".55"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="20">
+ <param_driver>
+ <driven
+ id="761"
+ min1="0"
+ max1="0"
+ max2="0"
+ min2=".5" />
+
+ <driven
+ id="180"
+ min1=".5"
+ max1="1"
+ max2="1"
+ min2="1" />
+ </param_driver>
+ </param>
+
+ <param
+ id="834"
+ group="0"
+ wearable="jacket"
+ edit_group="colorpicker"
+ name="jacket_red"
+ value_min="0"
+ value_max="1"
+ value_default="1">
+ <param_driver>
+ <driven
+ id="809"
+ min1="0"
+ max1="1"
+ max2="1"
+ min2="1" />
+
+ <driven
+ id="831"
+ min1="0"
+ max1="1"
+ max2="1"
+ min2="1" />
+ </param_driver>
+ </param>
+
+ <param
+ id="835"
+ group="0"
+ wearable="jacket"
+ edit_group="colorpicker"
+ name="jacket_green"
+ value_min="0"
+ value_max="1"
+ value_default="1">
+ <param_driver>
+ <driven
+ id="810"
+ min1="0"
+ max1="1"
+ max2="1"
+ min2="1" />
+
+ <driven
+ id="832"
+ min1="0"
+ max1="1"
+ max2="1"
+ min2="1" />
+ </param_driver>
+ </param>
+
+ <param
+ id="836"
+ group="0"
+ wearable="jacket"
+ edit_group="colorpicker"
+ name="jacket_blue"
+ value_min="0"
+ value_max="1"
+ value_default="1">
+ <param_driver>
+ <driven
+ id="811"
+ min1="0"
+ max1="1"
+ max2="1"
+ min2="1" />
+
+ <driven
+ id="833"
+ min1="0"
+ max1="1"
+ max2="1"
+ min2="1" />
+ </param_driver>
+ </param>
+
+ <param
+ id="785"
+ group="0"
+ wearable="hair"
+ edit_group="hair_style"
+ edit_group_order="14.6"
+ name="Pigtails"
+ show_simple="true"
+ label_min="Short Pigtails"
+ label_max="Long Pigtails"
+ value_min="0"
+ value_max="1"
+ value_default="0"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="15">
+ <param_driver>
+ <driven
+ id="782"
+ min1="0"
+ max1=".10"
+ max2=".10"
+ min2=".5" />
+
+ <driven
+ id="783"
+ min1=".10"
+ max1=".5"
+ max2=".5"
+ min2=".75" />
+
+ <driven
+ id="790"
+ min1=".5"
+ max1=".75"
+ max2=".75"
+ min2="1" />
+
+ <driven
+ id="784"
+ min1=".75"
+ max1="1"
+ max2="1"
+ min2="1" />
+ </param_driver>
+ </param>
+
+ <param
+ id="789"
+ group="0"
+ wearable="hair"
+ edit_group="hair_style"
+ edit_group_order="14.7"
+ name="Ponytail"
+ label_min="Short Ponytail"
+ label_max="Long Ponytail"
+ value_min="0"
+ value_max="1"
+ value_default="0"
+ camera_elevation=".1"
+ camera_distance=".5"
+ camera_angle="180">
+ <param_driver>
+ <driven
+ id="786"
+ min1="0"
+ max1=".10"
+ max2=".10"
+ min2=".66" />
+
+ <driven
+ id="787"
+ min1=".10"
+ max1=".66"
+ max2=".66"
+ min2="1" />
+
+ <driven
+ id="788"
+ min1=".66"
+ max1="1"
+ max2="1"
+ min2="1" />
+ </param_driver>
+ </param>
+
+ <param
+ id="795"
+ group="0"
+ name="Butt Size"
+ label="Butt Size"
+ wearable="shape"
+ edit_group="shape_legs"
+ edit_group_order="4"
+ label_min="Flat Butt"
+ label_max="Big Butt"
+ value_min="0"
+ value_max="1"
+ value_default=".25"
+ camera_angle="180"
+ camera_distance=".6">
+ <param_driver>
+ <driven
+ id="867"
+ min1="0"
+ max1="0"
+ max2="0"
+ min2=".3" />
+
+ <driven
+ id="794"
+ min1="0"
+ max1="0"
+ max2="0"
+ min2=".3" />
+
+ <driven
+ id="151"
+ min1=".3"
+ max1="1"
+ max2="1"
+ min2="1" />
+
+ <driven
+ id="852"
+ min1=".3"
+ max1="1"
+ max2="1"
+ min2="1" />
+ </param_driver>
+ </param>
+
+ <param
+ id="841"
+ group="0"
+ name="Bowed_Legs"
+ label="Knee Angle"
+ wearable="shape"
+ edit_group_order="5.5"
+ edit_group="shape_legs"
+ label_min="Knock Kneed"
+ label_max="Bow Legged"
+ value_min="-1"
+ value_max="1"
+ value_default="0"
+ camera_distance="1.3"
+ camera_elevation="-.5">
+ <param_driver>
+ <driven
+ id="853" />
+
+ <driven
+ id="847" />
+ </param_driver>
+ </param>
+
+ <param
+ id="753"
+ group="0"
+ name="Saddlebags"
+ label="Saddle Bags"
+ wearable="shape"
+ edit_group="shape_legs"
+ edit_group_order="5"
+ label_min="Less Saddle"
+ label_max="More Saddle"
+ value_min="-0.5"
+ value_max="3"
+ value_default="0"
+ camera_angle="0"
+ camera_distance="1.2">
+ <param_driver>
+ <driven
+ id="850" />
+
+ <driven
+ id="854" />
+ </param_driver>
+ </param>
+
+ <param
+ id="676"
+ group="0"
+ name="Love_Handles"
+ label="Love Handles"
+ wearable="shape"
+ edit_group="shape_torso"
+ edit_group_order="12"
+ label_min="Less Love"
+ label_max="More Love"
+ value_min="-1"
+ value_max="2"
+ value_default="0"
+ camera_elevation=".3"
+ camera_distance=".9">
+ <param_driver>
+ <driven
+ id="855" />
+
+ <driven
+ id="856" />
+ </param_driver>
+ </param>
+
+ <param
+ id="863"
+ group="0"
+ name="skirt_looseness"
+ label="Skirt Fit"
+ show_simple="true"
+ clothing_morph="true"
+ wearable="skirt"
+ edit_group_order="2"
+ edit_group="skirt"
+ label_min="Tight Skirt"
+ label_max="Poofy Skirt"
+ value_min="0"
+ value_max="1"
+ value_default=".333"
+ camera_distance="1.3"
+ camera_elevation="-.5">
+ <param_driver>
+ <driven
+ id="866"
+ min1="0"
+ max1="0"
+ max2="0"
+ min2=".2" />
+
+ <driven
+ id="846"
+ min1="0"
+ max1=".5"
+ max2=".5"
+ min2="1" />
+
+ <driven
+ id="845"
+ min1=".5"
+ max1="1"
+ max2="1"
+ min2="1" />
+ </param_driver>
+ </param>
+
+ <param
+ id="119"
+ group="0"
+ wearable="hair"
+ edit_group="hair_eyebrows"
+ edit_group_order="1"
+ name="Eyebrow Size"
+ show_simple="true"
+ label_min="Thin Eyebrows"
+ label_max="Bushy Eyebrows"
+ value_min="0"
+ value_max="1"
+ value_default="0.5"
+ camera_elevation=".1"
+ camera_distance=".3">
+ <param_driver>
+ <driven
+ id="1000" />
+
+ <driven
+ id="1001" />
+ </param_driver>
+ </param>
+
+ <param
+ id="750"
+ group="0"
+ wearable="hair"
+ edit_group="hair_eyebrows"
+ edit_group_order="2"
+ name="Eyebrow Density"
+ label_min="Sparse"
+ label_max="Dense"
+ value_min="0"
+ value_max="1"
+ value_default="0.7"
+ camera_elevation=".1"
+ camera_distance=".3">
+ <param_driver>
+ <driven
+ id="1002" />
+
+ <driven
+ id="1003" />
+ </param_driver>
+ </param>
+
+ <param
+ id="166"
+ sex="male"
+ group="0"
+ wearable="hair"
+ edit_group="hair_facial"
+ edit_group_order="2"
+ name="Sideburns"
+ show_simple="true"
+ label_min="Short Sideburns"
+ label_max="Mutton Chops"
+ value_min="0"
+ value_max="1"
+ value_default="0.0"
+ camera_elevation=".1"
+ camera_distance=".3"
+ camera_angle="30">
+ <param_driver>
+ <driven
+ id="1004" />
+
+ <driven
+ id="1005" />
+ </param_driver>
+ </param>
+
+ <param
+ id="167"
+ sex="male"
+ group="0"
+ wearable="hair"
+ edit_group="hair_facial"
+ edit_group_order="3"
+ name="Moustache"
+ show_simple="true"
+ label_min="Chaplin"
+ label_max="Handlebars"
+ value_min="0"
+ value_max="1"
+ value_default="0.0"
+ camera_elevation=".1"
+ camera_distance=".3"
+ camera_angle="30">
+ <param_driver>
+ <driven
+ id="1006" />
+
+ <driven
+ id="1007" />
+ </param_driver>
+ </param>
+
+ <param
+ id="168"
+ sex="male"
+ group="0"
+ wearable="hair"
+ edit_group="hair_facial"
+ edit_group_order="5"
+ name="Soulpatch"
+ show_simple="true"
+ label_min="Less soul"
+ label_max="More soul"
+ value_min="0"
+ value_max="1"
+ value_default="0.0"
+ camera_elevation="-.1"
+ camera_distance=".3"
+ camera_angle="0">
+ <param_driver>
+ <driven
+ id="1008" />
+
+ <driven
+ id="1009" />
+ </param_driver>
+ </param>
+
+ <param
+ id="169"
+ sex="male"
+ group="0"
+ wearable="hair"
+ edit_group="hair_facial"
+ edit_group_order="4"
+ name="Chin Curtains"
+ show_simple="true"
+ label_min="Less Curtains"
+ label_max="More Curtains"
+ value_min="0"
+ value_max="1"
+ value_default="0.0"
+ camera_elevation="-.1"
+ camera_distance=".3"
+ camera_angle="45">
+ <param_driver>
+ <driven
+ id="1010" />
+
+ <driven
+ id="1011" />
+ </param_driver>
+ </param>
+
+ <param
+ id="606"
+ group="0"
+ wearable="jacket"
+ edit_group="jacket"
+ edit_group_order="1"
+ name="Sleeve Length"
+ label_min="Short"
+ label_max="Long"
+ value_min="0"
+ value_max="1"
+ value_default=".8"
+ camera_distance="1.2"
+ camera_angle="30"
+ camera_elevation=".2">
+ <param_driver>
+ <driven
+ id="1019" />
+
+ <driven
+ id="1039" />
+
+ <driven
+ id="1020" />
+ </param_driver>
+ </param>
+
+ <param
+ id="607"
+ group="0"
+ wearable="jacket"
+ edit_group="jacket"
+ edit_group_order="3"
+ name="Collar Front"
+ label_min="Low"
+ label_max="High"
+ value_min="0"
+ value_max="1"
+ value_default=".8"
+ camera_distance="1.2"
+ camera_angle="15"
+ camera_elevation=".2">
+ <param_driver>
+ <driven
+ id="1021" />
+
+ <driven
+ id="1040" />
+
+ <driven
+ id="1022" />
+ </param_driver>
+ </param>
+
+ <param
+ id="780"
+ group="0"
+ wearable="jacket"
+ edit_group="jacket"
+ edit_group_order="3.5"
+ name="Collar Back"
+ label_min="Low"
+ label_max="High"
+ value_min="0"
+ value_max="1"
+ value_default=".8"
+ camera_distance="1.2"
+ camera_angle="195"
+ camera_elevation=".2">
+ <param_driver>
+ <driven
+ id="1023" />
+
+ <driven
+ id="1041" />
+
+ <driven
+ id="1024" />
+ </param_driver>
+ </param>
+
+ <param
+ id="603"
+ group="0"
+ wearable="undershirt"
+ edit_group="undershirt"
+ edit_group_order="1"
+ name="Sleeve Length"
+ label_min="Short"
+ label_max="Long"
+ value_min=".01"
+ value_max="1"
+ value_default=".4"
+ camera_distance="1.2"
+ camera_angle="30"
+ camera_elevation=".2">
+ <param_driver>
+ <driven
+ id="1042" />
+
+ <driven
+ id="1043" />
+ </param_driver>
+ </param>
+
+ <param
+ id="604"
+ group="0"
+ wearable="undershirt"
+ edit_group="undershirt"
+ edit_group_order="2"
+ name="Bottom"
+ label_min="Short"
+ label_max="Long"
+ value_min="0"
+ value_max="1"
+ value_default=".85"
+ camera_distance="1.2"
+ camera_angle="30"
+ camera_elevation=".2">
+ <param_driver>
+ <driven
+ id="1044" />
+
+ <driven
+ id="1045" />
+ </param_driver>
+ </param>
+
+ <param
+ id="605"
+ group="0"
+ wearable="undershirt"
+ edit_group="undershirt"
+ edit_group_order="3"
+ name="Collar Front"
+ label_min="Low"
+ label_max="High"
+ value_min="0"
+ value_max="1"
+ value_default=".84"
+ camera_distance=".8"
+ camera_angle="15"
+ camera_elevation=".2">
+ <param_driver>
+ <driven
+ id="1046" />
+
+ <driven
+ id="1047" />
+ </param_driver>
+ </param>
+
+ <param
+ id="779"
+ group="0"
+ wearable="undershirt"
+ edit_group="undershirt"
+ edit_group_order="4"
+ name="Collar Back"
+ label_min="Low"
+ label_max="High"
+ value_min="0"
+ value_max="1"
+ value_default=".84"
+ camera_distance=".8"
+ camera_angle="195"
+ camera_elevation=".2">
+ <param_driver>
+ <driven
+ id="1048" />
+
+ <driven
+ id="1049" />
+ </param_driver>
+ </param>
+
+ <param
+ id="617"
+ group="0"
+ wearable="socks"
+ edit_group="socks"
+ name="Socks Length"
+ label_min="Short"
+ label_max="Long"
+ value_min="0"
+ value_max="1"
+ value_default="0.35"
+ camera_distance=".95"
+ camera_angle="30"
+ camera_elevation="-.75">
+ <param_driver>
+ <driven
+ id="1050" />
+
+ <driven
+ id="1051" />
+ </param_driver>
+ </param>
+
+ <param
+ id="616"
+ group="0"
+ wearable="shoes"
+ edit_group="shoes"
+ edit_group_order="1"
+ name="Shoe Height"
+ label_min="Short"
+ label_max="Tall"
+ value_min="0"
+ value_max="1"
+ value_default="0.1"
+ camera_distance="1.2"
+ camera_angle="30"
+ camera_elevation="-.75">
+ <param_driver>
+ <driven
+ id="1052" />
+
+ <driven
+ id="1053" />
+ </param_driver>
+ </param>
+
+ <param
+ id="619"
+ group="0"
+ wearable="underpants"
+ edit_group="underpants"
+ name="Pants Length"
+ label_min="Short"
+ label_max="Long"
+ value_min="0"
+ value_max="1"
+ value_default=".3"
+ camera_distance="1.2"
+ camera_angle="30"
+ camera_elevation="-.3">
+ <param_driver>
+ <driven
+ id="1054" />
+
+ <driven
+ id="1055" />
+ </param_driver>
+ </param>
+
+ <param
+ id="624"
+ group="0"
+ wearable="underpants"
+ edit_group="underpants"
+ name="Pants Waist"
+ label_min="Low"
+ label_max="High"
+ value_min="0"
+ value_max="1"
+ value_default=".8"
+ camera_distance="1.2"
+ camera_angle="30"
+ camera_elevation="-.3">
+ <param_driver>
+ <driven
+ id="1056" />
+
+ <driven
+ id="1057" />
+ </param_driver>
+ </param>
+
+ <param
+ id="93"
+ group="0"
+ wearable="gloves"
+ edit_group="gloves"
+ name="Glove Length"
+ label_min="Short"
+ label_max="Long"
+ value_min=".01"
+ value_max="1"
+ value_default=".8"
+ camera_distance="1.2"
+ camera_angle="30"
+ camera_elevation=".2">
+ <param_driver>
+ <driven
+ id="1058" />
+
+ <driven
+ id="1059" />
+ </param_driver>
+ </param>
+
+ <param
+ id="844"
+ group="0"
+ wearable="gloves"
+ edit_group="gloves"
+ name="Glove Fingers"
+ label_min="Fingerless"
+ label_max="Fingers"
+ value_min=".01"
+ value_max="1"
+ value_default="1"
+ camera_distance="1.2"
+ camera_angle="30"
+ camera_elevation=".2">
+ <param_driver>
+ <driven
+ id="1060" />
+
+ <driven
+ id="1061" />
+ </param_driver>
+ </param>
+
+ <!--Pointy eyebrows became a driver/driven param with new max value for backwards compatibility between 1.0 and 1.1-->
+ <param
+ id="16"
+ group="0"
+ name="Pointy_Eyebrows"
+ label="Eyebrow Points"
+ wearable="hair"
+ edit_group="hair_eyebrows"
+ edit_group_order="4"
+ label_min="Smooth"
+ label_max="Pointy"
+ value_min="-.5"
+ value_max="3"
+ camera_elevation=".1"
+ camera_distance=".3">
+ <param_driver>
+ <driven
+ id="870" />
+ </param_driver>
+ </param>
+
+ <!--Lower eyebrows became a driver/driven param with new min value for backwards compatibility between 1.0 and 1.1-->
+ <param
+ id="757"
+ group="0"
+ name="Lower_Eyebrows"
+ label="Eyebrow Height"
+ show_simple="true"
+ wearable="hair"
+ edit_group="hair_eyebrows"
+ edit_group_order="2.5"
+ label_min="Higher"
+ label_max="Lower"
+ value_min="-4"
+ value_max="2"
+ value_default="-1"
+ camera_elevation=".1"
+ camera_distance=".3">
+ <param_driver>
+ <driven
+ id="871" />
+ </param_driver>
+ </param>
+
+ <!--Arced eyebrows became a driver/driven param with new max value for backwards compatibility between 1.0 and 1.1-->
+ <param
+ id="31"
+ group="0"
+ name="Arced_Eyebrows"
+ label="Eyebrow Arc"
+ wearable="hair"
+ edit_group="hair_eyebrows"
+ edit_group_order="3"
+ label_min="Flat"
+ label_max="Arced"
+ value_min="0"
+ value_max="2"
+ value_default=".5"
+ camera_elevation=".1"
+ camera_distance=".3">
+ <param_driver>
+ <driven
+ id="872" />
+ </param_driver>
+ </param>
+
+
+ <param
+ id="877"
+ group="3"
+ name="Jacket Wrinkles"
+ label="Jacket Wrinkles"
+ wearable="jacket"
+ edit_group="jacket"
+ edit_group_order="20"
+ label_min="No Wrinkles"
+ label_max="Wrinkles"
+ value_min="0"
+ value_max="1"
+ value_default="0"
+ camera_elevation=".1"
+ camera_distance=".3">
+ <param_driver>
+ <driven
+ id="875" />
+
+
+ <driven
+ id="876" />
+ </param_driver>
+ </param>
+
+ <param
+ id="1071"
+ group="2"
+ wearable="tattoo"
+ edit_group="colorpicker"
+ name="tattoo_red"
+ value_min="0"
+ value_max="1"
+ value_default="1">
+ <param_driver>
+ <driven
+ id="1062"
+ min1="0"
+ max1="1"
+ max2="1"
+ min2="1" />
+
+ <driven
+ id="1065"
+ min1="0"
+ max1="1"
+ max2="1"
+ min2="1" />
+
+ <driven
+ id="1068"
+ min1="0"
+ max1="1"
+ max2="1"
+ min2="1" />
+ </param_driver>
+ </param>
+
+ <param
+ id="1072"
+ group="2"
+ wearable="tattoo"
+ edit_group="colorpicker"
+ name="tattoo_green"
+ value_min="0"
+ value_max="1"
+ value_default="1">
+ <param_driver>
+ <driven
+ id="1063"
+ min1="0"
+ max1="1"
+ max2="1"
+ min2="1" />
+
+ <driven
+ id="1066"
+ min1="0"
+ max1="1"
+ max2="1"
+ min2="1" />
+
+ <driven
+ id="1069"
+ min1="0"
+ max1="1"
+ max2="1"
+ min2="1" />
+ </param_driver>
+ </param>
+
+ <param
+ id="1073"
+ group="2"
+ wearable="tattoo"
+ edit_group="colorpicker"
+ name="tattoo_blue"
+ value_min="0"
+ value_max="1"
+ value_default="1">
+ <param_driver>
+ <driven
+ id="1064"
+ min1="0"
+ max1="1"
+ max2="1"
+ min2="1" />
+
+ <driven
+ id="1067"
+ min1="0"
+ max1="1"
+ max2="1"
+ min2="1" />
+
+ <driven
+ id="1070"
+ min1="0"
+ max1="1"
+ max2="1"
+ min2="1" />
+
+ </param_driver>
+ </param>
+
+ <!-- ==PHYSICS PARAMETERS======================================= -->
+
+ <param
+ id="1100"
+ group="1"
+ sex="female"
+ wearable="physics"
+ name="Breast_Physics_UpDown_Controller"
+ label="Breast Physics UpDown Controller"
+ value_min="-1"
+ value_max="1"
+ value_default="0">
+ <param_driver>
+ <driven
+ id="1200" />
+ </param_driver>
+ </param>
+
+ <param
+ id="1101"
+ group="1"
+ sex="female"
+ wearable="physics"
+ name="Breast_Physics_InOut_Controller"
+ label="Breast Physics InOut Controller"
+ value_min="-1"
+ value_max="1"
+ value_default="0">
+ <param_driver>
+ <driven
+ id="1201" />
+ </param_driver>
+ </param>
+
+ <param
+ id="1102"
+ group="1"
+ wearable="physics"
+ name="Belly_Physics_UpDown_Controller"
+ label="Belly Physics UpDown Controller"
+ value_min="-1"
+ value_max="1"
+ value_default="0">
+ <param_driver>
+ <driven
+ id="1202" />
+ <driven
+ id="1203" />
+ <driven
+ id="1204" />
+ </param_driver>
+ </param>
+
+ <param
+ id="1103"
+ group="1"
+ wearable="shape"
+ name="Butt_Physics_UpDown_Controller"
+ label="Butt Physics UpDown Controller"
+ value_min="-1"
+ value_max="1"
+ value_default="0">
+ <param_driver>
+ <driven
+ id="1205" />
+ </param_driver>
+ </param>
+
+ <param
+ id="1104"
+ group="1"
+ wearable="shape"
+ name="Butt_Physics_LeftRight_Controller"
+ label="Butt Physics LeftRight Controller"
+ value_min="-1"
+ value_max="1"
+ value_default="0">
+ <param_driver>
+ <driven
+ id="1206" />
+ </param_driver>
+ </param>
+
+ <param
+ id="1105"
+ group="1"
+ wearable="shape"
+ name="Breast_Physics_LeftRight_Controller"
+ label="Breast Physics LeftRight Controller"
+ value_min="-1"
+ value_max="1"
+ value_default="0">
+ <param_driver>
+ <driven
+ id="1207" />
+ </param_driver>
+ </param>
+
+ <param
+ id="10000"
+ group="0"
+ sex="female"
+ name="Breast_Physics_Mass"
+ label="Breast Physics Mass"
+ wearable="physics"
+ edit_group="physics_advanced"
+ value_default=".1"
+ value_min=".1"
+ value_max="1">
+ <param_driver />
+ </param>
+ <param
+ id="10001"
+ group="0"
+ sex="female"
+ name="Breast_Physics_Gravity"
+ label="Breast Physics Gravity"
+ wearable="physics"
+ edit_group="physics_advanced"
+ value_default="0"
+ value_min="0"
+ value_max="30">
+ <param_driver />
+ </param>
+
+ <param
+ id="10002"
+ group="0"
+ sex="female"
+ name="Breast_Physics_Drag"
+ label="Breast Physics Drag"
+ wearable="physics"
+ edit_group="physics_advanced"
+ value_default="1"
+ value_min="0"
+ value_max="10">
+ <param_driver />
+ </param>
+
+ <param
+ id="10003"
+ group="0"
+ sex="female"
+ name="Breast_Physics_UpDown_Max_Effect"
+ label="Breast Physics UpDown Max Effect"
+ wearable="physics"
+ edit_group="physics_breasts_updown"
+ value_default="0"
+ value_min="0"
+ value_max="3">
+ <param_driver />
+ </param>
+ <param
+ id="10004"
+ group="0"
+ sex="female"
+ name="Breast_Physics_UpDown_Spring"
+ label="Breast Physics UpDown Spring"
+ wearable="physics"
+ edit_group="physics_breasts_updown"
+ value_default="10"
+ value_min="0"
+ value_max="100">
+ <param_driver />
+ </param>
+ <param
+ id="10005"
+ group="0"
+ sex="female"
+ name="Breast_Physics_UpDown_Gain"
+ label="Breast Physics UpDown Gain"
+ wearable="physics"
+ edit_group="physics_breasts_updown"
+ value_default="10"
+ value_min="1"
+ value_max="100">
+ <param_driver />
+ </param>
+ <param
+ id="10006"
+ group="0"
+ sex="female"
+ name="Breast_Physics_UpDown_Damping"
+ label="Breast Physics UpDown Damping"
+ wearable="physics"
+ edit_group="physics_breasts_updown"
+ value_default=".2"
+ value_min="0"
+ value_max="1">
+ <param_driver />
+ </param>
+
+ <param
+ id="10007"
+ group="0"
+ sex="female"
+ name="Breast_Physics_InOut_Max_Effect"
+ label="Breast Physics InOut Max Effect"
+ wearable="physics"
+ edit_group="physics_breasts_inout"
+ value_default="0"
+ value_min="0"
+ value_max="3">
+ <param_driver />
+ </param>
+ <param
+ id="10008"
+ group="0"
+ sex="female"
+ name="Breast_Physics_InOut_Spring"
+ label="Breast Physics InOut Spring"
+ wearable="physics"
+ edit_group="physics_breasts_inout"
+ value_default="10"
+ value_min="0"
+ value_max="100">
+ <param_driver />
+ </param>
+ <param
+ id="10009"
+ group="0"
+ sex="female"
+ name="Breast_Physics_InOut_Gain"
+ label="Breast Physics InOut Gain"
+ wearable="physics"
+ edit_group="physics_breasts_inout"
+ value_default="10"
+ value_min="1"
+ value_max="100">
+ <param_driver />
+ </param>
+ <param
+ id="10010"
+ group="0"
+ sex="female"
+ name="Breast_Physics_InOut_Damping"
+ label="Breast Physics InOut Damping"
+ wearable="physics"
+ edit_group="physics_breasts_inout"
+ value_default=".2"
+ value_min="0"
+ value_max="1">
+ <param_driver />
+ </param>
+
+ <param
+ id="10011"
+ group="0"
+ name="Belly_Physics_Mass"
+ label="Belly Physics Mass"
+ wearable="physics"
+ edit_group="physics_advanced"
+ value_default=".1"
+ value_min=".1"
+ value_max="1">
+ <param_driver />
+ </param>
+ <param
+ id="10012"
+ group="0"
+ name="Belly_Physics_Gravity"
+ label="Belly Physics Gravity"
+ wearable="physics"
+ edit_group="physics_advanced"
+ value_default="0"
+ value_min="0"
+ value_max="30">
+ <param_driver />
+ </param>
+ <param
+ id="10013"
+ group="0"
+ name="Belly_Physics_Drag"
+ label="Belly Physics Drag"
+ wearable="physics"
+ edit_group="physics_advanced"
+ value_default="1"
+ value_min="0"
+ value_max="10">
+ <param_driver />
+ </param>
+ <param
+ id="10014"
+ group="0"
+ name="Belly_Physics_UpDown_Max_Effect"
+ label="Belly Physics UpDown Max Effect"
+ wearable="physics"
+ edit_group="physics_belly_updown"
+ value_default="0"
+ value_min="0"
+ value_max="3">
+ <param_driver />
+ </param>
+ <param
+ id="10015"
+ group="0"
+ name="Belly_Physics_UpDown_Spring"
+ label="Belly Physics UpDown Spring"
+ wearable="physics"
+ edit_group="physics_belly_updown"
+ value_default="10"
+ value_min="0"
+ value_max="100">
+ <param_driver />
+ </param>
+ <param
+ id="10016"
+ group="0"
+ name="Belly_Physics_UpDown_Gain"
+ label="Belly Physics UpDown Gain"
+ wearable="physics"
+ edit_group="physics_belly_updown"
+ value_default="10"
+ value_min="1"
+ value_max="100">
+ <param_driver />
+ </param>
+ <param
+ id="10017"
+ group="0"
+ name="Belly_Physics_UpDown_Damping"
+ label="Belly Physics UpDown Damping"
+ wearable="physics"
+ edit_group="physics_belly_updown"
+ value_default=".2"
+ value_min="0"
+ value_max="1">
+ <param_driver />
+ </param>
+
+ <param
+ id="10018"
+ group="0"
+ name="Butt_Physics_Mass"
+ label="Butt Physics Mass"
+ wearable="physics"
+ edit_group="physics_advanced"
+ value_default=".1"
+ value_min=".1"
+ value_max="1">
+ <param_driver />
+ </param>
+ <param
+ id="10019"
+ group="0"
+ name="Butt_Physics_Gravity"
+ label="Butt Physics Gravity"
+ wearable="physics"
+ edit_group="physics_advanced"
+ value_default="0"
+ value_min="0"
+ value_max="30">
+ <param_driver />
+ </param>
+ <param
+ id="10020"
+ group="0"
+ name="Butt_Physics_Drag"
+ label="Butt Physics Drag"
+ wearable="physics"
+ edit_group="physics_advanced"
+ value_default="1"
+ value_min="0"
+ value_max="10">
+ <param_driver />
+ </param>
+
+ <param
+ id="10021"
+ group="0"
+ name="Butt_Physics_UpDown_Max_Effect"
+ label="Butt Physics UpDown Max Effect"
+ wearable="physics"
+ edit_group="physics_butt_updown"
+ value_default="0"
+ value_min="0"
+ value_max="3">
+ <param_driver />
+ </param>
+ <param
+ id="10022"
+ group="0"
+ name="Butt_Physics_UpDown_Spring"
+ label="Butt Physics UpDown Spring"
+ wearable="physics"
+ edit_group="physics_butt_updown"
+ value_default="10"
+ value_min="0"
+ value_max="100">
+ <param_driver />
+ </param>
+ <param
+ id="10023"
+ group="0"
+ name="Butt_Physics_UpDown_Gain"
+ label="Butt Physics UpDown Gain"
+ wearable="physics"
+ edit_group="physics_butt_updown"
+ value_default="10"
+ value_min="1"
+ value_max="100">
+ <param_driver />
+ </param>
+ <param
+ id="10024"
+ group="0"
+ name="Butt_Physics_UpDown_Damping"
+ label="Butt Physics UpDown Damping"
+ wearable="physics"
+ edit_group="physics_butt_updown"
+ value_default=".2"
+ value_min="0"
+ value_max="1">
+ <param_driver />
+ </param>
+
+ <param
+ id="10025"
+ group="0"
+ name="Butt_Physics_LeftRight_Max_Effect"
+ label="Butt Physics LeftRight Max Effect"
+ wearable="physics"
+ edit_group="physics_butt_leftright"
+ value_default="0"
+ value_min="0"
+ value_max="3">
+ <param_driver />
+ </param>
+ <param
+ id="10026"
+ group="0"
+ name="Butt_Physics_LeftRight_Spring"
+ label="Butt Physics LeftRight Spring"
+ wearable="physics"
+ edit_group="physics_butt_leftright"
+ value_default="10"
+ value_min="0"
+ value_max="100">
+ <param_driver />
+ </param>
+ <param
+ id="10027"
+ group="0"
+ name="Butt_Physics_LeftRight_Gain"
+ label="Butt Physics LeftRight Gain"
+ wearable="physics"
+ edit_group="physics_butt_leftright"
+ value_default="10"
+ value_min="1"
+ value_max="100">
+ <param_driver />
+ </param>
+ <param
+ id="10028"
+ group="0"
+ name="Butt_Physics_LeftRight_Damping"
+ label="Butt Physics LeftRight Damping"
+ wearable="physics"
+ edit_group="physics_butt_leftright"
+ value_default=".2"
+ value_min="0"
+ value_max="1">
+ <param_driver />
+ </param>
+
+ <param
+ id="10029"
+ group="0"
+ sex="female"
+ name="Breast_Physics_LeftRight_Max_Effect"
+ label="Breast Physics LeftRight Max Effect"
+ wearable="physics"
+ edit_group="physics_breasts_leftright"
+ value_default="0"
+ value_min="0"
+ value_max="3">
+ <param_driver />
+ </param>
+ <param
+ id="10030"
+ group="0"
+ sex="female"
+ name="Breast_Physics_LeftRight_Spring"
+ label="Breast Physics LeftRight Spring"
+ wearable="physics"
+ edit_group="physics_breasts_leftright"
+ value_default="10"
+ value_min="0"
+ value_max="100">
+ <param_driver />
+ </param>
+ <param
+ id="10031"
+ group="0"
+ sex="female"
+ name="Breast_Physics_LeftRight_Gain"
+ label="Breast Physics LeftRight Gain"
+ wearable="physics"
+ edit_group="physics_breasts_leftright"
+ value_default="10"
+ value_min="1"
+ value_max="100">
+ <param_driver />
+ </param>
+ <param
+ id="10032"
+ group="0"
+ sex="female"
+ name="Breast_Physics_LeftRight_Damping"
+ label="Breast Physics LeftRight Damping"
+ wearable="physics"
+ edit_group="physics_breasts_leftright"
+ value_default=".2"
+ value_min="0"
+ value_max="1">
+ <param_driver />
+ </param>
+
+ <param
+ id="11000"
+ group="0"
+ name="AppearanceMessage_Version"
+ label="AppearanceMessage Version"
+ value_default="0"
+ value_min="0"
+ value_max="255">
+ <param_driver />
+ </param>
+
+ </driver_parameters>
+
+ <morph_masks>
+ <mask
+ morph_name="Displace_Hair_Facial"
+ body_region="head"
+ layer="facialhair" />
+ <mask
+ morph_name="Displace_Loose_Upperbody"
+ body_region="upper_body"
+ layer="upper_clothes" />
+ <mask
+ morph_name="Shirtsleeve_flair"
+ body_region="upper_body"
+ layer="upper_clothes" />
+ <mask
+ morph_name="Displace_Loose_Lowerbody"
+ body_region="lower_body"
+ layer="lower_pants" />
+ <mask
+ morph_name="Leg_Pantflair"
+ body_region="lower_body"
+ layer="lower_pants" />
+ <mask
+ morph_name="Low_Crotch"
+ body_region="lower_body"
+ layer="lower_pants" />
+ <mask
+ morph_name="Leg_Longcuffs"
+ body_region="lower_body"
+ layer="lower_pants" />
+ </morph_masks>
+</linden_avatar>
+
diff --git a/indra/newview/character/avatar_skeleton.xml b/indra/newview/character/avatar_skeleton.xml
index 6b07bbc1d3..7a088484d8 100755
--- a/indra/newview/character/avatar_skeleton.xml
+++ b/indra/newview/character/avatar_skeleton.xml
@@ -1,6 +1,14 @@
<?xml version="1.0" encoding="US-ASCII" standalone="yes"?>
-<linden_skeleton version="1.0" num_bones="53" num_collision_volumes="26">
+<linden_skeleton version="1.0" num_bones="53" num_collision_volumes="29">
<bone name="mPelvis" pos="0.000 0.000 1.067" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="0.000000 0.000000 1.067015">
+ <bone name="mTail_1" pos="0.000 0.000 0.000" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="-0.25 0.000000 0.000000">
+ <bone name="mTail_2" pos="-0.2500 0.000 0.000" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="-.25000000 0.000000 0.000000">
+ <bone name="mTail_3" pos="-0.2500 0.000 0.000" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="-0.2500000 0.000000 0.000000">
+ <bone name="mTail_4" pos="-0.2500 0.000 0.000" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="-0.25000000 0.000000 0.000000">
+ </bone>
+ </bone>
+ </bone>
+ </bone>
<collision_volume name="PELVIS" pos = "-0.01 0 -0.02" rot="0.000000 8.00000 0.000000" scale="0.12 0.16 0.17"/>
<collision_volume name="BUTT" pos = "-0.06 0 -0.1" rot="0.000000 0.00000 0.000000" scale="0.1 0.1 0.1"/>
<bone name="mTorso" pos="0.000 0.000 0.084" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="0.000000 0.000000 0.084073">
@@ -9,6 +17,22 @@
<collision_volume name="LEFT_HANDLE" pos = "0.0 0.10 0.058" rot="0.000000 0.00000 0.000000" scale="0.05 0.05 0.05"/>
<collision_volume name="RIGHT_HANDLE" pos = "0.0 -0.10 0.058" rot="0.000000 0.00000 0.000000" scale="0.05 0.05 0.05"/>
<bone name="mChest" pos="-0.015 0.000 0.205" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="-0.015368 0.000000 0.204877">
+ <bone name="mRightWingShoulder" pos="-0.07 -0.082 0.165" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="-0.07 -0.082 0.165">
+ <bone name="mRightWingElbow" pos="-0.085 -0.115 0" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="-0.085 -0.115 0">
+ <bone name="mRightWingWrist" pos="0.000 -0.231 -0.000" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="0.000000 -.231 -0.000000">
+ <bone name="mRightWingTip" pos="0.000 -0.214 -0.000" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="0.000 -0.214 -0.000">
+ </bone>
+ </bone>
+ </bone>
+ </bone>
+ <bone name="mLeftWingShoulder" pos="-0.07 0.082 0.165" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="-0.07 0.082 0.165">
+ <bone name="mLeftWingElbow" pos="-0.085 0.115 0" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="-0.085 0.115 0">
+ <bone name="mLeftWingWrist" pos="0.000 0.231 -0.000" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="0.000000 0.231 -0.000000">
+ <bone name="mLeftWingTip" pos="0.000 0.214 -0.000" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="0.000 0.214 -0.000">
+ </bone>
+ </bone>
+ </bone>
+ </bone>
<collision_volume name="CHEST" pos = "0.028 0 0.07" rot="0.000000 -10.00000 0.000000" scale="0.11 0.15 0.2"/>
<collision_volume name="UPPER_BACK" pos = "0.0 0.0 0.017" rot="0.000000 0.00000 0.000000" scale="0.09 0.13 0.15"/>
<collision_volume name="LEFT_PEC" pos = "0.119 0.082 0.042" rot="0.000000 4.29000 0.000000" scale="0.05 0.05 0.05"/>
@@ -78,4 +102,4 @@
</bone>
</bone>
</bone>
-</linden_skeleton> \ No newline at end of file
+</linden_skeleton>
diff --git a/indra/newview/character/avatar_skeleton_orig.xml b/indra/newview/character/avatar_skeleton_orig.xml
new file mode 100644
index 0000000000..6b07bbc1d3
--- /dev/null
+++ b/indra/newview/character/avatar_skeleton_orig.xml
@@ -0,0 +1,81 @@
+<?xml version="1.0" encoding="US-ASCII" standalone="yes"?>
+<linden_skeleton version="1.0" num_bones="53" num_collision_volumes="26">
+<bone name="mPelvis" pos="0.000 0.000 1.067" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="0.000000 0.000000 1.067015">
+ <collision_volume name="PELVIS" pos = "-0.01 0 -0.02" rot="0.000000 8.00000 0.000000" scale="0.12 0.16 0.17"/>
+ <collision_volume name="BUTT" pos = "-0.06 0 -0.1" rot="0.000000 0.00000 0.000000" scale="0.1 0.1 0.1"/>
+ <bone name="mTorso" pos="0.000 0.000 0.084" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="0.000000 0.000000 0.084073">
+ <collision_volume name="BELLY" pos = "0.028 0 0.04" rot="0.000000 8.00000 0.000000" scale="0.09 0.13 0.15"/>
+ <collision_volume name="LOWER_BACK" pos = "0.0 0.0 0.023" rot="0.000000 0.00000 0.000000" scale="0.09 0.13 0.15"/>
+ <collision_volume name="LEFT_HANDLE" pos = "0.0 0.10 0.058" rot="0.000000 0.00000 0.000000" scale="0.05 0.05 0.05"/>
+ <collision_volume name="RIGHT_HANDLE" pos = "0.0 -0.10 0.058" rot="0.000000 0.00000 0.000000" scale="0.05 0.05 0.05"/>
+ <bone name="mChest" pos="-0.015 0.000 0.205" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="-0.015368 0.000000 0.204877">
+ <collision_volume name="CHEST" pos = "0.028 0 0.07" rot="0.000000 -10.00000 0.000000" scale="0.11 0.15 0.2"/>
+ <collision_volume name="UPPER_BACK" pos = "0.0 0.0 0.017" rot="0.000000 0.00000 0.000000" scale="0.09 0.13 0.15"/>
+ <collision_volume name="LEFT_PEC" pos = "0.119 0.082 0.042" rot="0.000000 4.29000 0.000000" scale="0.05 0.05 0.05"/>
+ <collision_volume name="RIGHT_PEC" pos = "0.119 -0.082 0.042" rot="0.000000 4.29000 0.000000" scale="0.05 0.05 0.05"/>
+ <bone name="mNeck" pos="-0.010 0.000 0.251" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="-0.009507 0.000000 0.251108">
+ <collision_volume name="NECK" pos = "0.0 0 0.02" rot="0.000000 0.000000 0.000000" scale="0.05 0.06 0.08"/>
+ <bone name="mHead" pos="0.000 -0.000 0.076" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="0.000000 -0.000000 0.075630">
+ <collision_volume name="HEAD" pos = "0.02 0 0.07" rot="0.000000 0.000000 0.000000" scale="0.11 0.09 0.12"/>
+ <bone name="mSkull" pos="0.000 0.000 0.079" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="0.000000 0.000000 0.079000">
+ </bone>
+ <bone name="mEyeRight" pos="0.098 -0.036 0.079" rot="0.000000 0.000000 -0.000000" scale="1.000 1.000 1.000" pivot="0.098466 -0.036000 0.079000">
+ </bone>
+ <bone name="mEyeLeft" pos="0.098 0.036 0.079" rot="0.000000 -0.000000 0.000000" scale="1.000 1.000 1.000" pivot="0.098461 0.036000 0.079000">
+ </bone>
+ </bone>
+ </bone>
+ <bone name="mCollarLeft" pos="-0.021 0.085 0.165" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="-0.020927 0.084665 0.165396">
+ <collision_volume name="L_CLAVICLE" pos = "0.02 0 0.02" rot="0.000000 0.00000 0.000000" scale="0.07 0.14 0.05"/>
+ <bone name="mShoulderLeft" pos="0.000 0.079 -0.000" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="0.000000 0.079000 -0.000000">
+ <collision_volume name="L_UPPER_ARM" pos = "0.0 0.12 0.01" rot="-5.000000 0.00000 0.000000" scale="0.05 0.17 0.05"/>
+ <bone name="mElbowLeft" pos="0.000 0.248 0.000" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="0.000000 0.248000 0.000000">
+ <collision_volume name="L_LOWER_ARM" pos = "0.0 0.1 0.0" rot="-3.000000 0.00000 0.000000" scale="0.04 0.14 0.04"/>
+ <bone name="mWristLeft" pos="-0.000 0.205 0.000" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="-0.000000 0.204846 0.000000">
+ <collision_volume name="L_HAND" pos = "0.01 0.05 0.0" rot="-3.000000 0.00000 -10.000000" scale="0.05 0.08 0.03"/>
+ </bone>
+ </bone>
+ </bone>
+ </bone>
+ <bone name="mCollarRight" pos="-0.021 -0.085 0.165" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="-0.020927 -0.085000 0.165396">
+ <collision_volume name="R_CLAVICLE" pos = "0.02 0 0.02" rot="0.000000 0.00000 0.000000" scale="0.07 0.14 0.05"/>
+ <bone name="mShoulderRight" pos="0.000 -0.079 -0.000" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="0.000000 -0.079418 -0.000000">
+ <collision_volume name="R_UPPER_ARM" pos = "0.0 -0.12 0.01" rot="5.000000 0.00000 0.000000" scale="0.05 0.17 0.05"/>
+ <bone name="mElbowRight" pos="0.000 -0.248 -0.000" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="0.000000 -0.248000 -0.000000">
+ <collision_volume name="R_LOWER_ARM" pos = "0.0 -0.1 0.0" rot="3.000000 0.00000 0.000000" scale="0.04 0.14 0.04"/>
+ <bone name="mWristRight" pos="0.000 -0.205 -0.000" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="-0.000000 -0.205000 -0.000000">
+ <collision_volume name="R_HAND" pos = "0.01 -0.05 0.0" rot="3.000000 0.00000 10.000000" scale="0.05 0.08 0.03"/>
+ </bone>
+ </bone>
+ </bone>
+ </bone>
+ </bone>
+ </bone>
+ <bone name="mHipRight" pos="0.034 -0.129 -0.041" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="0.033620 -0.128806 -0.041086">
+ <collision_volume name="R_UPPER_LEG" pos = "-0.02 0.05 -0.22" rot="0.000000 0.00000 0.000000" scale="0.09 0.09 0.32"/>
+ <bone name="mKneeRight" pos="-0.001 0.049 -0.491" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="-0.000780 0.048635 -0.490922">
+ <collision_volume name="R_LOWER_LEG" pos = "-0.02 0.0 -0.2" rot="0.000000 0.00000 0.000000" scale="0.06 0.06 0.25"/>
+ <bone name="mAnkleRight" pos="-0.029 0.000 -0.468" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="-0.028869 0.000000 -0.468494">
+ <collision_volume name="R_FOOT" pos = "0.077 0.0 -0.041" rot="0.000000 10.00000 0.000000" scale="0.13 0.05 0.05"/>
+ <bone name="mFootRight" pos="0.112 -0.000 -0.061" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="0.111956 -0.000000 -0.060637">
+ <bone name="mToeRight" pos="0.109 0.000 0.000" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="0.105399 -0.010408 -0.000104">
+ </bone>
+ </bone>
+ </bone>
+ </bone>
+ </bone>
+ <bone name="mHipLeft" pos="0.034 0.127 -0.041" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="0.033757 0.126765 -0.040998">
+ <collision_volume name="L_UPPER_LEG" pos = "-0.02 -0.05 -0.22" rot="0.000000 0.00000 0.000000" scale="0.09 0.09 0.32"/>
+ <bone name="mKneeLeft" pos="-0.001 -0.046 -0.491" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="-0.000887 -0.045568 -0.491053">
+ <collision_volume name="L_LOWER_LEG" pos = "-0.02 0.0 -0.2" rot="0.000000 0.00000 0.000000" scale="0.06 0.06 0.25"/>
+ <bone name="mAnkleLeft" pos="-0.029 0.001 -0.468" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="-0.028887 0.001378 -0.468449">
+ <collision_volume name="L_FOOT" pos = "0.077 0.0 -0.041" rot="0.000000 10.00000 0.000000" scale="0.13 0.05 0.05"/>
+ <bone name="mFootLeft" pos="0.112 -0.000 -0.061" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="0.111956 -0.000000 -0.060620">
+ <bone name="mToeLeft" pos="0.109 0.000 0.000" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="0.105387 0.008270 0.000871">
+ </bone>
+ </bone>
+ </bone>
+ </bone>
+ </bone>
+</bone>
+</linden_skeleton> \ No newline at end of file
diff --git a/indra/newview/character/avatar_skeleton_tentacles.xml b/indra/newview/character/avatar_skeleton_tentacles.xml
new file mode 100644
index 0000000000..9863a5cbfd
--- /dev/null
+++ b/indra/newview/character/avatar_skeleton_tentacles.xml
@@ -0,0 +1,281 @@
+<?xml version="1.0" encoding="US-ASCII" standalone="yes"?>
+<linden_skeleton version="1.0" num_bones="152" num_collision_volumes="26">
+ <bone name="mPelvis" pos="0.000 0.000 1.067" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="0.000000 0.000000 1.067015">
+ <collision_volume name="PELVIS" pos = "-0.01 0 -0.02" rot="0.000000 8.00000 0.000000" scale="0.12 0.16 0.17"/>
+ <collision_volume name="BUTT" pos = "-0.06 0 -0.1" rot="0.000000 0.00000 0.000000" scale="0.1 0.1 0.1"/>
+ <bone name="mTorso" pos="0.000 0.000 0.084" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="0.000000 0.000000 0.084073">
+ <collision_volume name="BELLY" pos = "0.028 0 0.04" rot="0.000000 8.00000 0.000000" scale="0.09 0.13 0.15"/>
+ <collision_volume name="LOWER_BACK" pos = "0.0 0.0 0.023" rot="0.000000 0.00000 0.000000" scale="0.09 0.13 0.15"/>
+ <collision_volume name="LEFT_HANDLE" pos = "0.0 0.10 0.058" rot="0.000000 0.00000 0.000000" scale="0.05 0.05 0.05"/>
+ <collision_volume name="RIGHT_HANDLE" pos = "0.0 -0.10 0.058" rot="0.000000 0.00000 0.000000" scale="0.05 0.05 0.05"/>
+ <bone name="mChest" pos="-0.015 0.000 0.205" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="-0.015368 0.000000 0.204877">
+ <collision_volume name="CHEST" pos = "0.028 0 0.07" rot="0.000000 -10.00000 0.000000" scale="0.11 0.15 0.2"/>
+ <collision_volume name="UPPER_BACK" pos = "0.0 0.0 0.017" rot="0.000000 0.00000 0.000000" scale="0.09 0.13 0.15"/>
+ <collision_volume name="LEFT_PEC" pos = "0.119 0.082 0.042" rot="0.000000 4.29000 0.000000" scale="0.05 0.05 0.05"/>
+ <collision_volume name="RIGHT_PEC" pos = "0.119 -0.082 0.042" rot="0.000000 4.29000 0.000000" scale="0.05 0.05 0.05"/>
+ <bone name="mNeck" pos="-0.010 0.000 0.251" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="-0.009507 0.000000 0.251108">
+ <collision_volume name="NECK" pos = "0.0 0 0.02" rot="0.000000 0.000000 0.000000" scale="0.05 0.06 0.08"/>
+ <bone name="mHead" pos="0.000 -0.000 0.076" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="0.000000 -0.000000 0.075630">
+ <collision_volume name="HEAD" pos = "0.02 0 0.07" rot="0.000000 0.000000 0.000000" scale="0.11 0.09 0.12"/>
+ <bone name="mSkull" pos="0.000 0.000 0.079" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="0.000000 0.000000 0.079000">
+ </bone>
+ <bone name="mEyeRight" pos="0.098 -0.036 0.079" rot="0.000000 0.000000 -0.000000" scale="1.000 1.000 1.000" pivot="0.098466 -0.036000 0.079000">
+ </bone>
+ <bone name="mEyeLeft" pos="0.098 0.036 0.079" rot="0.000000 -0.000000 0.000000" scale="1.000 1.000 1.000" pivot="0.098461 0.036000 0.079000">
+ </bone>
+ </bone>
+ </bone>
+ <bone name="mCollarLeft" pos="-0.021 0.085 0.165" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="-0.020927 0.084665 0.165396">
+ <collision_volume name="L_CLAVICLE" pos = "0.02 0 0.02" rot="0.000000 0.00000 0.000000" scale="0.07 0.14 0.05"/>
+ <bone name="mShoulderLeft" pos="0.000 0.079 -0.000" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="0.000000 0.079000 -0.000000">
+ <collision_volume name="L_UPPER_ARM" pos = "0.0 0.12 0.01" rot="-5.000000 0.00000 0.000000" scale="0.05 0.17 0.05"/>
+ <bone name="mElbowLeft" pos="0.000 0.248 0.000" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="0.000000 0.248000 0.000000">
+ <collision_volume name="L_LOWER_ARM" pos = "0.0 0.1 0.0" rot="-3.000000 0.00000 0.000000" scale="0.04 0.14 0.04"/>
+ <bone name="mWristLeft" pos="-0.000 0.205 0.000" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="-0.000000 0.204846 0.000000">
+ <collision_volume name="L_HAND" pos = "0.01 0.05 0.0" rot="-3.000000 0.00000 -10.000000" scale="0.05 0.08 0.03"/>
+ </bone>
+ </bone>
+ </bone>
+ </bone>
+ <bone name="mCollarRight" pos="-0.021 -0.085 0.165" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="-0.020927 -0.085000 0.165396">
+ <collision_volume name="R_CLAVICLE" pos = "0.02 0 0.02" rot="0.000000 0.00000 0.000000" scale="0.07 0.14 0.05"/>
+ <bone name="mShoulderRight" pos="0.000 -0.079 -0.000" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="0.000000 -0.079418 -0.000000">
+ <collision_volume name="R_UPPER_ARM" pos = "0.0 -0.12 0.01" rot="5.000000 0.00000 0.000000" scale="0.05 0.17 0.05"/>
+ <bone name="mElbowRight" pos="0.000 -0.248 -0.000" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="0.000000 -0.248000 -0.000000">
+ <collision_volume name="R_LOWER_ARM" pos = "0.0 -0.1 0.0" rot="3.000000 0.00000 0.000000" scale="0.04 0.14 0.04"/>
+ <bone name="mWristRight" pos="0.000 -0.205 -0.000" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="-0.000000 -0.205000 -0.000000">
+ <collision_volume name="R_HAND" pos = "0.01 -0.05 0.0" rot="3.000000 0.00000 10.000000" scale="0.05 0.08 0.03"/>
+ </bone>
+ </bone>
+ </bone>
+ </bone>
+ <bone name="mTentacle0_0" pos="0.0 0.0 0.0" rot="0.0 0.0 0.000000" scale="1.0 1.0 1.0" pivot="0.0 0.0 0.0">
+ <bone name="mTentacle0_1" pos="0.100000 0.0 0.0" rot="0.0 0.0 0.0" scale="1.0 1.0 1.0" pivot="0.1 0.0 0.0">
+ <bone name="mTentacle0_2" pos="0.100000 0.0 0.0" rot="0.0 0.0 0.0" scale="1.0 1.0 1.0" pivot="0.1 0.0 0.0">
+ <bone name="mTentacle0_3" pos="0.100000 0.0 0.0" rot="0.0 0.0 0.0" scale="1.0 1.0 1.0" pivot="0.1 0.0 0.0">
+ <bone name="mTentacle0_4" pos="0.100000 0.0 0.0" rot="0.0 0.0 0.0" scale="1.0 1.0 1.0" pivot="0.1 0.0 0.0">
+ <bone name="mTentacle0_5" pos="0.100000 0.0 0.0" rot="0.0 0.0 0.0" scale="1.0 1.0 1.0" pivot="0.1 0.0 0.0">
+ <bone name="mTentacle0_6" pos="0.100000 0.0 0.0" rot="0.0 0.0 0.0" scale="1.0 1.0 1.0" pivot="0.1 0.0 0.0">
+ <bone name="mTentacle0_7" pos="0.100000 0.0 0.0" rot="0.0 0.0 0.0" scale="1.0 1.0 1.0" pivot="0.1 0.0 0.0">
+ <bone name="mTentacle0_8" pos="0.100000 0.0 0.0" rot="0.0 0.0 0.0" scale="1.0 1.0 1.0" pivot="0.1 0.0 0.0">
+ <bone name="mTentacle0_9" pos="0.100000 0.0 0.0" rot="0.0 0.0 0.0" scale="1.0 1.0 1.0" pivot="0.1 0.0 0.0">
+ </bone>
+ </bone>
+ </bone>
+ </bone>
+ </bone>
+ </bone>
+ </bone>
+ </bone>
+ </bone>
+ </bone>
+ <bone name="mTentacle1_0" pos="0.0 0.0 0.0" rot="0.0 0.0 36.000000" scale="1.0 1.0 1.0" pivot="0.0 0.0 0.0">
+ <bone name="mTentacle1_1" pos="0.100000 0.0 0.0" rot="0.0 0.0 0.0" scale="1.0 1.0 1.0" pivot="0.1 0.0 0.0">
+ <bone name="mTentacle1_2" pos="0.100000 0.0 0.0" rot="0.0 0.0 0.0" scale="1.0 1.0 1.0" pivot="0.1 0.0 0.0">
+ <bone name="mTentacle1_3" pos="0.100000 0.0 0.0" rot="0.0 0.0 0.0" scale="1.0 1.0 1.0" pivot="0.1 0.0 0.0">
+ <bone name="mTentacle1_4" pos="0.100000 0.0 0.0" rot="0.0 0.0 0.0" scale="1.0 1.0 1.0" pivot="0.1 0.0 0.0">
+ <bone name="mTentacle1_5" pos="0.100000 0.0 0.0" rot="0.0 0.0 0.0" scale="1.0 1.0 1.0" pivot="0.1 0.0 0.0">
+ <bone name="mTentacle1_6" pos="0.100000 0.0 0.0" rot="0.0 0.0 0.0" scale="1.0 1.0 1.0" pivot="0.1 0.0 0.0">
+ <bone name="mTentacle1_7" pos="0.100000 0.0 0.0" rot="0.0 0.0 0.0" scale="1.0 1.0 1.0" pivot="0.1 0.0 0.0">
+ <bone name="mTentacle1_8" pos="0.100000 0.0 0.0" rot="0.0 0.0 0.0" scale="1.0 1.0 1.0" pivot="0.1 0.0 0.0">
+ <bone name="mTentacle1_9" pos="0.100000 0.0 0.0" rot="0.0 0.0 0.0" scale="1.0 1.0 1.0" pivot="0.1 0.0 0.0">
+ </bone>
+ </bone>
+ </bone>
+ </bone>
+ </bone>
+ </bone>
+ </bone>
+ </bone>
+ </bone>
+ </bone>
+ <bone name="mTentacle2_0" pos="0.0 0.0 0.0" rot="0.0 0.0 72.000000" scale="1.0 1.0 1.0" pivot="0.0 0.0 0.0">
+ <bone name="mTentacle2_1" pos="0.100000 0.0 0.0" rot="0.0 0.0 0.0" scale="1.0 1.0 1.0" pivot="0.1 0.0 0.0">
+ <bone name="mTentacle2_2" pos="0.100000 0.0 0.0" rot="0.0 0.0 0.0" scale="1.0 1.0 1.0" pivot="0.1 0.0 0.0">
+ <bone name="mTentacle2_3" pos="0.100000 0.0 0.0" rot="0.0 0.0 0.0" scale="1.0 1.0 1.0" pivot="0.1 0.0 0.0">
+ <bone name="mTentacle2_4" pos="0.100000 0.0 0.0" rot="0.0 0.0 0.0" scale="1.0 1.0 1.0" pivot="0.1 0.0 0.0">
+ <bone name="mTentacle2_5" pos="0.100000 0.0 0.0" rot="0.0 0.0 0.0" scale="1.0 1.0 1.0" pivot="0.1 0.0 0.0">
+ <bone name="mTentacle2_6" pos="0.100000 0.0 0.0" rot="0.0 0.0 0.0" scale="1.0 1.0 1.0" pivot="0.1 0.0 0.0">
+ <bone name="mTentacle2_7" pos="0.100000 0.0 0.0" rot="0.0 0.0 0.0" scale="1.0 1.0 1.0" pivot="0.1 0.0 0.0">
+ <bone name="mTentacle2_8" pos="0.100000 0.0 0.0" rot="0.0 0.0 0.0" scale="1.0 1.0 1.0" pivot="0.1 0.0 0.0">
+ <bone name="mTentacle2_9" pos="0.100000 0.0 0.0" rot="0.0 0.0 0.0" scale="1.0 1.0 1.0" pivot="0.1 0.0 0.0">
+ </bone>
+ </bone>
+ </bone>
+ </bone>
+ </bone>
+ </bone>
+ </bone>
+ </bone>
+ </bone>
+ </bone>
+ <bone name="mTentacle3_0" pos="0.0 0.0 0.0" rot="0.0 0.0 108.000000" scale="1.0 1.0 1.0" pivot="0.0 0.0 0.0">
+ <bone name="mTentacle3_1" pos="0.100000 0.0 0.0" rot="0.0 0.0 0.0" scale="1.0 1.0 1.0" pivot="0.1 0.0 0.0">
+ <bone name="mTentacle3_2" pos="0.100000 0.0 0.0" rot="0.0 0.0 0.0" scale="1.0 1.0 1.0" pivot="0.1 0.0 0.0">
+ <bone name="mTentacle3_3" pos="0.100000 0.0 0.0" rot="0.0 0.0 0.0" scale="1.0 1.0 1.0" pivot="0.1 0.0 0.0">
+ <bone name="mTentacle3_4" pos="0.100000 0.0 0.0" rot="0.0 0.0 0.0" scale="1.0 1.0 1.0" pivot="0.1 0.0 0.0">
+ <bone name="mTentacle3_5" pos="0.100000 0.0 0.0" rot="0.0 0.0 0.0" scale="1.0 1.0 1.0" pivot="0.1 0.0 0.0">
+ <bone name="mTentacle3_6" pos="0.100000 0.0 0.0" rot="0.0 0.0 0.0" scale="1.0 1.0 1.0" pivot="0.1 0.0 0.0">
+ <bone name="mTentacle3_7" pos="0.100000 0.0 0.0" rot="0.0 0.0 0.0" scale="1.0 1.0 1.0" pivot="0.1 0.0 0.0">
+ <bone name="mTentacle3_8" pos="0.100000 0.0 0.0" rot="0.0 0.0 0.0" scale="1.0 1.0 1.0" pivot="0.1 0.0 0.0">
+ <bone name="mTentacle3_9" pos="0.100000 0.0 0.0" rot="0.0 0.0 0.0" scale="1.0 1.0 1.0" pivot="0.1 0.0 0.0">
+ </bone>
+ </bone>
+ </bone>
+ </bone>
+ </bone>
+ </bone>
+ </bone>
+ </bone>
+ </bone>
+ </bone>
+ <bone name="mTentacle4_0" pos="0.0 0.0 0.0" rot="0.0 0.0 144.000000" scale="1.0 1.0 1.0" pivot="0.0 0.0 0.0">
+ <bone name="mTentacle4_1" pos="0.100000 0.0 0.0" rot="0.0 0.0 0.0" scale="1.0 1.0 1.0" pivot="0.1 0.0 0.0">
+ <bone name="mTentacle4_2" pos="0.100000 0.0 0.0" rot="0.0 0.0 0.0" scale="1.0 1.0 1.0" pivot="0.1 0.0 0.0">
+ <bone name="mTentacle4_3" pos="0.100000 0.0 0.0" rot="0.0 0.0 0.0" scale="1.0 1.0 1.0" pivot="0.1 0.0 0.0">
+ <bone name="mTentacle4_4" pos="0.100000 0.0 0.0" rot="0.0 0.0 0.0" scale="1.0 1.0 1.0" pivot="0.1 0.0 0.0">
+ <bone name="mTentacle4_5" pos="0.100000 0.0 0.0" rot="0.0 0.0 0.0" scale="1.0 1.0 1.0" pivot="0.1 0.0 0.0">
+ <bone name="mTentacle4_6" pos="0.100000 0.0 0.0" rot="0.0 0.0 0.0" scale="1.0 1.0 1.0" pivot="0.1 0.0 0.0">
+ <bone name="mTentacle4_7" pos="0.100000 0.0 0.0" rot="0.0 0.0 0.0" scale="1.0 1.0 1.0" pivot="0.1 0.0 0.0">
+ <bone name="mTentacle4_8" pos="0.100000 0.0 0.0" rot="0.0 0.0 0.0" scale="1.0 1.0 1.0" pivot="0.1 0.0 0.0">
+ <bone name="mTentacle4_9" pos="0.100000 0.0 0.0" rot="0.0 0.0 0.0" scale="1.0 1.0 1.0" pivot="0.1 0.0 0.0">
+ </bone>
+ </bone>
+ </bone>
+ </bone>
+ </bone>
+ </bone>
+ </bone>
+ </bone>
+ </bone>
+ </bone>
+ <bone name="mTentacle5_0" pos="0.0 0.0 0.0" rot="0.0 0.0 180.000000" scale="1.0 1.0 1.0" pivot="0.0 0.0 0.0">
+ <bone name="mTentacle5_1" pos="0.100000 0.0 0.0" rot="0.0 0.0 0.0" scale="1.0 1.0 1.0" pivot="0.1 0.0 0.0">
+ <bone name="mTentacle5_2" pos="0.100000 0.0 0.0" rot="0.0 0.0 0.0" scale="1.0 1.0 1.0" pivot="0.1 0.0 0.0">
+ <bone name="mTentacle5_3" pos="0.100000 0.0 0.0" rot="0.0 0.0 0.0" scale="1.0 1.0 1.0" pivot="0.1 0.0 0.0">
+ <bone name="mTentacle5_4" pos="0.100000 0.0 0.0" rot="0.0 0.0 0.0" scale="1.0 1.0 1.0" pivot="0.1 0.0 0.0">
+ <bone name="mTentacle5_5" pos="0.100000 0.0 0.0" rot="0.0 0.0 0.0" scale="1.0 1.0 1.0" pivot="0.1 0.0 0.0">
+ <bone name="mTentacle5_6" pos="0.100000 0.0 0.0" rot="0.0 0.0 0.0" scale="1.0 1.0 1.0" pivot="0.1 0.0 0.0">
+ <bone name="mTentacle5_7" pos="0.100000 0.0 0.0" rot="0.0 0.0 0.0" scale="1.0 1.0 1.0" pivot="0.1 0.0 0.0">
+ <bone name="mTentacle5_8" pos="0.100000 0.0 0.0" rot="0.0 0.0 0.0" scale="1.0 1.0 1.0" pivot="0.1 0.0 0.0">
+ <bone name="mTentacle5_9" pos="0.100000 0.0 0.0" rot="0.0 0.0 0.0" scale="1.0 1.0 1.0" pivot="0.1 0.0 0.0">
+ </bone>
+ </bone>
+ </bone>
+ </bone>
+ </bone>
+ </bone>
+ </bone>
+ </bone>
+ </bone>
+ </bone>
+ <bone name="mTentacle6_0" pos="0.0 0.0 0.0" rot="0.0 0.0 216.000000" scale="1.0 1.0 1.0" pivot="0.0 0.0 0.0">
+ <bone name="mTentacle6_1" pos="0.100000 0.0 0.0" rot="0.0 0.0 0.0" scale="1.0 1.0 1.0" pivot="0.1 0.0 0.0">
+ <bone name="mTentacle6_2" pos="0.100000 0.0 0.0" rot="0.0 0.0 0.0" scale="1.0 1.0 1.0" pivot="0.1 0.0 0.0">
+ <bone name="mTentacle6_3" pos="0.100000 0.0 0.0" rot="0.0 0.0 0.0" scale="1.0 1.0 1.0" pivot="0.1 0.0 0.0">
+ <bone name="mTentacle6_4" pos="0.100000 0.0 0.0" rot="0.0 0.0 0.0" scale="1.0 1.0 1.0" pivot="0.1 0.0 0.0">
+ <bone name="mTentacle6_5" pos="0.100000 0.0 0.0" rot="0.0 0.0 0.0" scale="1.0 1.0 1.0" pivot="0.1 0.0 0.0">
+ <bone name="mTentacle6_6" pos="0.100000 0.0 0.0" rot="0.0 0.0 0.0" scale="1.0 1.0 1.0" pivot="0.1 0.0 0.0">
+ <bone name="mTentacle6_7" pos="0.100000 0.0 0.0" rot="0.0 0.0 0.0" scale="1.0 1.0 1.0" pivot="0.1 0.0 0.0">
+ <bone name="mTentacle6_8" pos="0.100000 0.0 0.0" rot="0.0 0.0 0.0" scale="1.0 1.0 1.0" pivot="0.1 0.0 0.0">
+ <bone name="mTentacle6_9" pos="0.100000 0.0 0.0" rot="0.0 0.0 0.0" scale="1.0 1.0 1.0" pivot="0.1 0.0 0.0">
+ </bone>
+ </bone>
+ </bone>
+ </bone>
+ </bone>
+ </bone>
+ </bone>
+ </bone>
+ </bone>
+ </bone>
+ <bone name="mTentacle7_0" pos="0.0 0.0 0.0" rot="0.0 0.0 252.000000" scale="1.0 1.0 1.0" pivot="0.0 0.0 0.0">
+ <bone name="mTentacle7_1" pos="0.100000 0.0 0.0" rot="0.0 0.0 0.0" scale="1.0 1.0 1.0" pivot="0.1 0.0 0.0">
+ <bone name="mTentacle7_2" pos="0.100000 0.0 0.0" rot="0.0 0.0 0.0" scale="1.0 1.0 1.0" pivot="0.1 0.0 0.0">
+ <bone name="mTentacle7_3" pos="0.100000 0.0 0.0" rot="0.0 0.0 0.0" scale="1.0 1.0 1.0" pivot="0.1 0.0 0.0">
+ <bone name="mTentacle7_4" pos="0.100000 0.0 0.0" rot="0.0 0.0 0.0" scale="1.0 1.0 1.0" pivot="0.1 0.0 0.0">
+ <bone name="mTentacle7_5" pos="0.100000 0.0 0.0" rot="0.0 0.0 0.0" scale="1.0 1.0 1.0" pivot="0.1 0.0 0.0">
+ <bone name="mTentacle7_6" pos="0.100000 0.0 0.0" rot="0.0 0.0 0.0" scale="1.0 1.0 1.0" pivot="0.1 0.0 0.0">
+ <bone name="mTentacle7_7" pos="0.100000 0.0 0.0" rot="0.0 0.0 0.0" scale="1.0 1.0 1.0" pivot="0.1 0.0 0.0">
+ <bone name="mTentacle7_8" pos="0.100000 0.0 0.0" rot="0.0 0.0 0.0" scale="1.0 1.0 1.0" pivot="0.1 0.0 0.0">
+ <bone name="mTentacle7_9" pos="0.100000 0.0 0.0" rot="0.0 0.0 0.0" scale="1.0 1.0 1.0" pivot="0.1 0.0 0.0">
+ </bone>
+ </bone>
+ </bone>
+ </bone>
+ </bone>
+ </bone>
+ </bone>
+ </bone>
+ </bone>
+ </bone>
+ <bone name="mTentacle8_0" pos="0.0 0.0 0.0" rot="0.0 0.0 288.000000" scale="1.0 1.0 1.0" pivot="0.0 0.0 0.0">
+ <bone name="mTentacle8_1" pos="0.100000 0.0 0.0" rot="0.0 0.0 0.0" scale="1.0 1.0 1.0" pivot="0.1 0.0 0.0">
+ <bone name="mTentacle8_2" pos="0.100000 0.0 0.0" rot="0.0 0.0 0.0" scale="1.0 1.0 1.0" pivot="0.1 0.0 0.0">
+ <bone name="mTentacle8_3" pos="0.100000 0.0 0.0" rot="0.0 0.0 0.0" scale="1.0 1.0 1.0" pivot="0.1 0.0 0.0">
+ <bone name="mTentacle8_4" pos="0.100000 0.0 0.0" rot="0.0 0.0 0.0" scale="1.0 1.0 1.0" pivot="0.1 0.0 0.0">
+ <bone name="mTentacle8_5" pos="0.100000 0.0 0.0" rot="0.0 0.0 0.0" scale="1.0 1.0 1.0" pivot="0.1 0.0 0.0">
+ <bone name="mTentacle8_6" pos="0.100000 0.0 0.0" rot="0.0 0.0 0.0" scale="1.0 1.0 1.0" pivot="0.1 0.0 0.0">
+ <bone name="mTentacle8_7" pos="0.100000 0.0 0.0" rot="0.0 0.0 0.0" scale="1.0 1.0 1.0" pivot="0.1 0.0 0.0">
+ <bone name="mTentacle8_8" pos="0.100000 0.0 0.0" rot="0.0 0.0 0.0" scale="1.0 1.0 1.0" pivot="0.1 0.0 0.0">
+ <bone name="mTentacle8_9" pos="0.100000 0.0 0.0" rot="0.0 0.0 0.0" scale="1.0 1.0 1.0" pivot="0.1 0.0 0.0">
+ </bone>
+ </bone>
+ </bone>
+ </bone>
+ </bone>
+ </bone>
+ </bone>
+ </bone>
+ </bone>
+ </bone>
+ <bone name="mTentacle9_0" pos="0.0 0.0 0.0" rot="0.0 0.0 324.000000" scale="1.0 1.0 1.0" pivot="0.0 0.0 0.0">
+ <bone name="mTentacle9_1" pos="0.100000 0.0 0.0" rot="0.0 0.0 0.0" scale="1.0 1.0 1.0" pivot="0.1 0.0 0.0">
+ <bone name="mTentacle9_2" pos="0.100000 0.0 0.0" rot="0.0 0.0 0.0" scale="1.0 1.0 1.0" pivot="0.1 0.0 0.0">
+ <bone name="mTentacle9_3" pos="0.100000 0.0 0.0" rot="0.0 0.0 0.0" scale="1.0 1.0 1.0" pivot="0.1 0.0 0.0">
+ <bone name="mTentacle9_4" pos="0.100000 0.0 0.0" rot="0.0 0.0 0.0" scale="1.0 1.0 1.0" pivot="0.1 0.0 0.0">
+ <bone name="mTentacle9_5" pos="0.100000 0.0 0.0" rot="0.0 0.0 0.0" scale="1.0 1.0 1.0" pivot="0.1 0.0 0.0">
+ <bone name="mTentacle9_6" pos="0.100000 0.0 0.0" rot="0.0 0.0 0.0" scale="1.0 1.0 1.0" pivot="0.1 0.0 0.0">
+ <bone name="mTentacle9_7" pos="0.100000 0.0 0.0" rot="0.0 0.0 0.0" scale="1.0 1.0 1.0" pivot="0.1 0.0 0.0">
+ <bone name="mTentacle9_8" pos="0.100000 0.0 0.0" rot="0.0 0.0 0.0" scale="1.0 1.0 1.0" pivot="0.1 0.0 0.0">
+ <bone name="mTentacle9_9" pos="0.100000 0.0 0.0" rot="0.0 0.0 0.0" scale="1.0 1.0 1.0" pivot="0.1 0.0 0.0">
+ </bone>
+ </bone>
+ </bone>
+ </bone>
+ </bone>
+ </bone>
+ </bone>
+ </bone>
+ </bone>
+ </bone>
+ </bone>
+ </bone>
+ <bone name="mHipRight" pos="0.034 -0.129 -0.041" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="0.033620 -0.128806 -0.041086">
+ <collision_volume name="R_UPPER_LEG" pos = "-0.02 0.05 -0.22" rot="0.000000 0.00000 0.000000" scale="0.09 0.09 0.32"/>
+ <bone name="mKneeRight" pos="-0.001 0.049 -0.491" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="-0.000780 0.048635 -0.490922">
+ <collision_volume name="R_LOWER_LEG" pos = "-0.02 0.0 -0.2" rot="0.000000 0.00000 0.000000" scale="0.06 0.06 0.25"/>
+ <bone name="mAnkleRight" pos="-0.029 0.000 -0.468" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="-0.028869 0.000000 -0.468494">
+ <collision_volume name="R_FOOT" pos = "0.077 0.0 -0.041" rot="0.000000 10.00000 0.000000" scale="0.13 0.05 0.05"/>
+ <bone name="mFootRight" pos="0.112 -0.000 -0.061" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="0.111956 -0.000000 -0.060637">
+ <bone name="mToeRight" pos="0.109 0.000 0.000" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="0.105399 -0.010408 -0.000104">
+ </bone>
+ </bone>
+ </bone>
+ </bone>
+ </bone>
+ <bone name="mHipLeft" pos="0.034 0.127 -0.041" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="0.033757 0.126765 -0.040998">
+ <collision_volume name="L_UPPER_LEG" pos = "-0.02 -0.05 -0.22" rot="0.000000 0.00000 0.000000" scale="0.09 0.09 0.32"/>
+ <bone name="mKneeLeft" pos="-0.001 -0.046 -0.491" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="-0.000887 -0.045568 -0.491053">
+ <collision_volume name="L_LOWER_LEG" pos = "-0.02 0.0 -0.2" rot="0.000000 0.00000 0.000000" scale="0.06 0.06 0.25"/>
+ <bone name="mAnkleLeft" pos="-0.029 0.001 -0.468" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="-0.028887 0.001378 -0.468449">
+ <collision_volume name="L_FOOT" pos = "0.077 0.0 -0.041" rot="0.000000 10.00000 0.000000" scale="0.13 0.05 0.05"/>
+ <bone name="mFootLeft" pos="0.112 -0.000 -0.061" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="0.111956 -0.000000 -0.060620">
+ <bone name="mToeLeft" pos="0.109 0.000 0.000" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="0.105387 0.008270 0.000871">
+ </bone>
+ </bone>
+ </bone>
+ </bone>
+ </bone>
+ </bone>
+</linden_skeleton>
diff --git a/indra/newview/character/avatar_skeleton_wings_tail.xml b/indra/newview/character/avatar_skeleton_wings_tail.xml
new file mode 100644
index 0000000000..7a088484d8
--- /dev/null
+++ b/indra/newview/character/avatar_skeleton_wings_tail.xml
@@ -0,0 +1,105 @@
+<?xml version="1.0" encoding="US-ASCII" standalone="yes"?>
+<linden_skeleton version="1.0" num_bones="53" num_collision_volumes="29">
+<bone name="mPelvis" pos="0.000 0.000 1.067" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="0.000000 0.000000 1.067015">
+ <bone name="mTail_1" pos="0.000 0.000 0.000" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="-0.25 0.000000 0.000000">
+ <bone name="mTail_2" pos="-0.2500 0.000 0.000" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="-.25000000 0.000000 0.000000">
+ <bone name="mTail_3" pos="-0.2500 0.000 0.000" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="-0.2500000 0.000000 0.000000">
+ <bone name="mTail_4" pos="-0.2500 0.000 0.000" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="-0.25000000 0.000000 0.000000">
+ </bone>
+ </bone>
+ </bone>
+ </bone>
+ <collision_volume name="PELVIS" pos = "-0.01 0 -0.02" rot="0.000000 8.00000 0.000000" scale="0.12 0.16 0.17"/>
+ <collision_volume name="BUTT" pos = "-0.06 0 -0.1" rot="0.000000 0.00000 0.000000" scale="0.1 0.1 0.1"/>
+ <bone name="mTorso" pos="0.000 0.000 0.084" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="0.000000 0.000000 0.084073">
+ <collision_volume name="BELLY" pos = "0.028 0 0.04" rot="0.000000 8.00000 0.000000" scale="0.09 0.13 0.15"/>
+ <collision_volume name="LOWER_BACK" pos = "0.0 0.0 0.023" rot="0.000000 0.00000 0.000000" scale="0.09 0.13 0.15"/>
+ <collision_volume name="LEFT_HANDLE" pos = "0.0 0.10 0.058" rot="0.000000 0.00000 0.000000" scale="0.05 0.05 0.05"/>
+ <collision_volume name="RIGHT_HANDLE" pos = "0.0 -0.10 0.058" rot="0.000000 0.00000 0.000000" scale="0.05 0.05 0.05"/>
+ <bone name="mChest" pos="-0.015 0.000 0.205" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="-0.015368 0.000000 0.204877">
+ <bone name="mRightWingShoulder" pos="-0.07 -0.082 0.165" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="-0.07 -0.082 0.165">
+ <bone name="mRightWingElbow" pos="-0.085 -0.115 0" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="-0.085 -0.115 0">
+ <bone name="mRightWingWrist" pos="0.000 -0.231 -0.000" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="0.000000 -.231 -0.000000">
+ <bone name="mRightWingTip" pos="0.000 -0.214 -0.000" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="0.000 -0.214 -0.000">
+ </bone>
+ </bone>
+ </bone>
+ </bone>
+ <bone name="mLeftWingShoulder" pos="-0.07 0.082 0.165" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="-0.07 0.082 0.165">
+ <bone name="mLeftWingElbow" pos="-0.085 0.115 0" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="-0.085 0.115 0">
+ <bone name="mLeftWingWrist" pos="0.000 0.231 -0.000" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="0.000000 0.231 -0.000000">
+ <bone name="mLeftWingTip" pos="0.000 0.214 -0.000" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="0.000 0.214 -0.000">
+ </bone>
+ </bone>
+ </bone>
+ </bone>
+ <collision_volume name="CHEST" pos = "0.028 0 0.07" rot="0.000000 -10.00000 0.000000" scale="0.11 0.15 0.2"/>
+ <collision_volume name="UPPER_BACK" pos = "0.0 0.0 0.017" rot="0.000000 0.00000 0.000000" scale="0.09 0.13 0.15"/>
+ <collision_volume name="LEFT_PEC" pos = "0.119 0.082 0.042" rot="0.000000 4.29000 0.000000" scale="0.05 0.05 0.05"/>
+ <collision_volume name="RIGHT_PEC" pos = "0.119 -0.082 0.042" rot="0.000000 4.29000 0.000000" scale="0.05 0.05 0.05"/>
+ <bone name="mNeck" pos="-0.010 0.000 0.251" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="-0.009507 0.000000 0.251108">
+ <collision_volume name="NECK" pos = "0.0 0 0.02" rot="0.000000 0.000000 0.000000" scale="0.05 0.06 0.08"/>
+ <bone name="mHead" pos="0.000 -0.000 0.076" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="0.000000 -0.000000 0.075630">
+ <collision_volume name="HEAD" pos = "0.02 0 0.07" rot="0.000000 0.000000 0.000000" scale="0.11 0.09 0.12"/>
+ <bone name="mSkull" pos="0.000 0.000 0.079" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="0.000000 0.000000 0.079000">
+ </bone>
+ <bone name="mEyeRight" pos="0.098 -0.036 0.079" rot="0.000000 0.000000 -0.000000" scale="1.000 1.000 1.000" pivot="0.098466 -0.036000 0.079000">
+ </bone>
+ <bone name="mEyeLeft" pos="0.098 0.036 0.079" rot="0.000000 -0.000000 0.000000" scale="1.000 1.000 1.000" pivot="0.098461 0.036000 0.079000">
+ </bone>
+ </bone>
+ </bone>
+ <bone name="mCollarLeft" pos="-0.021 0.085 0.165" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="-0.020927 0.084665 0.165396">
+ <collision_volume name="L_CLAVICLE" pos = "0.02 0 0.02" rot="0.000000 0.00000 0.000000" scale="0.07 0.14 0.05"/>
+ <bone name="mShoulderLeft" pos="0.000 0.079 -0.000" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="0.000000 0.079000 -0.000000">
+ <collision_volume name="L_UPPER_ARM" pos = "0.0 0.12 0.01" rot="-5.000000 0.00000 0.000000" scale="0.05 0.17 0.05"/>
+ <bone name="mElbowLeft" pos="0.000 0.248 0.000" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="0.000000 0.248000 0.000000">
+ <collision_volume name="L_LOWER_ARM" pos = "0.0 0.1 0.0" rot="-3.000000 0.00000 0.000000" scale="0.04 0.14 0.04"/>
+ <bone name="mWristLeft" pos="-0.000 0.205 0.000" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="-0.000000 0.204846 0.000000">
+ <collision_volume name="L_HAND" pos = "0.01 0.05 0.0" rot="-3.000000 0.00000 -10.000000" scale="0.05 0.08 0.03"/>
+ </bone>
+ </bone>
+ </bone>
+ </bone>
+ <bone name="mCollarRight" pos="-0.021 -0.085 0.165" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="-0.020927 -0.085000 0.165396">
+ <collision_volume name="R_CLAVICLE" pos = "0.02 0 0.02" rot="0.000000 0.00000 0.000000" scale="0.07 0.14 0.05"/>
+ <bone name="mShoulderRight" pos="0.000 -0.079 -0.000" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="0.000000 -0.079418 -0.000000">
+ <collision_volume name="R_UPPER_ARM" pos = "0.0 -0.12 0.01" rot="5.000000 0.00000 0.000000" scale="0.05 0.17 0.05"/>
+ <bone name="mElbowRight" pos="0.000 -0.248 -0.000" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="0.000000 -0.248000 -0.000000">
+ <collision_volume name="R_LOWER_ARM" pos = "0.0 -0.1 0.0" rot="3.000000 0.00000 0.000000" scale="0.04 0.14 0.04"/>
+ <bone name="mWristRight" pos="0.000 -0.205 -0.000" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="-0.000000 -0.205000 -0.000000">
+ <collision_volume name="R_HAND" pos = "0.01 -0.05 0.0" rot="3.000000 0.00000 10.000000" scale="0.05 0.08 0.03"/>
+ </bone>
+ </bone>
+ </bone>
+ </bone>
+ </bone>
+ </bone>
+ <bone name="mHipRight" pos="0.034 -0.129 -0.041" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="0.033620 -0.128806 -0.041086">
+ <collision_volume name="R_UPPER_LEG" pos = "-0.02 0.05 -0.22" rot="0.000000 0.00000 0.000000" scale="0.09 0.09 0.32"/>
+ <bone name="mKneeRight" pos="-0.001 0.049 -0.491" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="-0.000780 0.048635 -0.490922">
+ <collision_volume name="R_LOWER_LEG" pos = "-0.02 0.0 -0.2" rot="0.000000 0.00000 0.000000" scale="0.06 0.06 0.25"/>
+ <bone name="mAnkleRight" pos="-0.029 0.000 -0.468" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="-0.028869 0.000000 -0.468494">
+ <collision_volume name="R_FOOT" pos = "0.077 0.0 -0.041" rot="0.000000 10.00000 0.000000" scale="0.13 0.05 0.05"/>
+ <bone name="mFootRight" pos="0.112 -0.000 -0.061" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="0.111956 -0.000000 -0.060637">
+ <bone name="mToeRight" pos="0.109 0.000 0.000" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="0.105399 -0.010408 -0.000104">
+ </bone>
+ </bone>
+ </bone>
+ </bone>
+ </bone>
+ <bone name="mHipLeft" pos="0.034 0.127 -0.041" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="0.033757 0.126765 -0.040998">
+ <collision_volume name="L_UPPER_LEG" pos = "-0.02 -0.05 -0.22" rot="0.000000 0.00000 0.000000" scale="0.09 0.09 0.32"/>
+ <bone name="mKneeLeft" pos="-0.001 -0.046 -0.491" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="-0.000887 -0.045568 -0.491053">
+ <collision_volume name="L_LOWER_LEG" pos = "-0.02 0.0 -0.2" rot="0.000000 0.00000 0.000000" scale="0.06 0.06 0.25"/>
+ <bone name="mAnkleLeft" pos="-0.029 0.001 -0.468" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="-0.028887 0.001378 -0.468449">
+ <collision_volume name="L_FOOT" pos = "0.077 0.0 -0.041" rot="0.000000 10.00000 0.000000" scale="0.13 0.05 0.05"/>
+ <bone name="mFootLeft" pos="0.112 -0.000 -0.061" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="0.111956 -0.000000 -0.060620">
+ <bone name="mToeLeft" pos="0.109 0.000 0.000" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="0.105387 0.008270 0.000871">
+ </bone>
+ </bone>
+ </bone>
+ </bone>
+ </bone>
+</bone>
+</linden_skeleton>
diff --git a/indra/newview/llcallbacklist.cpp b/indra/newview/llcallbacklist.cpp
index 59ecbdd0ea..59ecbdd0ea 100755..100644
--- a/indra/newview/llcallbacklist.cpp
+++ b/indra/newview/llcallbacklist.cpp
diff --git a/indra/newview/llcommandhandler.cpp b/indra/newview/llcommandhandler.cpp
index 19dba3f917..5ea7efc045 100755
--- a/indra/newview/llcommandhandler.cpp
+++ b/indra/newview/llcommandhandler.cpp
@@ -30,6 +30,7 @@
#include "llcommandhandler.h"
#include "llnotificationsutil.h"
#include "llcommanddispatcherlistener.h"
+#include "llstartup.h"
#include "stringize.h"
// system includes
@@ -116,7 +117,11 @@ bool LLCommandHandlerRegistry::dispatch(const std::string& cmd,
LL_WARNS_ONCE("SLURL") << "Blocked SLURL command from untrusted browser" << LL_ENDL;
if (! slurl_blocked)
{
- LLNotificationsUtil::add("BlockedSLURL");
+ if (LLStartUp::getStartupState() >= STATE_BROWSER_INIT)
+ {
+ // Note: commands can arrive before we initialize everything we need for Notification.
+ LLNotificationsUtil::add("BlockedSLURL");
+ }
slurl_blocked = true;
}
return true;
@@ -138,7 +143,10 @@ bool LLCommandHandlerRegistry::dispatch(const std::string& cmd,
LL_WARNS_ONCE("SLURL") << "Throttled SLURL command from untrusted browser" << LL_ENDL;
if (! slurl_throttled)
{
- LLNotificationsUtil::add("ThrottledSLURL");
+ if (LLStartUp::getStartupState() >= STATE_BROWSER_INIT)
+ {
+ LLNotificationsUtil::add("ThrottledSLURL");
+ }
slurl_throttled = true;
}
return true;
diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp
index 821d58a9b2..b3821fda85 100755
--- a/indra/newview/lldrawpoolavatar.cpp
+++ b/indra/newview/lldrawpoolavatar.cpp
@@ -55,8 +55,6 @@ static U32 sDataMask = LLDrawPoolAvatar::VERTEX_DATA_MASK;
static U32 sBufferUsage = GL_STREAM_DRAW_ARB;
static U32 sShaderLevel = 0;
-#define JOINT_COUNT 52
-
LLGLSLShader* LLDrawPoolAvatar::sVertexProgram = NULL;
BOOL LLDrawPoolAvatar::sSkipOpaque = FALSE;
BOOL LLDrawPoolAvatar::sSkipTransparent = FALSE;
@@ -1462,7 +1460,13 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)
}
}
-void LLDrawPoolAvatar::getRiggedGeometry(LLFace* face, LLPointer<LLVertexBuffer>& buffer, U32 data_mask, const LLMeshSkinInfo* skin, LLVolume* volume, const LLVolumeFace& vol_face)
+void LLDrawPoolAvatar::getRiggedGeometry(
+ LLFace* face,
+ LLPointer<LLVertexBuffer>& buffer,
+ U32 data_mask,
+ const LLMeshSkinInfo* skin,
+ LLVolume* volume,
+ const LLVolumeFace& vol_face)
{
face->setGeomIndex(0);
face->setIndicesIndex(0);
@@ -1471,7 +1475,8 @@ void LLDrawPoolAvatar::getRiggedGeometry(LLFace* face, LLPointer<LLVertexBuffer>
face->setTextureIndex(255);
if (buffer.isNull() || buffer->getTypeMask() != data_mask || !buffer->isWriteable())
- { //make a new buffer
+ {
+ // make a new buffer
if (sShaderLevel > 0)
{
buffer = new LLVertexBuffer(data_mask, GL_DYNAMIC_DRAW_ARB);
@@ -1483,7 +1488,8 @@ void LLDrawPoolAvatar::getRiggedGeometry(LLFace* face, LLPointer<LLVertexBuffer>
buffer->allocateBuffer(vol_face.mNumVertices, vol_face.mNumIndices, true);
}
else
- { //resize existing buffer
+ {
+ //resize existing buffer
buffer->resizeBuffer(vol_face.mNumVertices, vol_face.mNumIndices);
}
@@ -1497,9 +1503,9 @@ void LLDrawPoolAvatar::getRiggedGeometry(LLFace* face, LLPointer<LLVertexBuffer>
m = m.inverse().transpose();
F32 mat3[] =
- { m.m[0], m.m[1], m.m[2],
- m.m[4], m.m[5], m.m[6],
- m.m[8], m.m[9], m.m[10] };
+ { m.m[0], m.m[1], m.m[2],
+ m.m[4], m.m[5], m.m[6],
+ m.m[8], m.m[9], m.m[10] };
LLMatrix3 mat_normal(mat3);
@@ -1526,14 +1532,96 @@ void LLDrawPoolAvatar::getRiggedGeometry(LLFace* face, LLPointer<LLVertexBuffer>
{
face->clearState(LLFace::TEXTURE_ANIM);
}
-
-
face->getGeometryVolume(*volume, face->getTEOffset(), mat_vert, mat_normal, offset, true);
buffer->flush();
}
-void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(LLVOAvatar* avatar, LLFace* face, const LLMeshSkinInfo* skin, LLVolume* volume, const LLVolumeFace& vol_face)
+// static
+void LLDrawPoolAvatar::initSkinningMatrixPalette(
+ LLMatrix4* mat,
+ S32 count,
+ const LLMeshSkinInfo* skin,
+ LLVOAvatar *avatar)
+{
+ // BENTO - switching to use Matrix4a and SSE might speed this up.
+ // Note that we are mostly passing Matrix4a's to this routine anyway, just dubiously casted.
+ for (U32 j = 0; j < count; ++j)
+ {
+ LLJoint* joint = avatar->getJoint(skin->mJointNames[j]);
+ if (!joint)
+ {
+ joint = avatar->getJoint("mPelvis");
+ }
+ if (joint)
+ {
+ mat[j] = skin->mInvBindMatrix[j];
+ mat[j] *= joint->getWorldMatrix();
+ }
+ }
+ // This handles a bogus weights case that has turned up in
+ // practice, without the overhead of zeroing every matrix. We are
+ // doing this here instead of in getPerVertexSkinMatrix so the fix
+ // will also work in the HW skinning case.
+ if (count < LL_MAX_JOINTS_PER_MESH_OBJECT)
+ {
+ mat[count].setIdentity();
+ }
+}
+
+// static
+void LLDrawPoolAvatar::getPerVertexSkinMatrix(F32* weights, LLMatrix4a* mat, bool handle_bad_scale, LLMatrix4a& final_mat)
+{
+ final_mat.clear();
+
+ S32 idx[4];
+
+ LLVector4 wght;
+
+ F32 scale = 0.f;
+ for (U32 k = 0; k < 4; k++)
+ {
+ F32 w = weights[k];
+
+ // BENTO potential optimizations
+ // - Do clamping in unpackVolumeFaces() (once instead of every time)
+ // - int vs floor: if we know w is
+ // >= 0.0, we can use int instead of floorf; the latter
+ // allegedly has a lot of overhead due to ieeefp error
+ // checking which we should not need.
+ idx[k] = llclamp((S32) floorf(w), (S32)0, (S32)LL_MAX_JOINTS_PER_MESH_OBJECT-1);
+
+ wght[k] = w - floorf(w);
+ scale += wght[k];
+ }
+ if (handle_bad_scale && scale <= 0.f)
+ {
+ wght = LLVector4(1.0f, 0.0f, 0.0f, 0.0f);
+ }
+ else
+ {
+ // This is enforced in unpackVolumeFaces()
+ llassert(scale>0.f);
+ wght *= 1.f/scale;
+ }
+
+ for (U32 k = 0; k < 4; k++)
+ {
+ F32 w = wght[k];
+
+ LLMatrix4a src;
+ src.setMul(mat[idx[k]], w);
+
+ final_mat.add(src);
+ }
+}
+
+void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(
+ LLVOAvatar* avatar,
+ LLFace* face,
+ const LLMeshSkinInfo* skin,
+ LLVolume* volume,
+ const LLVolumeFace& vol_face)
{
LLVector4a* weight = vol_face.mWeights;
if (!weight)
@@ -1553,7 +1641,8 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(LLVOAvatar* avatar, LLFace*
(drawable && drawable->isState(LLDrawable::REBUILD_ALL)))
{
if (drawable && drawable->isState(LLDrawable::REBUILD_ALL))
- { //rebuild EVERY face in the drawable, not just this one, to avoid missing drawable wide rebuild issues
+ {
+ //rebuild EVERY face in the drawable, not just this one, to avoid missing drawable wide rebuild issues
for (S32 i = 0; i < drawable->getNumFaces(); ++i)
{
LLFace* facep = drawable->getFace(i);
@@ -1570,13 +1659,15 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(LLVOAvatar* avatar, LLFace*
buffer = face->getVertexBuffer();
}
else
- { //just rebuild this face
+ {
+ //just rebuild this face
getRiggedGeometry(face, buffer, data_mask, skin, volume, vol_face);
}
}
if (sShaderLevel <= 0 && face->mLastSkinTime < avatar->getLastSkinTime())
- { //perform software vertex skinning for this face
+ {
+ //perform software vertex skinning for this face
LLStrider<LLVector3> position;
LLStrider<LLVector3> normal;
@@ -1593,19 +1684,9 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(LLVOAvatar* avatar, LLFace*
LLVector4a* norm = has_normal ? (LLVector4a*) normal.get() : NULL;
//build matrix palette
- LLMatrix4a mp[JOINT_COUNT];
- LLMatrix4* mat = (LLMatrix4*) mp;
-
- U32 count = llmin((U32) skin->mJointNames.size(), (U32) JOINT_COUNT);
- for (U32 j = 0; j < count; ++j)
- {
- LLJoint* joint = avatar->getJoint(skin->mJointNames[j]);
- if (joint)
- {
- mat[j] = skin->mInvBindMatrix[j];
- mat[j] *= joint->getWorldMatrix();
- }
- }
+ LLMatrix4a mat[LL_MAX_JOINTS_PER_MESH_OBJECT];
+ U32 count = llmin((U32) skin->mJointNames.size(), (U32) LL_MAX_JOINTS_PER_MESH_OBJECT);
+ initSkinningMatrixPalette((LLMatrix4*)mat, count, skin, avatar);
LLMatrix4a bind_shape_matrix;
bind_shape_matrix.loadu(skin->mBindShapeMatrix);
@@ -1613,35 +1694,7 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(LLVOAvatar* avatar, LLFace*
for (U32 j = 0; j < buffer->getNumVerts(); ++j)
{
LLMatrix4a final_mat;
- final_mat.clear();
-
- S32 idx[4];
-
- LLVector4 wght;
-
- F32 scale = 0.f;
- for (U32 k = 0; k < 4; k++)
- {
- F32 w = weight[j][k];
-
- idx[k] = llclamp((S32) floorf(w), 0, JOINT_COUNT-1);
-
- wght[k] = w - floorf(w);
- scale += wght[k];
- }
-
- wght *= 1.f/scale;
-
- for (U32 k = 0; k < 4; k++)
- {
- F32 w = wght[k];
-
- LLMatrix4a src;
- src.setMul(mp[idx[k]], w);
-
- final_mat.add(src);
- }
-
+ getPerVertexSkinMatrix(weight[j].getF32ptr(), mat, false, final_mat);
LLVector4a& v = vol_face.mPositions[j];
LLVector4a t;
@@ -1721,30 +1774,21 @@ void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow)
if (buff)
{
if (sShaderLevel > 0)
- { //upload matrix palette to shader
- LLMatrix4 mat[JOINT_COUNT];
-
- U32 count = llmin((U32) skin->mJointNames.size(), (U32) JOINT_COUNT);
+ {
+ // upload matrix palette to shader
+ LLMatrix4a mat[LL_MAX_JOINTS_PER_MESH_OBJECT];
+ U32 count = llmin((U32) skin->mJointNames.size(), (U32) LL_MAX_JOINTS_PER_MESH_OBJECT);
+ initSkinningMatrixPalette((LLMatrix4*)mat, count, skin, avatar);
- for (U32 i = 0; i < count; ++i)
- {
- LLJoint* joint = avatar->getJoint(skin->mJointNames[i]);
- if (joint)
- {
- mat[i] = skin->mInvBindMatrix[i];
- mat[i] *= joint->getWorldMatrix();
- }
- }
-
stop_glerror();
- F32 mp[JOINT_COUNT*9];
+ F32 mp[LL_MAX_JOINTS_PER_MESH_OBJECT*9];
- F32 transp[JOINT_COUNT*3];
+ F32 transp[LL_MAX_JOINTS_PER_MESH_OBJECT*3];
for (U32 i = 0; i < count; ++i)
{
- F32* m = (F32*) mat[i].mMatrix;
+ F32* m = (F32*) mat[i].mMatrix[0].getF32ptr();
U32 idx = i*9;
diff --git a/indra/newview/lldrawpoolavatar.h b/indra/newview/lldrawpoolavatar.h
index b9d2204052..af063ee74e 100755
--- a/indra/newview/lldrawpoolavatar.h
+++ b/indra/newview/lldrawpoolavatar.h
@@ -134,6 +134,8 @@ public:
void endDeferredRiggedBump();
void getRiggedGeometry(LLFace* face, LLPointer<LLVertexBuffer>& buffer, U32 data_mask, const LLMeshSkinInfo* skin, LLVolume* volume, const LLVolumeFace& vol_face);
+ static void initSkinningMatrixPalette(LLMatrix4* mat, S32 count, const LLMeshSkinInfo* skin, LLVOAvatar *avatar);
+ static void getPerVertexSkinMatrix(F32* weights, LLMatrix4a* mat, bool handle_bad_scale, LLMatrix4a& final_mat);
void updateRiggedFaceVertexBuffer(LLVOAvatar* avatar,
LLFace* facep,
const LLMeshSkinInfo* skin,
diff --git a/indra/newview/llfloaterbvhpreview.cpp b/indra/newview/llfloaterbvhpreview.cpp
index 669ffa7c59..a800a3ca14 100755
--- a/indra/newview/llfloaterbvhpreview.cpp
+++ b/indra/newview/llfloaterbvhpreview.cpp
@@ -280,9 +280,12 @@ BOOL LLFloaterBvhPreview::postBuild()
LLDataPackerBinaryBuffer dp(buffer, buffer_size);
// pass animation data through memory buffer
+ LL_INFOS("BVH") << "Serializing loaderp" << LL_ENDL;
loaderp->serialize(dp);
dp.reset();
+ LL_INFOS("BVH") << "Deserializing motionp" << LL_ENDL;
BOOL success = motionp && motionp->deserialize(dp);
+ LL_INFOS("BVH") << "Done" << LL_ENDL;
delete []buffer;
diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp
index 6804b21b28..18a2729398 100755
--- a/indra/newview/llfloatermodelpreview.cpp
+++ b/indra/newview/llfloatermodelpreview.cpp
@@ -26,35 +26,8 @@
#include "llviewerprecompiledheaders.h"
-#if LL_MSVC
-#pragma warning (disable : 4263)
-#pragma warning (disable : 4264)
-#endif
-#include "dae.h"
-//#include "dom.h"
-#include "dom/domAsset.h"
-#include "dom/domBind_material.h"
-#include "dom/domCOLLADA.h"
-#include "dom/domConstants.h"
-#include "dom/domController.h"
-#include "dom/domEffect.h"
-#include "dom/domGeometry.h"
-#include "dom/domInstance_geometry.h"
-#include "dom/domInstance_material.h"
-#include "dom/domInstance_node.h"
-#include "dom/domInstance_effect.h"
-#include "dom/domMaterial.h"
-#include "dom/domMatrix.h"
-#include "dom/domNode.h"
-#include "dom/domProfile_COMMON.h"
-#include "dom/domRotate.h"
-#include "dom/domScale.h"
-#include "dom/domTranslate.h"
-#include "dom/domVisual_scene.h"
-#if LL_MSVC
-#pragma warning (default : 4263)
-#pragma warning (default : 4264)
-#endif
+#include "llmodelloader.h"
+#include "lldaeloader.h"
#include "llfloatermodelpreview.h"
@@ -112,14 +85,15 @@
#include "llanimationstates.h"
#include "llviewernetwork.h"
#include "llviewershadermgr.h"
-#include "glod/glod.h"
-const S32 SLM_SUPPORTED_VERSION = 3;
+#include "glod/glod.h"
+#include <boost/algorithm/string.hpp>
//static
S32 LLFloaterModelPreview::sUploadAmount = 10;
LLFloaterModelPreview* LLFloaterModelPreview::sInstance = NULL;
-std::list<LLModelLoader*> LLModelLoader::sActiveLoaderList;
+
+bool LLModelPreview::sIgnoreLoadedCallback = false;
// "Retain%" decomp parameter has values from 0.0 to 1.0 by 0.01
// But according to the UI spec for upload model floater, this parameter
@@ -199,190 +173,46 @@ std::string lod_label_name[NUM_LOD+1] =
"I went off the end of the lod_label_name array. Me so smart."
};
-std::string colladaVersion[VERSIONTYPE_COUNT+1] =
-{
- "1.4.0",
- "1.4.1",
- "Unsupported"
-};
-
-
-#define LL_DEGENERACY_TOLERANCE 1e-7f
-
-inline F32 dot3fpu(const LLVector4a& a, const LLVector4a& b)
-{
- volatile F32 p0 = a[0] * b[0];
- volatile F32 p1 = a[1] * b[1];
- volatile F32 p2 = a[2] * b[2];
- return p0 + p1 + p2;
-}
-
-bool ll_is_degenerate(const LLVector4a& a, const LLVector4a& b, const LLVector4a& c, F32 tolerance = LL_DEGENERACY_TOLERANCE)
-{
- // small area check
- {
- LLVector4a edge1; edge1.setSub( a, b );
- LLVector4a edge2; edge2.setSub( a, c );
- //////////////////////////////////////////////////////////////////////////
- /// Linden Modified
- //////////////////////////////////////////////////////////////////////////
-
- // If no one edge is more than 10x longer than any other edge, we weaken
- // the tolerance by a factor of 1e-4f.
-
- LLVector4a edge3; edge3.setSub( c, b );
- const F32 len1sq = edge1.dot3(edge1).getF32();
- const F32 len2sq = edge2.dot3(edge2).getF32();
- const F32 len3sq = edge3.dot3(edge3).getF32();
- bool abOK = (len1sq <= 100.f * len2sq) && (len1sq <= 100.f * len3sq);
- bool acOK = (len2sq <= 100.f * len1sq) && (len1sq <= 100.f * len3sq);
- bool cbOK = (len3sq <= 100.f * len1sq) && (len1sq <= 100.f * len2sq);
- if ( abOK && acOK && cbOK )
- {
- tolerance *= 1e-4f;
- }
-
- //////////////////////////////////////////////////////////////////////////
- /// End Modified
- //////////////////////////////////////////////////////////////////////////
-
- LLVector4a cross; cross.setCross3( edge1, edge2 );
-
- LLVector4a edge1b; edge1b.setSub( b, a );
- LLVector4a edge2b; edge2b.setSub( b, c );
- LLVector4a crossb; crossb.setCross3( edge1b, edge2b );
-
- if ( ( cross.dot3(cross).getF32() < tolerance ) || ( crossb.dot3(crossb).getF32() < tolerance ))
- {
- return true;
- }
- }
-
- // point triangle distance check
- {
- LLVector4a Q; Q.setSub(a, b);
- LLVector4a R; R.setSub(c, b);
-
- const F32 QQ = dot3fpu(Q, Q);
- const F32 RR = dot3fpu(R, R);
- const F32 QR = dot3fpu(R, Q);
-
- volatile F32 QQRR = QQ * RR;
- volatile F32 QRQR = QR * QR;
- F32 Det = (QQRR - QRQR);
-
- if( Det == 0.0f )
- {
- return true;
- }
- }
-
- return false;
-}
-
-bool validate_face(const LLVolumeFace& face)
+BOOL stop_gloderror()
{
+ GLuint error = glodGetError();
- for (U32 v = 0; v < face.mNumVertices; v++)
- {
- if(face.mPositions && !face.mPositions[v].isFinite3())
- {
- LL_WARNS() << "NaN position data in face found!" << LL_ENDL;
- return false;
- }
-
- if(face.mNormals && !face.mNormals[v].isFinite3())
- {
- LL_WARNS() << "NaN normal data in face found!" << LL_ENDL;
- return false;
- }
- }
-
- for (U32 i = 0; i < face.mNumIndices; ++i)
- {
- if (face.mIndices[i] >= face.mNumVertices)
- {
- LL_WARNS() << "Face has invalid index." << LL_ENDL;
- return false;
- }
- }
-
- if (face.mNumIndices % 3 != 0 || face.mNumIndices == 0)
+ if (error != GLOD_NO_ERROR)
{
- LL_WARNS() << "Face has invalid number of indices." << LL_ENDL;
- return false;
+ LL_WARNS() << "GLOD error detected, cannot generate LOD: " << std::hex << error << LL_ENDL;
+ return TRUE;
}
-
- /*const LLVector4a scale(0.5f);
-
-
- for (U32 i = 0; i < face.mNumIndices; i+=3)
- {
- U16 idx1 = face.mIndices[i];
- U16 idx2 = face.mIndices[i+1];
- U16 idx3 = face.mIndices[i+2];
-
- LLVector4a v1; v1.setMul(face.mPositions[idx1], scale);
- LLVector4a v2; v2.setMul(face.mPositions[idx2], scale);
- LLVector4a v3; v3.setMul(face.mPositions[idx3], scale);
-
- if (ll_is_degenerate(v1,v2,v3))
- {
- LL_WARNS() << "Degenerate face found!" << LL_ENDL;
- return false;
- }
- }*/
- return true;
+ return FALSE;
}
-bool validate_model(const LLModel* mdl)
+LLViewerFetchedTexture* bindMaterialDiffuseTexture(const LLImportMaterial& material)
{
- if (mdl->getNumVolumeFaces() == 0)
- {
- LL_WARNS() << "Model has no faces!" << LL_ENDL;
- return false;
- }
+ LLViewerFetchedTexture *texture = LLViewerTextureManager::getFetchedTexture(material.getDiffuseMap(), FTT_DEFAULT, TRUE, LLGLTexture::BOOST_PREVIEW);
- for (S32 i = 0; i < mdl->getNumVolumeFaces(); ++i)
+ if (texture)
{
- if (mdl->getVolumeFace(i).mNumVertices == 0)
- {
- LL_WARNS() << "Face has no vertices." << LL_ENDL;
- return false;
- }
-
- if (mdl->getVolumeFace(i).mNumIndices == 0)
+ if (texture->getDiscardLevel() > -1)
{
- LL_WARNS() << "Face has no indices." << LL_ENDL;
- return false;
- }
-
- if (!validate_face(mdl->getVolumeFace(i)))
- {
- return false;
+ gGL.getTexUnit(0)->bind(texture, true);
+ return texture;
}
}
- return true;
+ return NULL;
}
-BOOL stop_gloderror()
+std::string stripSuffix(std::string name)
{
- GLuint error = glodGetError();
-
- if (error != GLOD_NO_ERROR)
+ if ((name.find("_LOD") != -1) || (name.find("_PHYS") != -1))
{
- LL_WARNS() << "GLOD error detected, cannot generate LOD: " << std::hex << error << LL_ENDL;
- return TRUE;
+ return name.substr(0, name.rfind('_'));
}
-
- return FALSE;
+ return name;
}
-
LLMeshFilePicker::LLMeshFilePicker(LLModelPreview* mp, S32 lod)
- : LLFilePickerThread(LLFilePicker::FFLOAD_COLLADA)
+: LLFilePickerThread(LLFilePicker::FFLOAD_COLLADA)
{
mMP = mp;
mLOD = lod;
@@ -393,6 +223,29 @@ void LLMeshFilePicker::notify(const std::string& filename)
mMP->loadModel(mFile, mLOD);
}
+void FindModel(LLModelLoader::scene& scene, const std::string& name_to_match, LLModel*& baseModelOut, LLMatrix4& matOut)
+{
+ LLModelLoader::scene::iterator base_iter = scene.begin();
+ bool found = false;
+ while (!found && (base_iter != scene.end()))
+ {
+ matOut = base_iter->first;
+
+ LLModelLoader::model_instance_list::iterator base_instance_iter = base_iter->second.begin();
+ while (!found && (base_instance_iter != base_iter->second.end()))
+ {
+ LLModelInstance& base_instance = *base_instance_iter++;
+ LLModel* base_model = base_instance.mModel;
+
+ if (base_model && (base_model->mLabel == name_to_match))
+ {
+ baseModelOut = base_model;
+ return;
+ }
+ }
+ base_iter++;
+ }
+}
//-----------------------------------------------------------------------------
// LLFloaterModelPreview()
@@ -613,6 +466,11 @@ void LLFloaterModelPreview::disableViewOption(const std::string& option)
void LLFloaterModelPreview::loadModel(S32 lod)
{
mModelPreview->mLoading = true;
+ if (lod == LLModel::LOD_PHYSICS)
+ {
+ // loading physics from file
+ mModelPreview->mPhysicsSearchLOD = lod;
+ }
(new LLMeshFilePicker(mModelPreview, lod))->getFile();
}
@@ -791,9 +649,9 @@ void LLFloaterModelPreview::draw()
childSetTextArg("status", "[STATUS]", getString("status_material_mismatch"));
}
else
- if ( mModelPreview->getLoadState() > LLModelLoader::ERROR_PARSING )
- {
- childSetTextArg("status", "[STATUS]", getString(LLModel::getStatusString(mModelPreview->getLoadState() - LLModelLoader::ERROR_PARSING)));
+ if ( mModelPreview->getLoadState() > LLModelLoader::ERROR_MODEL )
+ {
+ childSetTextArg("status", "[STATUS]", getString(LLModel::getStatusString(mModelPreview->getLoadState() - LLModelLoader::ERROR_MODEL)));
}
else
if ( mModelPreview->getLoadState() == LLModelLoader::ERROR_PARSING )
@@ -945,9 +803,16 @@ BOOL LLFloaterModelPreview::handleScrollWheel(S32 x, S32 y, S32 clicks)
/*virtual*/
void LLFloaterModelPreview::onOpen(const LLSD& key)
{
+ LLModelPreview::sIgnoreLoadedCallback = false;
requestAgentUploadPermissions();
}
+/*virtual*/
+void LLFloaterModelPreview::onClose(bool app_quitting)
+{
+ LLModelPreview::sIgnoreLoadedCallback = true;
+}
+
//static
void LLFloaterModelPreview::onPhysicsParamCommit(LLUICtrl* ctrl, void* data)
{
@@ -1308,1815 +1173,6 @@ void LLFloaterModelPreview::onMouseCaptureLostModelPreview(LLMouseHandler* handl
}
//-----------------------------------------------------------------------------
-// LLModelLoader
-//-----------------------------------------------------------------------------
-LLModelLoader::LLModelLoader( std::string filename, S32 lod, LLModelPreview* preview, JointTransformMap& jointMap,
- std::deque<std::string>& jointsFromNodes )
-: mJointList( jointMap )
-, mJointsFromNode( jointsFromNodes )
-, LLThread("Model Loader"), mFilename(filename), mLod(lod), mPreview(preview), mFirstTransform(TRUE), mNumOfFetchingTextures(0)
-{
- mJointMap["mPelvis"] = "mPelvis";
- mJointMap["mTorso"] = "mTorso";
- mJointMap["mChest"] = "mChest";
- mJointMap["mNeck"] = "mNeck";
- mJointMap["mHead"] = "mHead";
- mJointMap["mSkull"] = "mSkull";
- mJointMap["mEyeRight"] = "mEyeRight";
- mJointMap["mEyeLeft"] = "mEyeLeft";
- mJointMap["mCollarLeft"] = "mCollarLeft";
- mJointMap["mShoulderLeft"] = "mShoulderLeft";
- mJointMap["mElbowLeft"] = "mElbowLeft";
- mJointMap["mWristLeft"] = "mWristLeft";
- mJointMap["mCollarRight"] = "mCollarRight";
- mJointMap["mShoulderRight"] = "mShoulderRight";
- mJointMap["mElbowRight"] = "mElbowRight";
- mJointMap["mWristRight"] = "mWristRight";
- mJointMap["mHipRight"] = "mHipRight";
- mJointMap["mKneeRight"] = "mKneeRight";
- mJointMap["mAnkleRight"] = "mAnkleRight";
- mJointMap["mFootRight"] = "mFootRight";
- mJointMap["mToeRight"] = "mToeRight";
- mJointMap["mHipLeft"] = "mHipLeft";
- mJointMap["mKneeLeft"] = "mKneeLeft";
- mJointMap["mAnkleLeft"] = "mAnkleLeft";
- mJointMap["mFootLeft"] = "mFootLeft";
- mJointMap["mToeLeft"] = "mToeLeft";
-
- mJointMap["avatar_mPelvis"] = "mPelvis";
- mJointMap["avatar_mTorso"] = "mTorso";
- mJointMap["avatar_mChest"] = "mChest";
- mJointMap["avatar_mNeck"] = "mNeck";
- mJointMap["avatar_mHead"] = "mHead";
- mJointMap["avatar_mSkull"] = "mSkull";
- mJointMap["avatar_mEyeRight"] = "mEyeRight";
- mJointMap["avatar_mEyeLeft"] = "mEyeLeft";
- mJointMap["avatar_mCollarLeft"] = "mCollarLeft";
- mJointMap["avatar_mShoulderLeft"] = "mShoulderLeft";
- mJointMap["avatar_mElbowLeft"] = "mElbowLeft";
- mJointMap["avatar_mWristLeft"] = "mWristLeft";
- mJointMap["avatar_mCollarRight"] = "mCollarRight";
- mJointMap["avatar_mShoulderRight"] = "mShoulderRight";
- mJointMap["avatar_mElbowRight"] = "mElbowRight";
- mJointMap["avatar_mWristRight"] = "mWristRight";
- mJointMap["avatar_mHipRight"] = "mHipRight";
- mJointMap["avatar_mKneeRight"] = "mKneeRight";
- mJointMap["avatar_mAnkleRight"] = "mAnkleRight";
- mJointMap["avatar_mFootRight"] = "mFootRight";
- mJointMap["avatar_mToeRight"] = "mToeRight";
- mJointMap["avatar_mHipLeft"] = "mHipLeft";
- mJointMap["avatar_mKneeLeft"] = "mKneeLeft";
- mJointMap["avatar_mAnkleLeft"] = "mAnkleLeft";
- mJointMap["avatar_mFootLeft"] = "mFootLeft";
- mJointMap["avatar_mToeLeft"] = "mToeLeft";
-
-
- mJointMap["hip"] = "mPelvis";
- mJointMap["abdomen"] = "mTorso";
- mJointMap["chest"] = "mChest";
- mJointMap["neck"] = "mNeck";
- mJointMap["head"] = "mHead";
- mJointMap["figureHair"] = "mSkull";
- mJointMap["lCollar"] = "mCollarLeft";
- mJointMap["lShldr"] = "mShoulderLeft";
- mJointMap["lForeArm"] = "mElbowLeft";
- mJointMap["lHand"] = "mWristLeft";
- mJointMap["rCollar"] = "mCollarRight";
- mJointMap["rShldr"] = "mShoulderRight";
- mJointMap["rForeArm"] = "mElbowRight";
- mJointMap["rHand"] = "mWristRight";
- mJointMap["rThigh"] = "mHipRight";
- mJointMap["rShin"] = "mKneeRight";
- mJointMap["rFoot"] = "mFootRight";
- mJointMap["lThigh"] = "mHipLeft";
- mJointMap["lShin"] = "mKneeLeft";
- mJointMap["lFoot"] = "mFootLeft";
-
- if (mPreview)
- {
- //only try to load from slm if viewer is configured to do so and this is the
- //initial model load (not an LoD or physics shape)
- mTrySLM = gSavedSettings.getBOOL("MeshImportUseSLM") && mPreview->mUploadData.empty();
- mPreview->setLoadState(STARTING);
- }
- else
- {
- mTrySLM = false;
- }
-
- assert_main_thread();
- sActiveLoaderList.push_back(this) ;
-}
-
-LLModelLoader::~LLModelLoader()
-{
- assert_main_thread();
- sActiveLoaderList.remove(this);
-}
-
-void stretch_extents(LLModel* model, LLMatrix4a& mat, LLVector4a& min, LLVector4a& max, BOOL& first_transform)
-{
- LLVector4a box[] =
- {
- LLVector4a(-1, 1,-1),
- LLVector4a(-1, 1, 1),
- LLVector4a(-1,-1,-1),
- LLVector4a(-1,-1, 1),
- LLVector4a( 1, 1,-1),
- LLVector4a( 1, 1, 1),
- LLVector4a( 1,-1,-1),
- LLVector4a( 1,-1, 1),
- };
-
- for (S32 j = 0; j < model->getNumVolumeFaces(); ++j)
- {
- const LLVolumeFace& face = model->getVolumeFace(j);
-
- LLVector4a center;
- center.setAdd(face.mExtents[0], face.mExtents[1]);
- center.mul(0.5f);
- LLVector4a size;
- size.setSub(face.mExtents[1],face.mExtents[0]);
- size.mul(0.5f);
-
- for (U32 i = 0; i < 8; i++)
- {
- LLVector4a t;
- t.setMul(size, box[i]);
- t.add(center);
-
- LLVector4a v;
-
- mat.affineTransform(t, v);
-
- if (first_transform)
- {
- first_transform = FALSE;
- min = max = v;
- }
- else
- {
- update_min_max(min, max, v);
- }
- }
- }
-}
-
-void stretch_extents(LLModel* model, LLMatrix4& mat, LLVector3& min, LLVector3& max, BOOL& first_transform)
-{
- LLVector4a mina, maxa;
- LLMatrix4a mata;
-
- mata.loadu(mat);
- mina.load3(min.mV);
- maxa.load3(max.mV);
-
- stretch_extents(model, mata, mina, maxa, first_transform);
-
- min.set(mina.getF32ptr());
- max.set(maxa.getF32ptr());
-}
-
-void LLModelLoader::run()
-{
- doLoadModel();
- doOnIdleOneTime(boost::bind(&LLModelLoader::loadModelCallback,this));
-}
-
-bool LLModelLoader::doLoadModel()
-{
- //first, look for a .slm file of the same name that was modified later
- //than the .dae
-
- if (mTrySLM)
- {
- std::string filename = mFilename;
-
- std::string::size_type i = filename.rfind(".");
- if (i != std::string::npos)
- {
- filename.replace(i, filename.size()-1, ".slm");
- llstat slm_status;
- if (LLFile::stat(filename, &slm_status) == 0)
- { //slm file exists
- llstat dae_status;
- if (LLFile::stat(mFilename, &dae_status) != 0 ||
- dae_status.st_mtime < slm_status.st_mtime)
- {
- if (loadFromSLM(filename))
- { //slm successfully loaded, if this fails, fall through and
- //try loading from dae
-
- mLod = -1; //successfully loading from an slm implicitly sets all
- //LoDs
- return true;
- }
- }
- }
- }
- }
-
- //no suitable slm exists, load from the .dae file
- DAE dae;
- domCOLLADA* dom = dae.open(mFilename);
-
- if (!dom)
- {
- LL_INFOS()<<" Error with dae - traditionally indicates a corrupt file."<<LL_ENDL;
- setLoadState( ERROR_PARSING );
- return false;
- }
- //Dom version
- daeString domVersion = dae.getDomVersion();
- std::string sldom(domVersion);
- LL_INFOS()<<"Collada Importer Version: "<<sldom<<LL_ENDL;
- //Dae version
- domVersionType docVersion = dom->getVersion();
- //0=1.4
- //1=1.4.1
- //2=Currently unsupported, however may work
- if (docVersion > 1 )
- {
- docVersion = VERSIONTYPE_COUNT;
- }
- LL_INFOS()<<"Dae version "<<colladaVersion[docVersion]<<LL_ENDL;
-
-
- daeDatabase* db = dae.getDatabase();
-
- daeInt count = db->getElementCount(NULL, COLLADA_TYPE_MESH);
-
- daeDocument* doc = dae.getDoc(mFilename);
- if (!doc)
- {
- LL_WARNS() << "can't find internal doc" << LL_ENDL;
- return false;
- }
-
- daeElement* root = doc->getDomRoot();
- if (!root)
- {
- LL_WARNS() << "document has no root" << LL_ENDL;
- return false;
- }
-
- //Verify some basic properties of the dae
- //1. Basic validity check on controller
- U32 controllerCount = (int) db->getElementCount( NULL, "controller" );
- bool result = false;
- for ( int i=0; i<controllerCount; ++i )
- {
- domController* pController = NULL;
- db->getElement( (daeElement**) &pController, i , NULL, "controller" );
- result = mPreview->verifyController( pController );
- if (!result)
- {
- setLoadState( ERROR_PARSING );
- return true;
- }
- }
-
-
- //get unit scale
- mTransform.setIdentity();
-
- domAsset::domUnit* unit = daeSafeCast<domAsset::domUnit>(root->getDescendant(daeElement::matchType(domAsset::domUnit::ID())));
-
- if (unit)
- {
- F32 meter = unit->getMeter();
- mTransform.mMatrix[0][0] = meter;
- mTransform.mMatrix[1][1] = meter;
- mTransform.mMatrix[2][2] = meter;
- }
-
- //get up axis rotation
- LLMatrix4 rotation;
-
- domUpAxisType up = UPAXISTYPE_Y_UP; // default is Y_UP
- domAsset::domUp_axis* up_axis =
- daeSafeCast<domAsset::domUp_axis>(root->getDescendant(daeElement::matchType(domAsset::domUp_axis::ID())));
-
- if (up_axis)
- {
- up = up_axis->getValue();
- }
-
- if (up == UPAXISTYPE_X_UP)
- {
- rotation.initRotation(0.0f, 90.0f * DEG_TO_RAD, 0.0f);
- }
- else if (up == UPAXISTYPE_Y_UP)
- {
- rotation.initRotation(90.0f * DEG_TO_RAD, 0.0f, 0.0f);
- }
-
- rotation *= mTransform;
- mTransform = rotation;
-
-
- for (daeInt idx = 0; idx < count; ++idx)
- { //build map of domEntities to LLModel
- domMesh* mesh = NULL;
- db->getElement((daeElement**) &mesh, idx, NULL, COLLADA_TYPE_MESH);
-
- if (mesh)
- {
- LLPointer<LLModel> model = LLModel::loadModelFromDomMesh(mesh);
-
- if(model->getStatus() != LLModel::NO_ERRORS)
- {
- setLoadState(ERROR_PARSING + model->getStatus()) ;
- return false; //abort
- }
-
- if (model.notNull() && validate_model(model))
- {
- mModelList.push_back(model);
- mModel[mesh] = model;
- }
- }
- }
-
- count = db->getElementCount(NULL, COLLADA_TYPE_SKIN);
- for (daeInt idx = 0; idx < count; ++idx)
- { //add skinned meshes as instances
- domSkin* skin = NULL;
- db->getElement((daeElement**) &skin, idx, NULL, COLLADA_TYPE_SKIN);
-
- if (skin)
- {
- domGeometry* geom = daeSafeCast<domGeometry>(skin->getSource().getElement());
-
- if (geom)
- {
- domMesh* mesh = geom->getMesh();
- if (mesh)
- {
- LLModel* model = mModel[mesh];
- if (model)
- {
- LLVector3 mesh_scale_vector;
- LLVector3 mesh_translation_vector;
- model->getNormalizedScaleTranslation(mesh_scale_vector, mesh_translation_vector);
-
- LLMatrix4 normalized_transformation;
- normalized_transformation.setTranslation(mesh_translation_vector);
-
- LLMatrix4 mesh_scale;
- mesh_scale.initScale(mesh_scale_vector);
- mesh_scale *= normalized_transformation;
- normalized_transformation = mesh_scale;
-
- glh::matrix4f inv_mat((F32*) normalized_transformation.mMatrix);
- inv_mat = inv_mat.inverse();
- LLMatrix4 inverse_normalized_transformation(inv_mat.m);
-
- domSkin::domBind_shape_matrix* bind_mat = skin->getBind_shape_matrix();
-
- if (bind_mat)
- { //get bind shape matrix
- domFloat4x4& dom_value = bind_mat->getValue();
-
- LLMeshSkinInfo& skin_info = model->mSkinInfo;
-
- for (int i = 0; i < 4; i++)
- {
- for(int j = 0; j < 4; j++)
- {
- skin_info.mBindShapeMatrix.mMatrix[i][j] = dom_value[i + j*4];
- }
- }
-
- LLMatrix4 trans = normalized_transformation;
- trans *= skin_info.mBindShapeMatrix;
- skin_info.mBindShapeMatrix = trans;
- }
-
-
- //Some collada setup for accessing the skeleton
- daeElement* pElement = 0;
- dae.getDatabase()->getElement( &pElement, 0, 0, "skeleton" );
-
- //Try to get at the skeletal instance controller
- domInstance_controller::domSkeleton* pSkeleton = daeSafeCast<domInstance_controller::domSkeleton>( pElement );
- bool missingSkeletonOrScene = false;
-
- //If no skeleton, do a breadth-first search to get at specific joints
- bool rootNode = false;
-
- //Need to test for a skeleton that does not have a root node
- //This occurs when your instance controller does not have an associated scene
- if ( pSkeleton )
- {
- daeElement* pSkeletonRootNode = pSkeleton->getValue().getElement();
- if ( pSkeletonRootNode )
- {
- rootNode = true;
- }
-
- }
- if ( !pSkeleton || !rootNode )
- {
- daeElement* pScene = root->getDescendant("visual_scene");
- if ( !pScene )
- {
- LL_WARNS()<<"No visual scene - unable to parse bone offsets "<<LL_ENDL;
- missingSkeletonOrScene = true;
- }
- else
- {
- //Get the children at this level
- daeTArray< daeSmartRef<daeElement> > children = pScene->getChildren();
- S32 childCount = children.getCount();
-
- //Process any children that are joints
- //Not all children are joints, some code be ambient lights, cameras, geometry etc..
- for (S32 i = 0; i < childCount; ++i)
- {
- domNode* pNode = daeSafeCast<domNode>(children[i]);
- if ( isNodeAJoint( pNode ) )
- {
- processJointNode( pNode, mJointList );
- }
- }
- }
- }
- else
- //Has Skeleton
- {
- //Get the root node of the skeleton
- daeElement* pSkeletonRootNode = pSkeleton->getValue().getElement();
- if ( pSkeletonRootNode )
- {
- //Once we have the root node - start acccessing it's joint components
- const int jointCnt = mJointMap.size();
- std::map<std::string, std::string> :: const_iterator jointIt = mJointMap.begin();
-
- //Loop over all the possible joints within the .dae - using the allowed joint list in the ctor.
- for ( int i=0; i<jointCnt; ++i, ++jointIt )
- {
- //Build a joint for the resolver to work with
- char str[64]={0};
- sprintf(str,"./%s",(*jointIt).first.c_str() );
- //LL_WARNS()<<"Joint "<< str <<LL_ENDL;
-
- //Setup the resolver
- daeSIDResolver resolver( pSkeletonRootNode, str );
-
- //Look for the joint
- domNode* pJoint = daeSafeCast<domNode>( resolver.getElement() );
- if ( pJoint )
- {
- //Pull out the translate id and store it in the jointTranslations map
- daeSIDResolver jointResolverA( pJoint, "./translate" );
- domTranslate* pTranslateA = daeSafeCast<domTranslate>( jointResolverA.getElement() );
- daeSIDResolver jointResolverB( pJoint, "./location" );
- domTranslate* pTranslateB = daeSafeCast<domTranslate>( jointResolverB.getElement() );
-
- LLMatrix4 workingTransform;
-
- //Translation via SID
- if ( pTranslateA )
- {
- extractTranslation( pTranslateA, workingTransform );
- }
- else
- if ( pTranslateB )
- {
- extractTranslation( pTranslateB, workingTransform );
- }
- else
- {
- //Translation via child from element
- daeElement* pTranslateElement = getChildFromElement( pJoint, "translate" );
- if ( pTranslateElement && pTranslateElement->typeID() != domTranslate::ID() )
- {
- LL_WARNS()<< "The found element is not a translate node" <<LL_ENDL;
- missingSkeletonOrScene = true;
- }
- else
- if ( pTranslateElement )
- {
- extractTranslationViaElement( pTranslateElement, workingTransform );
- }
- else
- {
- extractTranslationViaSID( pJoint, workingTransform );
- }
-
- }
-
- //Store the joint transform w/respect to it's name.
- mJointList[(*jointIt).second.c_str()] = workingTransform;
- }
- }
-
- //If anything failed in regards to extracting the skeleton, joints or translation id,
- //mention it
- if ( missingSkeletonOrScene )
- {
- LL_WARNS()<< "Partial jointmap found in asset - did you mean to just have a partial map?" << LL_ENDL;
- }
- }//got skeleton?
- }
-
-
- domSkin::domJoints* joints = skin->getJoints();
-
- domInputLocal_Array& joint_input = joints->getInput_array();
-
- for (size_t i = 0; i < joint_input.getCount(); ++i)
- {
- domInputLocal* input = joint_input.get(i);
- xsNMTOKEN semantic = input->getSemantic();
-
- if (strcmp(semantic, COMMON_PROFILE_INPUT_JOINT) == 0)
- { //found joint source, fill model->mJointMap and model->mSkinInfo.mJointNames
- daeElement* elem = input->getSource().getElement();
-
- domSource* source = daeSafeCast<domSource>(elem);
- if (source)
- {
-
-
- domName_array* names_source = source->getName_array();
-
- if (names_source)
- {
- domListOfNames &names = names_source->getValue();
-
- for (size_t j = 0; j < names.getCount(); ++j)
- {
- std::string name(names.get(j));
- if (mJointMap.find(name) != mJointMap.end())
- {
- name = mJointMap[name];
- }
- model->mSkinInfo.mJointNames.push_back(name);
- model->mSkinInfo.mJointMap[name] = j;
- }
- }
- else
- {
- domIDREF_array* names_source = source->getIDREF_array();
- if (names_source)
- {
- xsIDREFS& names = names_source->getValue();
-
- for (size_t j = 0; j < names.getCount(); ++j)
- {
- std::string name(names.get(j).getID());
- if (mJointMap.find(name) != mJointMap.end())
- {
- name = mJointMap[name];
- }
- model->mSkinInfo.mJointNames.push_back(name);
- model->mSkinInfo.mJointMap[name] = j;
- }
- }
- }
- }
- }
- else if (strcmp(semantic, COMMON_PROFILE_INPUT_INV_BIND_MATRIX) == 0)
- { //found inv_bind_matrix array, fill model->mInvBindMatrix
- domSource* source = daeSafeCast<domSource>(input->getSource().getElement());
- if (source)
- {
- domFloat_array* t = source->getFloat_array();
- if (t)
- {
- domListOfFloats& transform = t->getValue();
- S32 count = transform.getCount()/16;
-
- for (S32 k = 0; k < count; ++k)
- {
- LLMatrix4 mat;
-
- for (int i = 0; i < 4; i++)
- {
- for(int j = 0; j < 4; j++)
- {
- mat.mMatrix[i][j] = transform[k*16 + i + j*4];
- }
- }
-
- model->mSkinInfo.mInvBindMatrix.push_back(mat);
- }
- }
- }
- }
- }
-
- //Now that we've parsed the joint array, let's determine if we have a full rig
- //(which means we have all the joint sthat are required for an avatar versus
- //a skinned asset attached to a node in a file that contains an entire skeleton,
- //but does not use the skeleton).
- buildJointToNodeMappingFromScene( root );
- mPreview->critiqueRigForUploadApplicability( model->mSkinInfo.mJointNames );
-
- if ( !missingSkeletonOrScene )
- {
- //Set the joint translations on the avatar - if it's a full mapping
- //The joints are reset in the dtor
- if ( mPreview->getRigWithSceneParity() )
- {
- std::map<std::string, std::string> :: const_iterator masterJointIt = mJointMap.begin();
- std::map<std::string, std::string> :: const_iterator masterJointItEnd = mJointMap.end();
- for (;masterJointIt!=masterJointItEnd;++masterJointIt )
- {
- std::string lookingForJoint = (*masterJointIt).first.c_str();
-
- if ( mJointList.find( lookingForJoint ) != mJointList.end() )
- {
- //LL_INFOS()<<"joint "<<lookingForJoint.c_str()<<LL_ENDL;
- LLMatrix4 jointTransform = mJointList[lookingForJoint];
- LLJoint* pJoint = mPreview->getPreviewAvatar()->getJoint( lookingForJoint );
- if ( pJoint )
- {
- LLUUID fake_mesh_id;
- fake_mesh_id.generate();
- pJoint->addAttachmentPosOverride( jointTransform.getTranslation(), fake_mesh_id, gAgentAvatarp->avString());
- }
- else
- {
- //Most likely an error in the asset.
- LL_WARNS()<<"Tried to apply joint position from .dae, but it did not exist in the avatar rig." << LL_ENDL;
- }
- }
- }
- }
- } //missingSkeletonOrScene
-
-
- //We need to construct the alternate bind matrix (which contains the new joint positions)
- //in the same order as they were stored in the joint buffer. The joints associated
- //with the skeleton are not stored in the same order as they are in the exported joint buffer.
- //This remaps the skeletal joints to be in the same order as the joints stored in the model.
- std::vector<std::string> :: const_iterator jointIt = model->mSkinInfo.mJointNames.begin();
- const int jointCnt = model->mSkinInfo.mJointNames.size();
- for ( int i=0; i<jointCnt; ++i, ++jointIt )
- {
- std::string lookingForJoint = (*jointIt).c_str();
- //Look for the joint xform that we extracted from the skeleton, using the jointIt as the key
- //and store it in the alternate bind matrix
- if ( mJointList.find( lookingForJoint ) != mJointList.end() )
- {
- LLMatrix4 jointTransform = mJointList[lookingForJoint];
- LLMatrix4 newInverse = model->mSkinInfo.mInvBindMatrix[i];
- newInverse.setTranslation( mJointList[lookingForJoint].getTranslation() );
- model->mSkinInfo.mAlternateBindMatrix.push_back( newInverse );
- }
- else
- {
- LL_WARNS()<<"Possibly misnamed/missing joint [" <<lookingForJoint.c_str()<<" ] "<<LL_ENDL;
- }
- }
-
- //grab raw position array
-
- domVertices* verts = mesh->getVertices();
- if (verts)
- {
- domInputLocal_Array& inputs = verts->getInput_array();
- for (size_t i = 0; i < inputs.getCount() && model->mPosition.empty(); ++i)
- {
- if (strcmp(inputs[i]->getSemantic(), COMMON_PROFILE_INPUT_POSITION) == 0)
- {
- domSource* pos_source = daeSafeCast<domSource>(inputs[i]->getSource().getElement());
- if (pos_source)
- {
- domFloat_array* pos_array = pos_source->getFloat_array();
- if (pos_array)
- {
- domListOfFloats& pos = pos_array->getValue();
-
- for (size_t j = 0; j < pos.getCount(); j += 3)
- {
- if (pos.getCount() <= j+2)
- {
- LL_ERRS() << "Invalid position array size." << LL_ENDL;
- }
-
- LLVector3 v(pos[j], pos[j+1], pos[j+2]);
-
- //transform from COLLADA space to volume space
- v = v * inverse_normalized_transformation;
-
- model->mPosition.push_back(v);
- }
- }
- }
- }
- }
- }
-
- //grab skin weights array
- domSkin::domVertex_weights* weights = skin->getVertex_weights();
- if (weights)
- {
- domInputLocalOffset_Array& inputs = weights->getInput_array();
- domFloat_array* vertex_weights = NULL;
- for (size_t i = 0; i < inputs.getCount(); ++i)
- {
- if (strcmp(inputs[i]->getSemantic(), COMMON_PROFILE_INPUT_WEIGHT) == 0)
- {
- domSource* weight_source = daeSafeCast<domSource>(inputs[i]->getSource().getElement());
- if (weight_source)
- {
- vertex_weights = weight_source->getFloat_array();
- }
- }
- }
-
- if (vertex_weights)
- {
- domListOfFloats& w = vertex_weights->getValue();
- domListOfUInts& vcount = weights->getVcount()->getValue();
- domListOfInts& v = weights->getV()->getValue();
-
- U32 c_idx = 0;
- for (size_t vc_idx = 0; vc_idx < vcount.getCount(); ++vc_idx)
- { //for each vertex
- daeUInt count = vcount[vc_idx];
-
- //create list of weights that influence this vertex
- LLModel::weight_list weight_list;
-
- for (daeUInt i = 0; i < count; ++i)
- { //for each weight
- daeInt joint_idx = v[c_idx++];
- daeInt weight_idx = v[c_idx++];
-
- if (joint_idx == -1)
- {
- //ignore bindings to bind_shape_matrix
- continue;
- }
-
- F32 weight_value = w[weight_idx];
-
- weight_list.push_back(LLModel::JointWeight(joint_idx, weight_value));
- }
-
- //sort by joint weight
- std::sort(weight_list.begin(), weight_list.end(), LLModel::CompareWeightGreater());
-
- std::vector<LLModel::JointWeight> wght;
-
- F32 total = 0.f;
-
- for (U32 i = 0; i < llmin((U32) 4, (U32) weight_list.size()); ++i)
- { //take up to 4 most significant weights
- if (weight_list[i].mWeight > 0.f)
- {
- wght.push_back( weight_list[i] );
- total += weight_list[i].mWeight;
- }
- }
-
- F32 scale = 1.f/total;
- if (scale != 1.f)
- { //normalize weights
- for (U32 i = 0; i < wght.size(); ++i)
- {
- wght[i].mWeight *= scale;
- }
- }
-
- model->mSkinWeights[model->mPosition[vc_idx]] = wght;
- }
-
- //add instance to scene for this model
-
- LLMatrix4 transformation = mTransform;
- // adjust the transformation to compensate for mesh normalization
-
- LLMatrix4 mesh_translation;
- mesh_translation.setTranslation(mesh_translation_vector);
- mesh_translation *= transformation;
- transformation = mesh_translation;
-
- LLMatrix4 mesh_scale;
- mesh_scale.initScale(mesh_scale_vector);
- mesh_scale *= transformation;
- transformation = mesh_scale;
-
- std::map<std::string, LLImportMaterial> materials;
- for (U32 i = 0; i < model->mMaterialList.size(); ++i)
- {
- materials[model->mMaterialList[i]] = LLImportMaterial();
- }
- mScene[transformation].push_back(LLModelInstance(model, model->mLabel, transformation, materials));
- stretch_extents(model, transformation, mExtents[0], mExtents[1], mFirstTransform);
- }
- }
- }
- }
- }
- }
- }
-
- daeElement* scene = root->getDescendant("visual_scene");
-
- if (!scene)
- {
- LL_WARNS() << "document has no visual_scene" << LL_ENDL;
- setLoadState( ERROR_PARSING );
- return true;
- }
-
- setLoadState( DONE );
-
- bool badElement = false;
-
- processElement( scene, badElement );
-
- if ( badElement )
- {
- setLoadState( ERROR_PARSING );
- }
-
- return true;
-}
-
-void LLModelLoader::setLoadState(U32 state)
-{
- if (mPreview)
- {
- mPreview->setLoadState(state);
- }
-}
-
-bool LLModelLoader::loadFromSLM(const std::string& filename)
-{
- //only need to populate mScene with data from slm
- llstat stat;
-
- if (LLFile::stat(filename, &stat))
- { //file does not exist
- return false;
- }
-
- S32 file_size = (S32) stat.st_size;
-
- llifstream ifstream(filename.c_str(), std::ifstream::in | std::ifstream::binary);
- LLSD data;
- LLSDSerialize::fromBinary(data, ifstream, file_size);
- ifstream.close();
-
- //build model list for each LoD
- model_list model[LLModel::NUM_LODS];
-
- if (data["version"].asInteger() != SLM_SUPPORTED_VERSION)
- { //unsupported version
- return false;
- }
-
- LLSD& mesh = data["mesh"];
-
- LLVolumeParams volume_params;
- volume_params.setType(LL_PCODE_PROFILE_SQUARE, LL_PCODE_PATH_LINE);
-
- for (S32 lod = 0; lod < LLModel::NUM_LODS; ++lod)
- {
- for (U32 i = 0; i < mesh.size(); ++i)
- {
- std::stringstream str(mesh[i].asString());
- LLPointer<LLModel> loaded_model = new LLModel(volume_params, (F32) lod);
- if (loaded_model->loadModel(str))
- {
- loaded_model->mLocalID = i;
- model[lod].push_back(loaded_model);
-
- if (lod == LLModel::LOD_HIGH && !loaded_model->mSkinInfo.mJointNames.empty())
- {
- //check to see if rig is valid
- mPreview->critiqueRigForUploadApplicability( loaded_model->mSkinInfo.mJointNames );
- }
- }
- }
- }
-
- if (model[LLModel::LOD_HIGH].empty())
- { //failed to load high lod
- return false;
- }
-
- // Set name.
- std::string name = data["name"];
- if (!name.empty())
- {
- model[LLModel::LOD_HIGH][0]->mLabel = name;
- }
-
-
- //load instance list
- model_instance_list instance_list;
-
- LLSD& instance = data["instance"];
-
- for (U32 i = 0; i < instance.size(); ++i)
- {
- //deserialize instance list
- instance_list.push_back(LLModelInstance(instance[i]));
-
- //match up model instance pointers
- S32 idx = instance_list[i].mLocalMeshID;
-
- for (U32 lod = 0; lod < LLModel::NUM_LODS; ++lod)
- {
- if (!model[lod].empty())
- {
- instance_list[i].mLOD[lod] = model[lod][idx];
- }
- }
-
- instance_list[i].mModel = model[LLModel::LOD_HIGH][idx];
- }
-
-
- //convert instance_list to mScene
- mFirstTransform = TRUE;
- for (U32 i = 0; i < instance_list.size(); ++i)
- {
- LLModelInstance& cur_instance = instance_list[i];
- mScene[cur_instance.mTransform].push_back(cur_instance);
- stretch_extents(cur_instance.mModel, cur_instance.mTransform, mExtents[0], mExtents[1], mFirstTransform);
- }
-
- setLoadState( DONE );
-
- return true;
-}
-
-//static
-bool LLModelLoader::isAlive(LLModelLoader* loader)
-{
- if(!loader)
- {
- return false ;
- }
-
- std::list<LLModelLoader*>::iterator iter = sActiveLoaderList.begin() ;
- for(; iter != sActiveLoaderList.end() && (*iter) != loader; ++iter) ;
-
- return *iter == loader ;
-}
-
-void LLModelLoader::loadModelCallback()
-{
- assert_main_thread();
-
- if (mPreview)
- {
- mPreview->loadModelCallback(mLod);
- }
-
- while (!isStopped())
- { //wait until this thread is stopped before deleting self
- apr_sleep(100);
- }
-
- //doubel check if "this" is valid before deleting it, in case it is aborted during running.
- if(!isAlive(this))
- {
- return ;
- }
-
- //cleanup model loader
- if (mPreview)
- {
- mPreview->mModelLoader = NULL;
- }
-
- delete this;
-}
-//-----------------------------------------------------------------------------
-// buildJointToNodeMappingFromScene()
-//-----------------------------------------------------------------------------
-void LLModelLoader::buildJointToNodeMappingFromScene( daeElement* pRoot )
-{
- daeElement* pScene = pRoot->getDescendant("visual_scene");
- if ( pScene )
- {
- daeTArray< daeSmartRef<daeElement> > children = pScene->getChildren();
- S32 childCount = children.getCount();
- for (S32 i = 0; i < childCount; ++i)
- {
- domNode* pNode = daeSafeCast<domNode>(children[i]);
- processJointToNodeMapping( pNode );
- }
- }
-}
-//-----------------------------------------------------------------------------
-// processJointToNodeMapping()
-//-----------------------------------------------------------------------------
-void LLModelLoader::processJointToNodeMapping( domNode* pNode )
-{
- if ( isNodeAJoint( pNode ) )
- {
- //1.Store the parent
- std::string nodeName = pNode->getName();
- if ( !nodeName.empty() )
- {
- mJointsFromNode.push_front( pNode->getName() );
- }
- //2. Handle the kiddo's
- processChildJoints( pNode );
- }
- else
- {
- //Determine if the're any children wrt to this failed node.
- //This occurs when an armature is exported and ends up being what essentially amounts to
- //as the root for the visual_scene
- if ( pNode )
- {
- processChildJoints( pNode );
- }
- else
- {
- LL_INFOS()<<"Node is NULL"<<LL_ENDL;
- }
-
- }
-}
-//-----------------------------------------------------------------------------
-// processChildJoint()
-//-----------------------------------------------------------------------------
-void LLModelLoader::processChildJoints( domNode* pParentNode )
-{
- daeTArray< daeSmartRef<daeElement> > childOfChild = pParentNode->getChildren();
- S32 childOfChildCount = childOfChild.getCount();
- for (S32 i = 0; i < childOfChildCount; ++i)
- {
- domNode* pChildNode = daeSafeCast<domNode>( childOfChild[i] );
- if ( pChildNode )
- {
- processJointToNodeMapping( pChildNode );
- }
- }
-}
-
-//-----------------------------------------------------------------------------
-// critiqueRigForUploadApplicability()
-//-----------------------------------------------------------------------------
-void LLModelPreview::critiqueRigForUploadApplicability( const std::vector<std::string> &jointListFromAsset )
-{
- critiqueJointToNodeMappingFromScene();
-
- //Determines the following use cases for a rig:
- //1. It is suitable for upload with skin weights & joint positions, or
- //2. It is suitable for upload as standard av with just skin weights
-
- bool isJointPositionUploadOK = isRigSuitableForJointPositionUpload( jointListFromAsset );
- bool isRigLegacyOK = isRigLegacy( jointListFromAsset );
-
- //It's OK that both could end up being true, both default to false
- if ( isJointPositionUploadOK )
- {
- setRigValidForJointPositionUpload( true );
- }
-
- if ( isRigLegacyOK)
- {
- setLegacyRigValid( true );
- }
-
-}
-//-----------------------------------------------------------------------------
-// critiqueJointToNodeMappingFromScene()
-//-----------------------------------------------------------------------------
-void LLModelPreview::critiqueJointToNodeMappingFromScene( void )
-{
- //Do the actual nodes back the joint listing from the dae?
- //if yes then this is a fully rigged asset, otherwise it's just a partial rig
-
- std::deque<std::string>::iterator jointsFromNodeIt = mJointsFromNode.begin();
- std::deque<std::string>::iterator jointsFromNodeEndIt = mJointsFromNode.end();
- bool result = true;
-
- if ( !mJointsFromNode.empty() )
- {
- for ( ;jointsFromNodeIt!=jointsFromNodeEndIt;++jointsFromNodeIt )
- {
- std::string name = *jointsFromNodeIt;
- if ( mJointTransformMap.find( name ) != mJointTransformMap.end() )
- {
- continue;
- }
- else
- {
- LL_INFOS()<<"critiqueJointToNodeMappingFromScene is missing a: "<<name<<LL_ENDL;
- result = false;
- }
- }
- }
- else
- {
- result = false;
- }
-
- //Determines the following use cases for a rig:
- //1. Full av rig w/1-1 mapping from the scene and joint array
- //2. Partial rig but w/o parity between the scene and joint array
- if ( result )
- {
- setRigWithSceneParity( true );
- }
-}
-//-----------------------------------------------------------------------------
-// isRigLegacy()
-//-----------------------------------------------------------------------------
-bool LLModelPreview::isRigLegacy( const std::vector<std::string> &jointListFromAsset )
-{
- //No joints in asset
- if ( jointListFromAsset.size() == 0 )
- {
- return false;
- }
-
- bool result = false;
-
- std::deque<std::string> :: const_iterator masterJointIt = mMasterLegacyJointList.begin();
- std::deque<std::string> :: const_iterator masterJointEndIt = mMasterLegacyJointList.end();
-
- std::vector<std::string> :: const_iterator modelJointIt = jointListFromAsset.begin();
- std::vector<std::string> :: const_iterator modelJointItEnd = jointListFromAsset.end();
-
- for ( ;masterJointIt!=masterJointEndIt;++masterJointIt )
- {
- result = false;
- modelJointIt = jointListFromAsset.begin();
-
- for ( ;modelJointIt!=modelJointItEnd; ++modelJointIt )
- {
- if ( *masterJointIt == *modelJointIt )
- {
- result = true;
- break;
- }
- }
- if ( !result )
- {
- LL_INFOS()<<" Asset did not contain the joint (if you're u/l a fully rigged asset w/joint positions - it is required)." << *masterJointIt<< LL_ENDL;
- break;
- }
- }
- return result;
-}
-//-----------------------------------------------------------------------------
-// isRigSuitableForJointPositionUpload()
-//-----------------------------------------------------------------------------
-bool LLModelPreview::isRigSuitableForJointPositionUpload( const std::vector<std::string> &jointListFromAsset )
-{
- bool result = false;
-
- std::deque<std::string> :: const_iterator masterJointIt = mMasterJointList.begin();
- std::deque<std::string> :: const_iterator masterJointEndIt = mMasterJointList.end();
-
- std::vector<std::string> :: const_iterator modelJointIt = jointListFromAsset.begin();
- std::vector<std::string> :: const_iterator modelJointItEnd = jointListFromAsset.end();
-
- for ( ;masterJointIt!=masterJointEndIt;++masterJointIt )
- {
- result = false;
- modelJointIt = jointListFromAsset.begin();
-
- for ( ;modelJointIt!=modelJointItEnd; ++modelJointIt )
- {
- if ( *masterJointIt == *modelJointIt )
- {
- result = true;
- break;
- }
- }
- if ( !result )
- {
- LL_INFOS()<<" Asset did not contain the joint (if you're u/l a fully rigged asset w/joint positions - it is required)." << *masterJointIt<< LL_ENDL;
- break;
- }
- }
- return result;
-}
-
-
-//called in the main thread
-void LLModelLoader::loadTextures()
-{
- BOOL is_paused = isPaused() ;
- pause() ; //pause the loader
-
- for(scene::iterator iter = mScene.begin(); iter != mScene.end(); ++iter)
- {
- for(U32 i = 0 ; i < iter->second.size(); i++)
- {
- for(std::map<std::string, LLImportMaterial>::iterator j = iter->second[i].mMaterial.begin();
- j != iter->second[i].mMaterial.end(); ++j)
- {
- LLImportMaterial& material = j->second;
-
- if(!material.mDiffuseMapFilename.empty())
- {
- material.mDiffuseMap =
- LLViewerTextureManager::getFetchedTextureFromUrl("file://" + material.mDiffuseMapFilename, FTT_LOCAL_FILE, TRUE, LLGLTexture::BOOST_PREVIEW);
- material.mDiffuseMap->setLoadedCallback(LLModelPreview::textureLoadedCallback, 0, TRUE, FALSE, mPreview, NULL, FALSE);
- material.mDiffuseMap->forceToSaveRawImage(0, F32_MAX);
- mNumOfFetchingTextures++ ;
- }
- }
- }
- }
-
- if(!is_paused)
- {
- unpause() ;
- }
-}
-
-//-----------------------------------------------------------------------------
-// isNodeAJoint()
-//-----------------------------------------------------------------------------
-bool LLModelLoader::isNodeAJoint( domNode* pNode )
-{
- if ( !pNode )
- {
- LL_INFOS()<<"Created node is NULL"<<LL_ENDL;
- return false;
- }
-
- if ( pNode->getName() == NULL )
- {
- LL_INFOS()<<"Parsed node has no name "<<LL_ENDL;
- //Attempt to write the node id, if possible (aids in debugging the visual scene)
- if ( pNode->getId() )
- {
- LL_INFOS()<<"Parsed node ID: "<<pNode->getId()<<LL_ENDL;
- }
- return false;
- }
-
- if ( mJointMap.find( pNode->getName() ) != mJointMap.end() )
- {
- return true;
- }
-
- return false;
-}
-//-----------------------------------------------------------------------------
-// verifyCount
-//-----------------------------------------------------------------------------
-bool LLModelPreview::verifyCount( int expected, int result )
-{
- if ( expected != result )
- {
- LL_INFOS()<< "Error: (expected/got)"<<expected<<"/"<<result<<"verts"<<LL_ENDL;
- return false;
- }
- return true;
-}
-//-----------------------------------------------------------------------------
-// verifyController
-//-----------------------------------------------------------------------------
-bool LLModelPreview::verifyController( domController* pController )
-{
-
- bool result = true;
-
- domSkin* pSkin = pController->getSkin();
-
- if ( pSkin )
- {
- xsAnyURI & uri = pSkin->getSource();
- domElement* pElement = uri.getElement();
-
- if ( !pElement )
- {
- LL_INFOS()<<"Can't resolve skin source"<<LL_ENDL;
- return false;
- }
-
- daeString type_str = pElement->getTypeName();
- if ( stricmp(type_str, "geometry") == 0 )
- {
- //Skin is reference directly by geometry and get the vertex count from skin
- domSkin::domVertex_weights* pVertexWeights = pSkin->getVertex_weights();
- U32 vertexWeightsCount = pVertexWeights->getCount();
- domGeometry* pGeometry = (domGeometry*) (domElement*) uri.getElement();
- domMesh* pMesh = pGeometry->getMesh();
-
- if ( pMesh )
- {
- //Get vertex count from geometry
- domVertices* pVertices = pMesh->getVertices();
- if ( !pVertices )
- {
- LL_INFOS()<<"No vertices!"<<LL_ENDL;
- return false;
- }
-
- if ( pVertices )
- {
- xsAnyURI src = pVertices->getInput_array()[0]->getSource();
- domSource* pSource = (domSource*) (domElement*) src.getElement();
- U32 verticesCount = pSource->getTechnique_common()->getAccessor()->getCount();
- result = verifyCount( verticesCount, vertexWeightsCount );
- if ( !result )
- {
- return result;
- }
- }
- }
-
- U32 vcountCount = (U32) pVertexWeights->getVcount()->getValue().getCount();
- result = verifyCount( vcountCount, vertexWeightsCount );
- if ( !result )
- {
- return result;
- }
-
- domInputLocalOffset_Array& inputs = pVertexWeights->getInput_array();
- U32 sum = 0;
- for (size_t i=0; i<vcountCount; i++)
- {
- sum += pVertexWeights->getVcount()->getValue()[i];
- }
- result = verifyCount( sum * inputs.getCount(), (domInt) pVertexWeights->getV()->getValue().getCount() );
- }
- }
-
- return result;
-}
-
-//-----------------------------------------------------------------------------
-// extractTranslation()
-//-----------------------------------------------------------------------------
-void LLModelLoader::extractTranslation( domTranslate* pTranslate, LLMatrix4& transform )
-{
- domFloat3 jointTrans = pTranslate->getValue();
- LLVector3 singleJointTranslation( jointTrans[0], jointTrans[1], jointTrans[2] );
- transform.setTranslation( singleJointTranslation );
-}
-//-----------------------------------------------------------------------------
-// extractTranslationViaElement()
-//-----------------------------------------------------------------------------
-void LLModelLoader::extractTranslationViaElement( daeElement* pTranslateElement, LLMatrix4& transform )
-{
- if ( pTranslateElement )
- {
- domTranslate* pTranslateChild = dynamic_cast<domTranslate*>( pTranslateElement );
- domFloat3 translateChild = pTranslateChild->getValue();
- LLVector3 singleJointTranslation( translateChild[0], translateChild[1], translateChild[2] );
- transform.setTranslation( singleJointTranslation );
- }
-}
-//-----------------------------------------------------------------------------
-// extractTranslationViaSID()
-//-----------------------------------------------------------------------------
-void LLModelLoader::extractTranslationViaSID( daeElement* pElement, LLMatrix4& transform )
-{
- if ( pElement )
- {
- daeSIDResolver resolver( pElement, "./transform" );
- domMatrix* pMatrix = daeSafeCast<domMatrix>( resolver.getElement() );
- //We are only extracting out the translational component atm
- LLMatrix4 workingTransform;
- if ( pMatrix )
- {
- domFloat4x4 domArray = pMatrix->getValue();
- for ( int i = 0; i < 4; i++ )
- {
- for( int j = 0; j < 4; j++ )
- {
- workingTransform.mMatrix[i][j] = domArray[i + j*4];
- }
- }
- LLVector3 trans = workingTransform.getTranslation();
- transform.setTranslation( trans );
- }
- }
- else
- {
- LL_WARNS()<<"Element is nonexistent - empty/unsupported node."<<LL_ENDL;
- }
-}
-//-----------------------------------------------------------------------------
-// processJointNode()
-//-----------------------------------------------------------------------------
-void LLModelLoader::processJointNode( domNode* pNode, JointTransformMap& jointTransforms )
-{
- if (pNode->getName() == NULL)
- {
- LL_WARNS() << "nameless node, can't process" << LL_ENDL;
- return;
- }
-
- //LL_WARNS()<<"ProcessJointNode# Node:" <<pNode->getName()<<LL_ENDL;
-
- //1. handle the incoming node - extract out translation via SID or element
-
- LLMatrix4 workingTransform;
-
- //Pull out the translate id and store it in the jointTranslations map
- daeSIDResolver jointResolverA( pNode, "./translate" );
- domTranslate* pTranslateA = daeSafeCast<domTranslate>( jointResolverA.getElement() );
- daeSIDResolver jointResolverB( pNode, "./location" );
- domTranslate* pTranslateB = daeSafeCast<domTranslate>( jointResolverB.getElement() );
-
- //Translation via SID was successful
- if ( pTranslateA )
- {
- extractTranslation( pTranslateA, workingTransform );
- }
- else
- if ( pTranslateB )
- {
- extractTranslation( pTranslateB, workingTransform );
- }
- else
- {
- //Translation via child from element
- daeElement* pTranslateElement = getChildFromElement( pNode, "translate" );
- if ( !pTranslateElement || pTranslateElement->typeID() != domTranslate::ID() )
- {
- //LL_WARNS()<< "The found element is not a translate node" <<LL_ENDL;
- daeSIDResolver jointResolver( pNode, "./matrix" );
- domMatrix* pMatrix = daeSafeCast<domMatrix>( jointResolver.getElement() );
- if ( pMatrix )
- {
- //LL_INFOS()<<"A matrix SID was however found!"<<LL_ENDL;
- domFloat4x4 domArray = pMatrix->getValue();
- for ( int i = 0; i < 4; i++ )
- {
- for( int j = 0; j < 4; j++ )
- {
- workingTransform.mMatrix[i][j] = domArray[i + j*4];
- }
- }
- }
- else
- {
- LL_WARNS()<< "The found element is not translate or matrix node - most likely a corrupt export!" <<LL_ENDL;
- }
- }
- else
- {
- extractTranslationViaElement( pTranslateElement, workingTransform );
- }
- }
-
- //Store the working transform relative to the nodes name.
- jointTransforms[ pNode->getName() ] = workingTransform;
-
- //2. handle the nodes children
-
- //Gather and handle the incoming nodes children
- daeTArray< daeSmartRef<daeElement> > childOfChild = pNode->getChildren();
- S32 childOfChildCount = childOfChild.getCount();
-
- for (S32 i = 0; i < childOfChildCount; ++i)
- {
- domNode* pChildNode = daeSafeCast<domNode>( childOfChild[i] );
- if ( pChildNode )
- {
- processJointNode( pChildNode, jointTransforms );
- }
- }
-}
-//-----------------------------------------------------------------------------
-// getChildFromElement()
-//-----------------------------------------------------------------------------
-daeElement* LLModelLoader::getChildFromElement( daeElement* pElement, std::string const & name )
-{
- daeElement* pChildOfElement = pElement->getChild( name.c_str() );
- if ( pChildOfElement )
- {
- return pChildOfElement;
- }
- LL_WARNS()<< "Could not find a child [" << name << "] for the element: \"" << pElement->getAttribute("id") << "\"" << LL_ENDL;
- return NULL;
-}
-
-void LLModelLoader::processElement( daeElement* element, bool& badElement )
-{
- LLMatrix4 saved_transform = mTransform;
-
- domTranslate* translate = daeSafeCast<domTranslate>(element);
- if (translate)
- {
- domFloat3 dom_value = translate->getValue();
-
- LLMatrix4 translation;
- translation.setTranslation(LLVector3(dom_value[0], dom_value[1], dom_value[2]));
-
- translation *= mTransform;
- mTransform = translation;
- }
-
- domRotate* rotate = daeSafeCast<domRotate>(element);
- if (rotate)
- {
- domFloat4 dom_value = rotate->getValue();
-
- LLMatrix4 rotation;
- rotation.initRotTrans(dom_value[3] * DEG_TO_RAD, LLVector3(dom_value[0], dom_value[1], dom_value[2]), LLVector3(0, 0, 0));
-
- rotation *= mTransform;
- mTransform = rotation;
- }
-
- domScale* scale = daeSafeCast<domScale>(element);
- if (scale)
- {
- domFloat3 dom_value = scale->getValue();
-
-
- LLVector3 scale_vector = LLVector3(dom_value[0], dom_value[1], dom_value[2]);
- scale_vector.abs(); // Set all values positive, since we don't currently support mirrored meshes
- LLMatrix4 scaling;
- scaling.initScale(scale_vector);
-
- scaling *= mTransform;
- mTransform = scaling;
- }
-
- domMatrix* matrix = daeSafeCast<domMatrix>(element);
- if (matrix)
- {
- domFloat4x4 dom_value = matrix->getValue();
-
- LLMatrix4 matrix_transform;
-
- for (int i = 0; i < 4; i++)
- {
- for(int j = 0; j < 4; j++)
- {
- matrix_transform.mMatrix[i][j] = dom_value[i + j*4];
- }
- }
-
- matrix_transform *= mTransform;
- mTransform = matrix_transform;
- }
-
- domInstance_geometry* instance_geo = daeSafeCast<domInstance_geometry>(element);
- if (instance_geo)
- {
- domGeometry* geo = daeSafeCast<domGeometry>(instance_geo->getUrl().getElement());
- if (geo)
- {
- domMesh* mesh = daeSafeCast<domMesh>(geo->getDescendant(daeElement::matchType(domMesh::ID())));
- if (mesh)
- {
- LLModel* model = mModel[mesh];
- if (model)
- {
- LLMatrix4 transformation = mTransform;
-
- if (mTransform.determinant() < 0)
- { //negative scales are not supported
- LL_INFOS() << "Negative scale detected, unsupported transform. domInstance_geometry: " << LLModel::getElementLabel(instance_geo) << LL_ENDL;
- badElement = true;
- }
-
- std::map<std::string, LLImportMaterial> materials = getMaterials(model, instance_geo);
-
- // adjust the transformation to compensate for mesh normalization
- LLVector3 mesh_scale_vector;
- LLVector3 mesh_translation_vector;
- model->getNormalizedScaleTranslation(mesh_scale_vector, mesh_translation_vector);
-
- LLMatrix4 mesh_translation;
- mesh_translation.setTranslation(mesh_translation_vector);
- mesh_translation *= transformation;
- transformation = mesh_translation;
-
- LLMatrix4 mesh_scale;
- mesh_scale.initScale(mesh_scale_vector);
- mesh_scale *= transformation;
- transformation = mesh_scale;
-
- std::string label = getElementLabel(instance_geo);
- mScene[transformation].push_back(LLModelInstance(model, label, transformation, materials));
-
- stretch_extents(model, transformation, mExtents[0], mExtents[1], mFirstTransform);
- }
- }
- }
- else
- {
- LL_INFOS()<<"Unable to resolve geometry URL."<<LL_ENDL;
- badElement = true;
- }
-
- }
-
- domInstance_node* instance_node = daeSafeCast<domInstance_node>(element);
- if (instance_node)
- {
- daeElement* instance = instance_node->getUrl().getElement();
- if (instance)
- {
- processElement(instance,badElement);
- }
- }
-
- //process children
- daeTArray< daeSmartRef<daeElement> > children = element->getChildren();
- int childCount = children.getCount();
- for (S32 i = 0; i < childCount; i++)
- {
- processElement(children[i],badElement);
- }
-
- domNode* node = daeSafeCast<domNode>(element);
- if (node)
- { //this element was a node, restore transform before processiing siblings
- mTransform = saved_transform;
- }
-}
-
-std::map<std::string, LLImportMaterial> LLModelLoader::getMaterials(LLModel* model, domInstance_geometry* instance_geo)
-{
- std::map<std::string, LLImportMaterial> materials;
- for (int i = 0; i < model->mMaterialList.size(); i++)
- {
- LLImportMaterial import_material;
-
- domInstance_material* instance_mat = NULL;
-
- domBind_material::domTechnique_common* technique =
- daeSafeCast<domBind_material::domTechnique_common>(instance_geo->getDescendant(daeElement::matchType(domBind_material::domTechnique_common::ID())));
-
- if (technique)
- {
- daeTArray< daeSmartRef<domInstance_material> > inst_materials = technique->getChildrenByType<domInstance_material>();
- for (int j = 0; j < inst_materials.getCount(); j++)
- {
- std::string symbol(inst_materials[j]->getSymbol());
-
- if (symbol == model->mMaterialList[i]) // found the binding
- {
- instance_mat = inst_materials[j];
- }
- }
- }
-
- if (instance_mat)
- {
- domMaterial* material = daeSafeCast<domMaterial>(instance_mat->getTarget().getElement());
- if (material)
- {
- domInstance_effect* instance_effect =
- daeSafeCast<domInstance_effect>(material->getDescendant(daeElement::matchType(domInstance_effect::ID())));
- if (instance_effect)
- {
- domEffect* effect = daeSafeCast<domEffect>(instance_effect->getUrl().getElement());
- if (effect)
- {
- domProfile_COMMON* profile =
- daeSafeCast<domProfile_COMMON>(effect->getDescendant(daeElement::matchType(domProfile_COMMON::ID())));
- if (profile)
- {
- import_material = profileToMaterial(profile);
- }
- }
- }
- }
- }
-
- import_material.mBinding = model->mMaterialList[i];
- materials[model->mMaterialList[i]] = import_material;
- }
-
- return materials;
-}
-
-LLImportMaterial LLModelLoader::profileToMaterial(domProfile_COMMON* material)
-{
- LLImportMaterial mat;
- mat.mFullbright = FALSE;
-
- daeElement* diffuse = material->getDescendant("diffuse");
- if (diffuse)
- {
- domCommon_color_or_texture_type_complexType::domTexture* texture =
- daeSafeCast<domCommon_color_or_texture_type_complexType::domTexture>(diffuse->getDescendant("texture"));
- if (texture)
- {
- domCommon_newparam_type_Array newparams = material->getNewparam_array();
- for (S32 i = 0; i < newparams.getCount(); i++)
- {
- domFx_surface_common* surface = newparams[i]->getSurface();
- if (surface)
- {
- domFx_surface_init_common* init = surface->getFx_surface_init_common();
- if (init)
- {
- domFx_surface_init_from_common_Array init_from = init->getInit_from_array();
-
- if (init_from.getCount() > i)
- {
- domImage* image = daeSafeCast<domImage>(init_from[i]->getValue().getElement());
- if (image)
- {
- // we only support init_from now - embedded data will come later
- domImage::domInit_from* init = image->getInit_from();
- if (init)
- {
- mat.mDiffuseMapFilename = cdom::uriToNativePath(init->getValue().str());
- mat.mDiffuseMapLabel = getElementLabel(material);
- }
- }
- }
- }
- }
- }
- }
-
- domCommon_color_or_texture_type_complexType::domColor* color =
- daeSafeCast<domCommon_color_or_texture_type_complexType::domColor>(diffuse->getDescendant("color"));
- if (color)
- {
- domFx_color_common domfx_color = color->getValue();
- LLColor4 value = LLColor4(domfx_color[0], domfx_color[1], domfx_color[2], domfx_color[3]);
- mat.mDiffuseColor = value;
- }
- }
-
- daeElement* emission = material->getDescendant("emission");
- if (emission)
- {
- LLColor4 emission_color = getDaeColor(emission);
- if (((emission_color[0] + emission_color[1] + emission_color[2]) / 3.0) > 0.25)
- {
- mat.mFullbright = TRUE;
- }
- }
-
- return mat;
-}
-
-// try to get a decent label for this element
-std::string LLModelLoader::getElementLabel(daeElement *element)
-{
- // if we have a name attribute, use it
- std::string name = element->getAttribute("name");
- if (name.length())
- {
- return name;
- }
-
- // if we have an ID attribute, use it
- if (element->getID())
- {
- return std::string(element->getID());
- }
-
- // if we have a parent, use it
- daeElement* parent = element->getParent();
- if (parent)
- {
- // if parent has a name, use it
- std::string name = parent->getAttribute("name");
- if (name.length())
- {
- return name;
- }
-
- // if parent has an ID, use it
- if (parent->getID())
- {
- return std::string(parent->getID());
- }
- }
-
- // try to use our type
- daeString element_name = element->getElementName();
- if (element_name)
- {
- return std::string(element_name);
- }
-
- // if all else fails, use "object"
- return std::string("object");
-}
-
-LLColor4 LLModelLoader::getDaeColor(daeElement* element)
-{
- LLColor4 value;
- domCommon_color_or_texture_type_complexType::domColor* color =
- daeSafeCast<domCommon_color_or_texture_type_complexType::domColor>(element->getDescendant("color"));
- if (color)
- {
- domFx_color_common domfx_color = color->getValue();
- value = LLColor4(domfx_color[0], domfx_color[1], domfx_color[2], domfx_color[3]);
- }
-
- return value;
-}
-
-//-----------------------------------------------------------------------------
// LLModelPreview
//-----------------------------------------------------------------------------
@@ -3125,7 +1181,9 @@ LLModelPreview::LLModelPreview(S32 width, S32 height, LLFloater* fmp)
, mPelvisZOffset( 0.0f )
, mLegacyRigValid( false )
, mRigValidJointUpload( false )
+, mPhysicsSearchLOD( LLModel::LOD_PHYSICS )
, mResetJoints( false )
+, mModelNoErrors( true )
, mRigParityWithScene( false )
, mLastJointUpdate( false )
{
@@ -3170,51 +1228,20 @@ LLModelPreview::LLModelPreview(S32 width, S32 height, LLFloater* fmp)
glodInit();
- //move into joint mapper class
- //1. joints for joint offset verification
- mMasterJointList.push_front("mPelvis");
- mMasterJointList.push_front("mTorso");
- mMasterJointList.push_front("mChest");
- mMasterJointList.push_front("mNeck");
- mMasterJointList.push_front("mHead");
- mMasterJointList.push_front("mCollarLeft");
- mMasterJointList.push_front("mShoulderLeft");
- mMasterJointList.push_front("mElbowLeft");
- mMasterJointList.push_front("mWristLeft");
- mMasterJointList.push_front("mCollarRight");
- mMasterJointList.push_front("mShoulderRight");
- mMasterJointList.push_front("mElbowRight");
- mMasterJointList.push_front("mWristRight");
- mMasterJointList.push_front("mHipRight");
- mMasterJointList.push_front("mKneeRight");
- mMasterJointList.push_front("mFootRight");
- mMasterJointList.push_front("mHipLeft");
- mMasterJointList.push_front("mKneeLeft");
- mMasterJointList.push_front("mFootLeft");
- //2. legacy joint list - used to verify rigs that will not be using joint offsets
- mMasterLegacyJointList.push_front("mPelvis");
- mMasterLegacyJointList.push_front("mTorso");
- mMasterLegacyJointList.push_front("mChest");
- mMasterLegacyJointList.push_front("mNeck");
- mMasterLegacyJointList.push_front("mHead");
- mMasterLegacyJointList.push_front("mHipRight");
- mMasterLegacyJointList.push_front("mKneeRight");
- mMasterLegacyJointList.push_front("mFootRight");
- mMasterLegacyJointList.push_front("mHipLeft");
- mMasterLegacyJointList.push_front("mKneeLeft");
- mMasterLegacyJointList.push_front("mFootLeft");
-
createPreviewAvatar();
}
LLModelPreview::~LLModelPreview()
{
- if (mModelLoader)
- {
- mModelLoader->mPreview = NULL;
- mModelLoader = NULL;
- }
- //*HACK : *TODO : turn this back on when we understand why this crashes
+ // glod apparently has internal mem alignment issues that are angering
+ // the heap-check code in windows, these should be hunted down in that
+ // TP code, if possible
+ //
+ // kernel32.dll!HeapFree() + 0x14 bytes
+ // msvcr100.dll!free(void * pBlock) Line 51 C
+ // glod.dll!glodGetGroupParameteriv() + 0x119 bytes
+ // glod.dll!glodShutdown() + 0x77 bytes
+ //
//glodShutdown();
}
@@ -3284,7 +1311,9 @@ U32 LLModelPreview::calcResourceCost()
decomp,
mFMP->childGetValue("upload_skin").asBoolean(),
mFMP->childGetValue("upload_joints").asBoolean(),
- TRUE);
+ TRUE,
+ FALSE,
+ instance.mModel->mSubmodelID);
num_hulls += decomp.mHull.size();
for (U32 i = 0; i < decomp.mHull.size(); ++i)
@@ -3351,29 +1380,12 @@ void LLModelPreview::rebuildUploadData()
F32 max_scale = 0.f;
- //reorder materials to match mBaseModel
- for (U32 i = 0; i < LLModel::NUM_LODS-1; i++)
- {
- if (mBaseModel.size() == mModel[i].size())
- {
- for (U32 j = 0; j < mBaseModel.size(); ++j)
- {
-
- int refFaceCnt = 0;
- int modelFaceCnt = 0;
-
- if ( !mModel[i][j]->matchMaterialOrder(mBaseModel[j], refFaceCnt, modelFaceCnt ) )
- {
- setLoadState( LLModelLoader::ERROR_MATERIALS );
- mFMP->childDisable( "calculate_btn" );
- }
- }
- }
- }
+ BOOL importerDebug = gSavedSettings.getBOOL("ImporterDebug");
+ BOOL legacyMatching = gSavedSettings.getBOOL("ImporterLegacyMatching");
for (LLModelLoader::scene::iterator iter = mBaseScene.begin(); iter != mBaseScene.end(); ++iter)
{ //for each transform in scene
- LLMatrix4 mat = iter->first;
+ LLMatrix4 mat = iter->first;
// compute position
LLVector3 position = LLVector3(0, 0, 0) * mat;
@@ -3390,38 +1402,171 @@ void LLModelPreview::rebuildUploadData()
mat *= scale_mat;
- for (LLModelLoader::model_instance_list::iterator model_iter = iter->second.begin(); model_iter != iter->second.end(); ++model_iter)
- { //for each instance with said transform applied
- LLModelInstance instance = *model_iter;
+ for (LLModelLoader::model_instance_list::iterator model_iter = iter->second.begin(); model_iter != iter->second.end();)
+ { //for each instance with said transform applied
+ LLModelInstance instance = *model_iter++;
LLModel* base_model = instance.mModel;
- if (base_model)
+ if (base_model && !requested_name.empty())
{
base_model->mRequestedLabel = requested_name;
base_model->mMetric = metric;
}
- S32 idx = 0;
- for (idx = 0; idx < mBaseModel.size(); ++idx)
- { //find reference instance for this model
- if (mBaseModel[idx] == base_model)
+ for (int i = LLModel::NUM_LODS - 1; i >= LLModel::LOD_IMPOSTOR; i--)
+ {
+ LLModel* lod_model = NULL;
+ if (!legacyMatching)
{
- break;
+ // Fill LOD slots by finding matching meshes by label with name extensions
+ // in the appropriate scene for each LOD. This fixes all kinds of issues
+ // where the indexed method below fails in spectacular fashion.
+ // If you don't take the time to name your LOD and PHYS meshes
+ // with the name of their corresponding mesh in the HIGH LOD,
+ // then the indexed method will be attempted below.
+
+ LLMatrix4 transform;
+
+ std::string name_to_match = instance.mLabel;
+ llassert(!name_to_match.empty());
+
+ int extensionLOD;
+ if (i != LLModel::LOD_PHYSICS || mModel[LLModel::LOD_PHYSICS].empty())
+ {
+ extensionLOD = i;
+ }
+ else
+ {
+ //Physics can be inherited from other LODs or loaded, so we need to adjust what extension we are searching for
+ extensionLOD = mPhysicsSearchLOD;
+ }
+
+ std::string toAdd;
+ switch (extensionLOD)
+ {
+ case LLModel::LOD_IMPOSTOR: toAdd = "_LOD0"; break;
+ case LLModel::LOD_LOW: toAdd = "_LOD1"; break;
+ case LLModel::LOD_MEDIUM: toAdd = "_LOD2"; break;
+ case LLModel::LOD_PHYSICS: toAdd = "_PHYS"; break;
+ case LLModel::LOD_HIGH: break;
+ }
+
+ if (name_to_match.find(toAdd) == -1)
+ {
+ name_to_match += toAdd;
+ }
+
+ FindModel(mScene[i], name_to_match, lod_model, transform);
+
+ if (!lod_model && i != LLModel::LOD_PHYSICS)
+ {
+ if (importerDebug)
+ {
+ LL_INFOS() << "Search of" << name_to_match << " in LOD" << i << " list failed. Searching for alternative among LOD lists." << LL_ENDL;
+ }
+
+ int searchLOD = (i > LLModel::LOD_HIGH) ? LLModel::LOD_HIGH : i;
+ while ((searchLOD <= LLModel::LOD_HIGH) && !lod_model)
+ {
+ std::string name_to_match = instance.mLabel;
+ llassert(!name_to_match.empty());
+
+ std::string toAdd;
+ switch (searchLOD)
+ {
+ case LLModel::LOD_IMPOSTOR: toAdd = "_LOD0"; break;
+ case LLModel::LOD_LOW: toAdd = "_LOD1"; break;
+ case LLModel::LOD_MEDIUM: toAdd = "_LOD2"; break;
+ case LLModel::LOD_PHYSICS: toAdd = "_PHYS"; break;
+ case LLModel::LOD_HIGH: break;
+ }
+
+ if (name_to_match.find(toAdd) == -1)
+ {
+ name_to_match += toAdd;
+ }
+
+ // See if we can find an appropriately named model in LOD 'searchLOD'
+ //
+ FindModel(mScene[searchLOD], name_to_match, lod_model, transform);
+ searchLOD++;
+ }
+ }
}
- }
+ else
+ {
+ // Use old method of index-based association
+ U32 idx = 0;
+ for (idx = 0; idx < mBaseModel.size(); ++idx)
+ {
+ // find reference instance for this model
+ if (mBaseModel[idx] == base_model)
+ {
+ if (importerDebug)
+ {
+ LL_INFOS() << "Attempting to use model index " << idx << " for LOD " << i << " of " << instance.mLabel << LL_ENDL;
+ }
+ break;
+ }
+ }
- if(idx < mBaseModel.size())
- {
- for (U32 i = 0; i < LLModel::NUM_LODS; i++)
- { //fill LOD slots based on reference model index
+ // If the model list for the current LOD includes that index...
+ //
if (mModel[i].size() > idx)
{
- instance.mLOD[i] = mModel[i][idx];
+ // Assign that index from the model list for our LOD as the LOD model for this instance
+ //
+ lod_model = mModel[i][idx];
+ if (importerDebug)
+ {
+ LL_INFOS() << "Indexed match of model index " << idx << " at LOD " << i << " to model named " << lod_model->mLabel << LL_ENDL;
+ }
}
- else
+ else if (importerDebug)
+ {
+ LL_INFOS() << "List of models does not include index " << idx << LL_ENDL;
+ }
+ }
+
+ if (lod_model)
+ {
+ if (importerDebug)
+ {
+ if (i == LLModel::LOD_PHYSICS)
+ {
+ LL_INFOS() << "Assigning collision for " << instance.mLabel << " to match " << lod_model->mLabel << LL_ENDL;
+ }
+ else
+ {
+ LL_INFOS() << "Assigning LOD" << i << " for " << instance.mLabel << " to found match " << lod_model->mLabel << LL_ENDL;
+ }
+ }
+ instance.mLOD[i] = lod_model;
+ }
+ else if (importerDebug)
+ {
+ LL_INFOS() << "List of models does not include " << instance.mLabel << LL_ENDL;
+ }
+ }
+
+ LLModel* high_lod_model = instance.mLOD[LLModel::LOD_HIGH];
+ if (!high_lod_model)
+ {
+ setLoadState( LLModelLoader::ERROR_MATERIALS );
+ mFMP->childDisable( "calculate_btn" );
+ }
+ else
+ {
+ for (U32 i = 0; i < LLModel::NUM_LODS-1; i++)
+ {
+ int refFaceCnt = 0;
+ int modelFaceCnt = 0;
+ llassert(instance.mLOD[i]);
+ if (instance.mLOD[i] && !instance.mLOD[i]->matchMaterialOrder(high_lod_model, refFaceCnt, modelFaceCnt ) )
{
- instance.mLOD[i] = NULL;
+ setLoadState( LLModelLoader::ERROR_MATERIALS );
+ mFMP->childDisable( "calculate_btn" );
}
}
}
@@ -3430,6 +1575,34 @@ void LLModelPreview::rebuildUploadData()
}
}
+ for (U32 lod = 0; lod < LLModel::NUM_LODS-1; lod++)
+ {
+ // Search for models that are not included into upload data
+ // If we found any, that means something we loaded is not a sub-model.
+ for (U32 model_ind = 0; model_ind < mModel[lod].size(); ++model_ind)
+ {
+ bool found_model = false;
+ for (LLMeshUploadThread::instance_list::iterator iter = mUploadData.begin(); iter != mUploadData.end(); ++iter)
+ {
+ LLModelInstance& instance = *iter;
+ if (instance.mLOD[lod] == mModel[lod][model_ind])
+ {
+ found_model = true;
+ break;
+ }
+ }
+ if (!found_model && mModel[lod][model_ind] && !mModel[lod][model_ind]->mSubmodelID)
+ {
+ if (importerDebug)
+ {
+ LL_INFOS() << "Model " << mModel[lod][model_ind]->mLabel << " was not used - mismatching lod models." << LL_ENDL;
+ }
+ setLoadState( LLModelLoader::ERROR_MATERIALS );
+ mFMP->childDisable( "calculate_btn" );
+ }
+ }
+ }
+
F32 max_import_scale = (DEFAULT_MAX_PRIM_SCALE-0.1f)/max_scale;
F32 max_axis = llmax(mPreviewScale.mV[0], mPreviewScale.mV[1]);
@@ -3496,7 +1669,6 @@ void LLModelPreview::saveUploadData(const std::string& filename, bool save_skinw
meshes.insert(instance.mModel);
std::stringstream str;
-
LLModel::Decomposition& decomp =
instance.mLOD[LLModel::LOD_PHYSICS].notNull() ?
instance.mLOD[LLModel::LOD_PHYSICS]->mPhysics :
@@ -3509,8 +1681,8 @@ void LLModelPreview::saveUploadData(const std::string& filename, bool save_skinw
instance.mLOD[LLModel::LOD_LOW],
instance.mLOD[LLModel::LOD_IMPOSTOR],
decomp,
- save_skinweights, save_joint_positions, FALSE, TRUE);
-
+ save_skinweights, save_joint_positions,
+ FALSE, TRUE, instance.mModel->mSubmodelID);
data["mesh"][instance.mModel->mLocalID] = str.str();
}
@@ -3536,6 +1708,21 @@ void LLModelPreview::clearModel(S32 lod)
mScene[lod].clear();
}
+void LLModelPreview::getLegalJointNames(JointNameSet& legal_joint_names)
+{
+ // Get all standard skeleton joints from the preview avatar.
+ LLVOAvatar *av = getPreviewAvatar();
+ const LLVOAvatar::avatar_joint_list_t &skel = av->getSkeleton();
+ for (S32 i=0; i<skel.size(); i++)
+ {
+ LLAvatarJoint *joint = skel[i];
+ if (joint)
+ {
+ legal_joint_names.push_back(joint->getName());
+ }
+ }
+}
+
void LLModelPreview::loadModel(std::string filename, S32 lod, bool force_disable_slm)
{
assert_main_thread();
@@ -3578,13 +1765,33 @@ void LLModelPreview::loadModel(std::string filename, S32 lod, bool force_disable
clearGLODGroup();
}
- mModelLoader = new LLModelLoader(filename, lod, this, mJointTransformMap, mJointsFromNode );
+
+ JointNameSet legal_joint_names;
+ getLegalJointNames(legal_joint_names);
+
+ mModelLoader = new LLDAELoader(
+ filename,
+ lod,
+ &LLModelPreview::loadedCallback,
+ &LLModelPreview::lookupJointByName,
+ &LLModelPreview::loadTextures,
+ &LLModelPreview::stateChangedCallback,
+ this,
+ mJointTransformMap,
+ mJointsFromNode,
+ legal_joint_names,
+ gSavedSettings.getU32("ImporterModelLimit"));
if (force_disable_slm)
{
mModelLoader->mTrySLM = false;
}
-
+ else
+ {
+ //only try to load from slm if viewer is configured to do so and this is the
+ //initial model load (not an LoD or physics shape)
+ mModelLoader->mTrySLM = gSavedSettings.getBOOL("MeshImportUseSLM") && mUploadData.empty();
+ }
mModelLoader->start();
mFMP->childSetTextArg("status", "[STATUS]", mFMP->getString("status_reading_file"));
@@ -3615,6 +1822,7 @@ void LLModelPreview::setPhysicsFromLOD(S32 lod)
if (lod >= 0 && lod <= 3)
{
+ mPhysicsSearchLOD = lod;
mModel[LLModel::LOD_PHYSICS] = mModel[lod];
mScene[LLModel::LOD_PHYSICS] = mScene[lod];
mLODFile[LLModel::LOD_PHYSICS].clear();
@@ -3634,11 +1842,14 @@ void LLModelPreview::clearIncompatible(S32 lod)
return;
}
+ // at this point we don't care about sub-models,
+ // different amount of sub-models means face count mismatch, not incompatibility
+ U32 lod_size = countRootModels(mModel[lod]);
for (U32 i = 0; i <= LLModel::LOD_HIGH; i++)
{ //clear out any entries that aren't compatible with this model
if (i != lod)
{
- if (mModel[i].size() != mModel[lod].size())
+ if (countRootModels(mModel[i]) != lod_size)
{
mModel[i].clear();
mScene[i].clear();
@@ -3673,7 +1884,7 @@ void LLModelPreview::clearGLODGroup()
}
}
-void LLModelPreview::loadModelCallback(S32 lod)
+void LLModelPreview::loadModelCallback(S32 loaded_lod)
{
assert_main_thread();
@@ -3686,12 +1897,18 @@ void LLModelPreview::loadModelCallback(S32 lod)
if(getLoadState() >= LLModelLoader::ERROR_PARSING)
{
mLoading = false ;
+ mModelLoader = NULL;
return ;
}
+ // Copy determinations about rig so UI will reflect them
+ //
+ setRigValidForJointPositionUpload(mModelLoader->isRigValidForJointPositionUpload());
+ setLegacyRigValid(mModelLoader->isLegacyRigValid());
+
mModelLoader->loadTextures() ;
- if (lod == -1)
+ if (loaded_lod == -1)
{ //populate all LoDs from model loader scene
mBaseModel.clear();
mBaseScene.clear();
@@ -3723,6 +1940,11 @@ void LLModelPreview::loadModelCallback(S32 lod)
//override displayed model with current LoD
list_iter->mModel = list_iter->mLOD[lod];
+ if (!list_iter->mModel)
+ {
+ continue;
+ }
+
//add current model to current LoD's model list (LLModel::mLocalID makes a good vector index)
S32 idx = list_iter->mModel->mLocalID;
@@ -3731,7 +1953,7 @@ void LLModelPreview::loadModelCallback(S32 lod)
mModel[lod].resize(idx+1);
}
- mModel[lod][idx] = list_iter->mModel;
+ mModel[lod][idx] = list_iter->mModel;
if (!list_iter->mModel->mSkinWeights.empty())
{
skin_weights = true;
@@ -3774,31 +1996,108 @@ void LLModelPreview::loadModelCallback(S32 lod)
}
else
{ //only replace given LoD
- mModel[lod] = mModelLoader->mModelList;
- mScene[lod] = mModelLoader->mScene;
- mVertexBuffer[lod].clear();
+ mModel[loaded_lod] = mModelLoader->mModelList;
+ mScene[loaded_lod] = mModelLoader->mScene;
+ mVertexBuffer[loaded_lod].clear();
- setPreviewLOD(lod);
+ setPreviewLOD(loaded_lod);
- if (lod == LLModel::LOD_HIGH)
+ if (loaded_lod == LLModel::LOD_HIGH)
{ //save a copy of the highest LOD for automatic LOD manipulation
if (mBaseModel.empty())
{ //first time we've loaded a model, auto-gen LoD
mGenLOD = true;
}
- mBaseModel = mModel[lod];
+ mBaseModel = mModel[loaded_lod];
clearGLODGroup();
- mBaseScene = mScene[lod];
+ mBaseScene = mScene[loaded_lod];
mVertexBuffer[5].clear();
}
+ else
+ {
+ BOOL importerDebug = gSavedSettings.getBOOL("ImporterDebug");
+ BOOL legacyMatching = gSavedSettings.getBOOL("ImporterLegacyMatching");
+ if (!legacyMatching)
+ {
+ if (!mBaseModel.empty())
+ {
+ BOOL name_based = FALSE;
+ BOOL has_submodels = FALSE;
+ for (U32 idx = 0; idx < mBaseModel.size(); ++idx)
+ {
+ if (mBaseModel[idx]->mSubmodelID)
+ { // don't do index-based renaming when the base model has submodels
+ has_submodels = TRUE;
+ if (importerDebug)
+ {
+ LL_INFOS() << "High LOD has submodels" << LL_ENDL;
+ }
+ break;
+ }
+ }
+
+ for (U32 idx = 0; idx < mModel[loaded_lod].size(); ++idx)
+ {
+ std::string loaded_name = stripSuffix(mModel[loaded_lod][idx]->mLabel);
+
+ LLModel* found_model = NULL;
+ LLMatrix4 transform;
+ FindModel(mBaseScene, loaded_name, found_model, transform);
+ if (found_model)
+ { // don't rename correctly named models (even if they are placed in a wrong order)
+ name_based = TRUE;
+ }
+
+ if (mModel[loaded_lod][idx]->mSubmodelID)
+ { // don't rename the models when loaded LOD model has submodels
+ has_submodels = TRUE;
+ }
+ }
+
+ if (importerDebug)
+ {
+ LL_INFOS() << "Loaded LOD " << loaded_lod << ": correct names" << (name_based ? "" : "NOT ") << "found; submodels " << (has_submodels ? "" : "NOT ") << "found" << LL_ENDL;
+ }
+
+ if (!name_based && !has_submodels)
+ { // replace the name of the model loaded for any non-HIGH LOD to match the others (MAINT-5601)
+ // this actually works like "ImporterLegacyMatching" for this particular LOD
+ for (U32 idx = 0; idx < mModel[loaded_lod].size() && idx < mBaseModel.size(); ++idx)
+ {
+ std::string name = mBaseModel[idx]->mLabel;
+ std::string loaded_name = stripSuffix(mModel[loaded_lod][idx]->mLabel);
+
+ if (loaded_name != name)
+ {
+ switch (loaded_lod)
+ {
+ case LLModel::LOD_IMPOSTOR: name += "_LOD0"; break;
+ case LLModel::LOD_LOW: name += "_LOD1"; break;
+ case LLModel::LOD_MEDIUM: name += "_LOD2"; break;
+ case LLModel::LOD_PHYSICS: name += "_PHYS"; break;
+ case LLModel::LOD_HIGH: break;
+ }
+
+ if (importerDebug)
+ {
+ LL_WARNS() << "Loded model name " << mModel[loaded_lod][idx]->mLabel << " for LOD " << loaded_lod << " doesn't match the base model. Renaming to " << name << LL_ENDL;
+ }
+
+ mModel[loaded_lod][idx]->mLabel = name;
+ }
+ }
+ }
+ }
+ }
+ }
- clearIncompatible(lod);
+ clearIncompatible(loaded_lod);
mDirty = true;
- if (lod == LLModel::LOD_HIGH)
+ if (loaded_lod == LLModel::LOD_HIGH)
{
resetPreviewTarget();
}
@@ -3817,6 +2116,8 @@ void LLModelPreview::loadModelCallback(S32 lod)
refresh();
mModelLoadedSignal();
+
+ mModelLoader = NULL;
}
void LLModelPreview::resetPreviewTarget()
@@ -4165,6 +2466,20 @@ void LLModelPreview::genLODs(S32 which_lod, U32 decimation, bool enforce_tri_lim
volume_params.setType(LL_PCODE_PROFILE_SQUARE, LL_PCODE_PATH_LINE);
mModel[lod][mdl_idx] = new LLModel(volume_params, 0.f);
+ std::string name = base->mLabel;
+
+ switch (lod)
+ {
+ case LLModel::LOD_IMPOSTOR: name += "_LOD0"; break;
+ case LLModel::LOD_LOW: name += "_LOD1"; break;
+ case LLModel::LOD_MEDIUM: name += "_LOD2"; break;
+ case LLModel::LOD_PHYSICS: name += "_PHYS"; break;
+ case LLModel::LOD_HIGH: break;
+ }
+
+ mModel[lod][mdl_idx]->mLabel = name;
+ mModel[lod][mdl_idx]->mSubmodelID = base->mSubmodelID;
+
GLint* sizes = new GLint[patch_count*2];
glodGetObjectParameteriv(mObject[base], GLOD_PATCH_SIZES, sizes);
stop_gloderror();
@@ -4277,17 +2592,6 @@ void LLModelPreview::genLODs(S32 which_lod, U32 decimation, bool enforce_tri_lim
{
shader->bind();
}
-
- /*if (which_lod == -1 && mScene[LLModel::LOD_PHYSICS].empty())
- { //build physics scene
- mScene[LLModel::LOD_PHYSICS] = mScene[LLModel::LOD_LOW];
- mModel[LLModel::LOD_PHYSICS] = mModel[LLModel::LOD_LOW];
-
- for (U32 i = 1; i < mModel[LLModel::LOD_PHYSICS].size(); ++i)
- {
- mPhysicsQ.push(mModel[LLModel::LOD_PHYSICS][i]);
- }
- }*/
}
void LLModelPreview::updateStatusMessages()
@@ -4304,43 +2608,89 @@ void LLModelPreview::updateStatusMessages()
S32 total_verts[LLModel::NUM_LODS];
S32 total_submeshes[LLModel::NUM_LODS];
- for (S32 lod = 0; lod < LLModel::NUM_LODS; ++lod)
+ for (U32 i = 0; i < LLModel::NUM_LODS-1; i++)
+ {
+ total_tris[i] = 0;
+ total_verts[i] = 0;
+ total_submeshes[i] = 0;
+ }
+
+ for (LLMeshUploadThread::instance_list::iterator iter = mUploadData.begin(); iter != mUploadData.end(); ++iter)
{
- //initialize total for this lod to 0
- total_tris[lod] = total_verts[lod] = total_submeshes[lod] = 0;
+ LLModelInstance& instance = *iter;
- for (LLModelLoader::scene::iterator iter = mScene[lod].begin(), endIter = mScene[lod].end(); iter != endIter; ++iter)
+ LLModel* model_high_lod = instance.mLOD[LLModel::LOD_HIGH];
+ if (!model_high_lod)
{
- for (LLModelLoader::model_instance_list::iterator instance = iter->second.begin(), end_instance = iter->second.end(); instance != end_instance; ++instance)
- {
- LLModel* model = instance->mModel;
- if (model)
- {
- //for each model in the lod
- S32 cur_tris = 0;
- S32 cur_verts = 0;
- S32 cur_submeshes = model->getNumVolumeFaces();
+ setLoadState( LLModelLoader::ERROR_MATERIALS );
+ mFMP->childDisable( "calculate_btn" );
+ continue;
+ }
- for (S32 j = 0; j < cur_submeshes; ++j)
- { //for each submesh (face), add triangles and vertices to current total
- const LLVolumeFace& face = model->getVolumeFace(j);
- cur_tris += face.mNumIndices/3;
- cur_verts += face.mNumVertices;
- }
+ for (U32 i = 0; i < LLModel::NUM_LODS-1; i++)
+ {
+ LLModel* lod_model = instance.mLOD[i];
+ if (!lod_model)
+ {
+ setLoadState( LLModelLoader::ERROR_MATERIALS );
+ mFMP->childDisable( "calculate_btn" );
+ }
+
+ int refFaceCnt = 0;
+ int modelFaceCnt = 0;
- //add this model to the lod total
- total_tris[lod] += cur_tris;
- total_verts[lod] += cur_verts;
- total_submeshes[lod] += cur_submeshes;
+ if (!lod_model->matchMaterialOrder(model_high_lod, refFaceCnt, modelFaceCnt ) )
+ {
+ setLoadState( LLModelLoader::ERROR_MATERIALS );
+ mFMP->childDisable( "calculate_btn" );
+ }
- //store this model's counts to asset data
- tris[lod].push_back(cur_tris);
- verts[lod].push_back(cur_verts);
- submeshes[lod].push_back(cur_submeshes);
+ if (lod_model)
+ {
+ //for each model in the lod
+ S32 cur_tris = 0;
+ S32 cur_verts = 0;
+ S32 cur_submeshes = lod_model->getNumVolumeFaces();
+
+ for (S32 j = 0; j < cur_submeshes; ++j)
+ { //for each submesh (face), add triangles and vertices to current total
+ const LLVolumeFace& face = lod_model->getVolumeFace(j);
+ cur_tris += face.mNumIndices/3;
+ cur_verts += face.mNumVertices;
}
+
+ std::string instance_name = instance.mLabel;
+
+ BOOL importerDebug = gSavedSettings.getBOOL("ImporterDebug");
+ if (importerDebug)
+ {
+ // Useful for debugging generalized complaints below about total submeshes which don't have enough
+ // context to address exactly what needs to be fixed to move towards compliance with the rules.
+ //
+ LL_INFOS() << "Instance " << lod_model->mLabel << " LOD " << i << " Verts: " << cur_verts << LL_ENDL;
+ LL_INFOS() << "Instance " << lod_model->mLabel << " LOD " << i << " Tris: " << cur_tris << LL_ENDL;
+ LL_INFOS() << "Instance " << lod_model->mLabel << " LOD " << i << " Faces: " << cur_submeshes << LL_ENDL;
+
+ LLModel::material_list::iterator mat_iter = lod_model->mMaterialList.begin();
+ while (mat_iter != lod_model->mMaterialList.end())
+ {
+ LL_INFOS() << "Instance " << lod_model->mLabel << " LOD " << i << " Material " << *(mat_iter) << LL_ENDL;
+ mat_iter++;
+ }
+ }
+
+ //add this model to the lod total
+ total_tris[i] += cur_tris;
+ total_verts[i] += cur_verts;
+ total_submeshes[i] += cur_submeshes;
+
+ //store this model's counts to asset data
+ tris[i].push_back(cur_tris);
+ verts[i].push_back(cur_verts);
+ submeshes[i].push_back(cur_submeshes);
}
}
- }
+ }
if (mMaxTriangleLimit == 0)
{
@@ -4354,37 +2704,48 @@ void LLModelPreview::updateStatusMessages()
const LLVector4a scale(0.5f);
for (U32 i = 0; i < mModel[lod].size() && !has_degenerate; ++i)
{ //for each model in the lod
- if (mModel[lod][i]->mPhysics.mHull.empty())
+ if (mModel[lod][i] && mModel[lod][i]->mPhysics.mHull.empty())
{ //no decomp exists
S32 cur_submeshes = mModel[lod][i]->getNumVolumeFaces();
for (S32 j = 0; j < cur_submeshes && !has_degenerate; ++j)
{ //for each submesh (face), add triangles and vertices to current total
- const LLVolumeFace& face = mModel[lod][i]->getVolumeFace(j);
- for (S32 k = 0; k < face.mNumIndices && !has_degenerate; )
+ LLVolumeFace& face = mModel[lod][i]->getVolumeFace(j);
+ for (S32 k = 0; (k < face.mNumIndices) && !has_degenerate; )
{
- LLVector4a v1; v1.setMul(face.mPositions[face.mIndices[k++]], scale);
- LLVector4a v2; v2.setMul(face.mPositions[face.mIndices[k++]], scale);
- LLVector4a v3; v3.setMul(face.mPositions[face.mIndices[k++]], scale);
+ U16 index_a = face.mIndices[k+0];
+ U16 index_b = face.mIndices[k+1];
+ U16 index_c = face.mIndices[k+2];
+
+ LLVector4a v1; v1.setMul(face.mPositions[index_a], scale);
+ LLVector4a v2; v2.setMul(face.mPositions[index_b], scale);
+ LLVector4a v3; v3.setMul(face.mPositions[index_c], scale);
if (ll_is_degenerate(v1,v2,v3))
{
has_degenerate = true;
}
+ else
+ {
+ k += 3;
+ }
}
}
}
}
}
-
+
mFMP->childSetTextArg("submeshes_info", "[SUBMESHES]", llformat("%d", total_submeshes[LLModel::LOD_HIGH]));
std::string mesh_status_na = mFMP->getString("mesh_status_na");
S32 upload_status[LLModel::LOD_HIGH+1];
- bool upload_ok = true;
+ mModelNoErrors = true;
- for (S32 lod = 0; lod <= LLModel::LOD_HIGH; ++lod)
+ const U32 lod_high = LLModel::LOD_HIGH;
+ U32 high_submodel_count = mModel[lod_high].size() - countRootModels(mModel[lod_high]);
+
+ for (S32 lod = 0; lod <= lod_high; ++lod)
{
upload_status[lod] = 0;
@@ -4397,7 +2758,7 @@ void LLModelPreview::updateStatusMessages()
}
else
{
- if (lod == LLModel::LOD_HIGH)
+ if (lod == lod_high)
{
upload_status[lod] = 2;
message = "mesh_status_missing_lod";
@@ -4418,8 +2779,6 @@ void LLModelPreview::updateStatusMessages()
mFMP->childSetValue(lod_vertices_name[lod], mesh_status_na);
}
- const U32 lod_high = LLModel::LOD_HIGH;
-
if (lod != lod_high)
{
if (total_submeshes[lod] && total_submeshes[lod] != total_submeshes[lod_high])
@@ -4427,6 +2786,13 @@ void LLModelPreview::updateStatusMessages()
message = "mesh_status_submesh_mismatch";
upload_status[lod] = 2;
}
+ else if (mModel[lod].size() - countRootModels(mModel[lod]) != high_submodel_count)
+ {//number of submodels is different, not all faces are matched correctly.
+ message = "mesh_status_submesh_mismatch";
+ upload_status[lod] = 2;
+ // Note: Submodels in instance were loaded from higher LOD and as result face count
+ // returns same value and total_submeshes[lod] is identical to high_lod one.
+ }
else if (!tris[lod].empty() && tris[lod].size() != tris[lod_high].size())
{ //number of meshes is different
message = "mesh_status_mesh_mismatch";
@@ -4447,7 +2813,7 @@ void LLModelPreview::updateStatusMessages()
{
//too many vertices in this lod
message = "mesh_status_too_many_vertices";
- upload_status[lod] = 2;
+ upload_status[lod] = 1;
}
}
}
@@ -4459,7 +2825,7 @@ void LLModelPreview::updateStatusMessages()
if (upload_status[lod] >= 2)
{
- upload_ok = false;
+ mModelNoErrors = false;
}
if (lod == mPreviewLOD)
@@ -4473,23 +2839,41 @@ void LLModelPreview::updateStatusMessages()
}
- //make sure no hulls have more than 256 points in them
- for (U32 i = 0; upload_ok && i < mModel[LLModel::LOD_PHYSICS].size(); ++i)
+ //warn if hulls have more than 256 points in them
+ BOOL physExceededVertexLimit = FALSE;
+ for (U32 i = 0; mModelNoErrors && i < mModel[LLModel::LOD_PHYSICS].size(); ++i)
{
LLModel* mdl = mModel[LLModel::LOD_PHYSICS][i];
- for (U32 j = 0; upload_ok && j < mdl->mPhysics.mHull.size(); ++j)
+ if (mdl)
{
- if (mdl->mPhysics.mHull[j].size() > 256)
+ for (U32 j = 0; j < mdl->mPhysics.mHull.size(); ++j)
{
- upload_ok = false;
+ if (mdl->mPhysics.mHull[j].size() > 256)
+ {
+ physExceededVertexLimit = TRUE;
+ LL_INFOS() << "Physical model " << mdl->mLabel << " exceeds vertex per hull limitations." << LL_ENDL;
+ break;
+ }
}
}
}
+ mFMP->childSetVisible("physics_status_message_text", physExceededVertexLimit);
+ LLIconCtrl* physStatusIcon = mFMP->getChild<LLIconCtrl>("physics_status_message_icon");
+ physStatusIcon->setVisible(physExceededVertexLimit);
+ if (physExceededVertexLimit)
+ {
+ mFMP->childSetValue("physics_status_message_text", mFMP->getString("phys_status_vertex_limit_exceeded"));
+ LLUIImagePtr img = LLUI::getUIImage("ModelImport_Status_Warning");
+ physStatusIcon->setImage(img);
+ }
- bool errorStateFromLoader = getLoadState() >= LLModelLoader::ERROR_PARSING ? true : false;
+ if (getLoadState() >= LLModelLoader::ERROR_PARSING)
+ {
+ mModelNoErrors = false;
+ LL_INFOS() << "Loader returned errors, model can't be uploaded" << LL_ENDL;
+ }
- bool skinAndRigOk = true;
bool uploadingSkin = mFMP->childGetValue("upload_skin").asBoolean();
bool uploadingJointPositions = mFMP->childGetValue("upload_joints").asBoolean();
@@ -4497,19 +2881,23 @@ void LLModelPreview::updateStatusMessages()
{
if ( uploadingJointPositions && !isRigValidForJointPositionUpload() )
{
- skinAndRigOk = false;
- }
+ mModelNoErrors = false;
+ LL_INFOS() << "Invalid rig, there might be issues with uploading Joint positions" << LL_ENDL;
+ }
}
-
- if(upload_ok && mModelLoader)
+
+ if(mModelNoErrors && mModelLoader)
{
if(!mModelLoader->areTexturesReady() && mFMP->childGetValue("upload_textures").asBoolean())
{
- upload_ok = false ;
+ // Some textures are still loading, prevent upload until they are done
+ mModelNoErrors = false;
}
}
- if (!upload_ok || errorStateFromLoader || !skinAndRigOk || has_degenerate)
+ // Todo: investigate use of has_degenerate and include into mModelNoErrors upload blocking mechanics
+ // current use of has_degenerate won't block upload permanently - later checks will restore the button
+ if (!mModelNoErrors || has_degenerate)
{
mFMP->childDisable("ok_btn");
}
@@ -4851,7 +3239,8 @@ void LLModelPreview::genBuffers(S32 lod, bool include_skin_weights)
LLModel* base_mdl = *base_iter;
base_iter++;
- for (S32 i = 0, e = mdl->getNumVolumeFaces(); i < e; ++i)
+ S32 num_faces = mdl->getNumVolumeFaces();
+ for (S32 i = 0; i < num_faces; ++i)
{
const LLVolumeFace &vf = mdl->getVolumeFace(i);
U32 num_vertices = vf.mNumVertices;
@@ -4946,23 +3335,23 @@ void LLModelPreview::genBuffers(S32 lod, bool include_skin_weights)
void LLModelPreview::update()
{
- if (mDirty)
+ if (mGenLOD)
{
- mDirty = false;
- mResourceCost = calcResourceCost();
+ mGenLOD = false;
+ genLODs();
refresh();
updateStatusMessages();
}
- if (mGenLOD)
+ if (mDirty)
{
- mGenLOD = false;
- genLODs();
+ mDirty = false;
+ mResourceCost = calcResourceCost();
refresh();
updateStatusMessages();
}
-
}
+
//-----------------------------------------------------------------------------
// getTranslationForJointOffset()
//-----------------------------------------------------------------------------
@@ -4996,10 +3385,79 @@ void LLModelPreview::createPreviewAvatar( void )
}
else
{
- LL_INFOS()<<"Failed to create preview avatar for upload model window"<<LL_ENDL;
+ LL_INFOS() << "Failed to create preview avatar for upload model window" << LL_ENDL;
}
}
+//static
+U32 LLModelPreview::countRootModels(LLModelLoader::model_list models)
+{
+ U32 root_models = 0;
+ model_list::iterator model_iter = models.begin();
+ while (model_iter != models.end())
+ {
+ LLModel* mdl = *model_iter;
+ if (mdl && mdl->mSubmodelID == 0)
+ {
+ root_models++;
+ }
+ model_iter++;
+ }
+ return root_models;
+}
+
+void LLModelPreview::loadedCallback(
+ LLModelLoader::scene& scene,
+ LLModelLoader::model_list& model_list,
+ S32 lod,
+ void* opaque)
+{
+ LLModelPreview* pPreview = static_cast< LLModelPreview* >(opaque);
+ if (pPreview && !LLModelPreview::sIgnoreLoadedCallback)
+ {
+ pPreview->loadModelCallback(lod);
+ }
+}
+
+void LLModelPreview::stateChangedCallback(U32 state,void* opaque)
+{
+ LLModelPreview* pPreview = static_cast< LLModelPreview* >(opaque);
+ if (pPreview)
+ {
+ pPreview->setLoadState(state);
+ }
+}
+
+LLJoint* LLModelPreview::lookupJointByName(const std::string& str, void* opaque)
+{
+ LLModelPreview* pPreview = static_cast< LLModelPreview* >(opaque);
+ if (pPreview)
+ {
+ return pPreview->getPreviewAvatar()->getJoint(str);
+ }
+ return NULL;
+}
+
+U32 LLModelPreview::loadTextures(LLImportMaterial& material,void* opaque)
+{
+ (void)opaque;
+
+ if (material.mDiffuseMapFilename.size())
+ {
+ material.mOpaqueData = new LLPointer< LLViewerFetchedTexture >;
+ LLPointer< LLViewerFetchedTexture >& tex = (*reinterpret_cast< LLPointer< LLViewerFetchedTexture > * >(material.mOpaqueData));
+
+ tex = LLViewerTextureManager::getFetchedTextureFromUrl("file://" + material.mDiffuseMapFilename, FTT_LOCAL_FILE, TRUE, LLGLTexture::BOOST_PREVIEW);
+ tex->setLoadedCallback(LLModelPreview::textureLoadedCallback, 0, TRUE, FALSE, opaque, NULL, FALSE);
+ tex->forceToSaveRawImage(0, F32_MAX);
+ material.setDiffuseMap(tex->getID()); // record tex ID
+ return 1;
+ }
+
+ material.mOpaqueData = NULL;
+ return 0;
+}
+
void LLModelPreview::addEmptyFace( LLModel* pTarget )
{
U32 type_mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_TEXCOORD0;
@@ -5036,6 +3494,7 @@ void LLModelPreview::addEmptyFace( LLModel* pTarget )
pTarget->setVolumeFaceData( faceCnt+1, pos, norm, tc, index, buff->getNumVerts(), buff->getNumIndices() );
}
+
//-----------------------------------------------------------------------------
// render()
//-----------------------------------------------------------------------------
@@ -5245,7 +3704,7 @@ BOOL LLModelPreview::render()
}
else
{
- LL_INFOS(" ") << "Vertex Buffer[" << mPreviewLOD << "]" << " is EMPTY!!!" << LL_ENDL;
+ LL_INFOS() << "Vertex Buffer[" << mPreviewLOD << "]" << " is EMPTY!!!" << LL_ENDL;
regen = TRUE;
}
}
@@ -5255,24 +3714,6 @@ BOOL LLModelPreview::render()
genBuffers(mPreviewLOD, skin_weight);
}
- //make sure material lists all match
- for (U32 i = 0; i < LLModel::NUM_LODS-1; i++)
- {
- if (mBaseModel.size() == mModel[i].size())
- {
- for (U32 j = 0; j < mBaseModel.size(); ++j)
- {
- int refFaceCnt = 0;
- int modelFaceCnt = 0;
-
- if ( !mModel[i][j]->matchMaterialOrder(mBaseModel[j], refFaceCnt, modelFaceCnt ) )
- {
- mFMP->childDisable( "calculate_btn" );
- }
- }
- }
- }
-
if (!skin_weight)
{
for (LLMeshUploadThread::instance_list::iterator iter = mUploadData.begin(); iter != mUploadData.end(); ++iter)
@@ -5281,62 +3722,63 @@ BOOL LLModelPreview::render()
LLModel* model = instance.mLOD[mPreviewLOD];
- if (!model)
- {
- continue;
- }
+ if (!model)
+ {
+ continue;
+ }
- gGL.pushMatrix();
- LLMatrix4 mat = instance.mTransform;
+ gGL.pushMatrix();
+ LLMatrix4 mat = instance.mTransform;
- gGL.multMatrix((GLfloat*) mat.mMatrix);
+ gGL.multMatrix((GLfloat*) mat.mMatrix);
- for (U32 i = 0, e = mVertexBuffer[mPreviewLOD][model].size(); i < e; ++i)
- {
- LLVertexBuffer* buffer = mVertexBuffer[mPreviewLOD][model][i];
-
- buffer->setBuffer(type_mask & buffer->getTypeMask());
- if (textures)
+ U32 num_models = mVertexBuffer[mPreviewLOD][model].size();
+ for (U32 i = 0; i < num_models; ++i)
{
- int materialCnt = instance.mModel->mMaterialList.size();
- if ( i < materialCnt )
+ LLVertexBuffer* buffer = mVertexBuffer[mPreviewLOD][model][i];
+
+ buffer->setBuffer(type_mask & buffer->getTypeMask());
+
+ if (textures)
{
- const std::string& binding = instance.mModel->mMaterialList[i];
- const LLImportMaterial& material = instance.mMaterial[binding];
+ int materialCnt = instance.mModel->mMaterialList.size();
+ if ( i < materialCnt )
+ {
+ const std::string& binding = instance.mModel->mMaterialList[i];
+ const LLImportMaterial& material = instance.mMaterial[binding];
- gGL.diffuseColor4fv(material.mDiffuseColor.mV);
+ gGL.diffuseColor4fv(material.mDiffuseColor.mV);
- if (material.mDiffuseMap.notNull())
- {
- if (material.mDiffuseMap->getDiscardLevel() > -1)
+ // Find the tex for this material, bind it, and add it to our set
+ //
+ LLViewerFetchedTexture* tex = bindMaterialDiffuseTexture(material);
+ if (tex)
{
- gGL.getTexUnit(0)->bind(material.mDiffuseMap, true);
- mTextureSet.insert(material.mDiffuseMap.get());
+ mTextureSet.insert(tex);
}
}
}
- }
- else
- {
- gGL.diffuseColor4f(1,1,1,1);
- }
-
- buffer->drawRange(LLRender::TRIANGLES, 0, buffer->getNumVerts()-1, buffer->getNumIndices(), 0);
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- gGL.diffuseColor3f(0.4f, 0.4f, 0.4f);
+ else
+ {
+ gGL.diffuseColor4f(1,1,1,1);
+ }
- if (edges)
- {
- glLineWidth(3.f);
- glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
buffer->drawRange(LLRender::TRIANGLES, 0, buffer->getNumVerts()-1, buffer->getNumIndices(), 0);
- glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
- glLineWidth(1.f);
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+ gGL.diffuseColor3f(0.4f, 0.4f, 0.4f);
+
+ if (edges)
+ {
+ glLineWidth(3.f);
+ glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
+ buffer->drawRange(LLRender::TRIANGLES, 0, buffer->getNumVerts()-1, buffer->getNumIndices(), 0);
+ glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+ glLineWidth(1.f);
+ }
}
+ gGL.popMatrix();
}
- gGL.popMatrix();
- }
if (physics)
{
@@ -5364,97 +3806,99 @@ BOOL LLModelPreview::render()
LLModel* model = instance.mLOD[LLModel::LOD_PHYSICS];
- if (!model)
- {
- continue;
- }
+ if (!model)
+ {
+ continue;
+ }
- gGL.pushMatrix();
- LLMatrix4 mat = instance.mTransform;
+ gGL.pushMatrix();
+ LLMatrix4 mat = instance.mTransform;
gGL.multMatrix((GLfloat*) mat.mMatrix);
- bool render_mesh = true;
+ bool render_mesh = true;
- LLPhysicsDecomp* decomp = gMeshRepo.mDecompThread;
- if (decomp)
- {
- LLMutexLock(decomp->mMutex);
+ LLPhysicsDecomp* decomp = gMeshRepo.mDecompThread;
+ if (decomp)
+ {
+ LLMutexLock(decomp->mMutex);
- LLModel::Decomposition& physics = model->mPhysics;
+ LLModel::Decomposition& physics = model->mPhysics;
- if (!physics.mHull.empty())
- {
- render_mesh = false;
+ if (!physics.mHull.empty())
+ {
+ render_mesh = false;
- if (physics.mMesh.empty())
- { //build vertex buffer for physics mesh
- gMeshRepo.buildPhysicsMesh(physics);
- }
+ if (physics.mMesh.empty())
+ { //build vertex buffer for physics mesh
+ gMeshRepo.buildPhysicsMesh(physics);
+ }
- if (!physics.mMesh.empty())
- { //render hull instead of mesh
- for (U32 i = 0; i < physics.mMesh.size(); ++i)
- {
- if (explode > 0.f)
+ if (!physics.mMesh.empty())
+ { //render hull instead of mesh
+ for (U32 i = 0; i < physics.mMesh.size(); ++i)
{
- gGL.pushMatrix();
+ if (explode > 0.f)
+ {
+ gGL.pushMatrix();
- LLVector3 offset = model->mHullCenter[i]-model->mCenterOfHullCenters;
- offset *= explode;
+ LLVector3 offset = model->mHullCenter[i]-model->mCenterOfHullCenters;
+ offset *= explode;
- gGL.translatef(offset.mV[0], offset.mV[1], offset.mV[2]);
- }
+ gGL.translatef(offset.mV[0], offset.mV[1], offset.mV[2]);
+ }
- static std::vector<LLColor4U> hull_colors;
+ static std::vector<LLColor4U> hull_colors;
- if (i+1 >= hull_colors.size())
- {
- hull_colors.push_back(LLColor4U(rand()%128+127, rand()%128+127, rand()%128+127, 128));
- }
+ if (i+1 >= hull_colors.size())
+ {
+ hull_colors.push_back(LLColor4U(rand()%128+127, rand()%128+127, rand()%128+127, 128));
+ }
- gGL.diffuseColor4ubv(hull_colors[i].mV);
- LLVertexBuffer::drawArrays(LLRender::TRIANGLES, physics.mMesh[i].mPositions, physics.mMesh[i].mNormals);
+ gGL.diffuseColor4ubv(hull_colors[i].mV);
+ LLVertexBuffer::drawArrays(LLRender::TRIANGLES, physics.mMesh[i].mPositions, physics.mMesh[i].mNormals);
- if (explode > 0.f)
- {
- gGL.popMatrix();
+ if (explode > 0.f)
+ {
+ gGL.popMatrix();
+ }
}
}
}
}
- }
-
- if (render_mesh)
- {
- if (mVertexBuffer[LLModel::LOD_PHYSICS].empty())
- {
- genBuffers(LLModel::LOD_PHYSICS, false);
- }
- for (U32 i = 0; i < mVertexBuffer[LLModel::LOD_PHYSICS][model].size(); ++i)
+
+ if (render_mesh)
{
- LLVertexBuffer* buffer = mVertexBuffer[LLModel::LOD_PHYSICS][model][i];
+ if (mVertexBuffer[LLModel::LOD_PHYSICS].empty())
+ {
+ genBuffers(LLModel::LOD_PHYSICS, false);
+ }
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- gGL.diffuseColor4f(0.4f, 0.4f, 0.0f, 0.4f);
+ U32 num_models = mVertexBuffer[LLModel::LOD_PHYSICS][model].size();
+ for (U32 i = 0; i < num_models; ++i)
+ {
+ LLVertexBuffer* buffer = mVertexBuffer[LLModel::LOD_PHYSICS][model][i];
- buffer->setBuffer(type_mask & buffer->getTypeMask());
- buffer->drawRange(LLRender::TRIANGLES, 0, buffer->getNumVerts()-1, buffer->getNumIndices(), 0);
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+ gGL.diffuseColor4f(0.4f, 0.4f, 0.0f, 0.4f);
- gGL.diffuseColor3f(1.f, 1.f, 0.f);
+ buffer->setBuffer(type_mask & buffer->getTypeMask());
+ buffer->drawRange(LLRender::TRIANGLES, 0, buffer->getNumVerts()-1, buffer->getNumIndices(), 0);
- glLineWidth(2.f);
- glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
- buffer->drawRange(LLRender::TRIANGLES, 0, buffer->getNumVerts()-1, buffer->getNumIndices(), 0);
+ gGL.diffuseColor3f(1.f, 1.f, 0.f);
- glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
- glLineWidth(1.f);
+ glLineWidth(2.f);
+ glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
+ buffer->drawRange(LLRender::TRIANGLES, 0, buffer->getNumVerts()-1, buffer->getNumIndices(), 0);
+
+ glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+ glLineWidth(1.f);
+ }
}
- }
- gGL.popMatrix();
- }
+ gGL.popMatrix();
+ }
glLineWidth(3.f);
glPointSize(8.f);
@@ -5581,74 +4025,47 @@ BOOL LLModelPreview::render()
//quick 'n dirty software vertex skinning
//build matrix palette
-
- LLMatrix4 mat[64];
- for (U32 j = 0; j < model->mSkinInfo.mJointNames.size(); ++j)
- {
- LLJoint* joint = getPreviewAvatar()->getJoint(model->mSkinInfo.mJointNames[j]);
- if (joint)
- {
- mat[j] = model->mSkinInfo.mInvBindMatrix[j];
- mat[j] *= joint->getWorldMatrix();
- }
- }
+ LLMatrix4a mat[LL_MAX_JOINTS_PER_MESH_OBJECT];
+ const LLMeshSkinInfo *skin = &model->mSkinInfo;
+ U32 count = llmin((U32) skin->mJointNames.size(), (U32) LL_MAX_JOINTS_PER_MESH_OBJECT);
+ LLDrawPoolAvatar::initSkinningMatrixPalette((LLMatrix4*)mat, count,
+ skin, getPreviewAvatar());
+ LLMatrix4a bind_shape_matrix;
+ bind_shape_matrix.loadu(skin->mBindShapeMatrix);
for (U32 j = 0; j < buffer->getNumVerts(); ++j)
{
- LLMatrix4 final_mat;
- final_mat.mMatrix[0][0] = final_mat.mMatrix[1][1] = final_mat.mMatrix[2][2] = final_mat.mMatrix[3][3] = 0.f;
-
- LLVector4 wght;
- S32 idx[4];
-
- F32 scale = 0.f;
- for (U32 k = 0; k < 4; k++)
- {
- F32 w = weight[j].mV[k];
-
- idx[k] = (S32) floorf(w);
- wght.mV[k] = w - floorf(w);
- scale += wght.mV[k];
- }
-
- wght *= 1.f/scale;
-
- for (U32 k = 0; k < 4; k++)
- {
- F32* src = (F32*) mat[idx[k]].mMatrix;
- F32* dst = (F32*) final_mat.mMatrix;
-
- F32 w = wght.mV[k];
-
- for (U32 l = 0; l < 16; l++)
- {
- dst[l] += src[l]*w;
- }
- }
+ LLMatrix4a final_mat;
+ F32 *wptr = weight[j].mV;
+ LLDrawPoolAvatar::getPerVertexSkinMatrix(wptr, mat, true, final_mat);
//VECTORIZE THIS
- LLVector3 v(face.mPositions[j].getF32ptr());
+ LLVector4a& v = face.mPositions[j];
- v = v * model->mSkinInfo.mBindShapeMatrix;
- v = v * final_mat;
+ LLVector4a t;
+ LLVector4a dst;
+ bind_shape_matrix.affineTransform(v, t);
+ final_mat.affineTransform(t, dst);
- position[j] = v;
+ position[j][0] = dst[0];
+ position[j][1] = dst[1];
+ position[j][2] = dst[2];
}
- llassert(model->mMaterialList.size() > i);
+ llassert(model->mMaterialList.size() > i);
const std::string& binding = instance.mModel->mMaterialList[i];
const LLImportMaterial& material = instance.mMaterial[binding];
buffer->setBuffer(type_mask & buffer->getTypeMask());
gGL.diffuseColor4fv(material.mDiffuseColor.mV);
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- if (material.mDiffuseMap.notNull())
+
+ // Find the tex for this material, bind it, and add it to our set
+ //
+ LLViewerFetchedTexture* tex = bindMaterialDiffuseTexture(material);
+ if (tex)
{
- if (material.mDiffuseMap->getDiscardLevel() > -1)
- {
- gGL.getTexUnit(0)->bind(material.mDiffuseMap, true);
- mTextureSet.insert(material.mDiffuseMap.get());
- }
+ mTextureSet.insert(tex);
}
buffer->draw(LLRender::TRIANGLES, buffer->getNumIndices(), 0);
@@ -5763,14 +4180,14 @@ void LLFloaterModelPreview::onReset(void* user_data)
LLFloaterModelPreview* fmp = (LLFloaterModelPreview*) user_data;
fmp->childDisable("reset_btn");
LLModelPreview* mp = fmp->mModelPreview;
- std::string filename = mp->mLODFile[3];
+ std::string filename = mp->mLODFile[LLModel::LOD_HIGH];
fmp->resetDisplayOptions();
//reset model preview
fmp->initModelPreview();
mp = fmp->mModelPreview;
- mp->loadModel(filename,3,true);
+ mp->loadModel(filename,LLModel::LOD_HIGH,true);
}
//static
@@ -5802,7 +4219,14 @@ void LLFloaterModelPreview::refresh()
}
//static
-void LLModelPreview::textureLoadedCallback( BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* src_aux, S32 discard_level, BOOL final, void* userdata )
+void LLModelPreview::textureLoadedCallback(
+ BOOL success,
+ LLViewerFetchedTexture *src_vi,
+ LLImageRaw* src,
+ LLImageRaw* src_aux,
+ S32 discard_level,
+ BOOL final,
+ void* userdata )
{
LLModelPreview* preview = (LLModelPreview*) userdata;
preview->refresh();
@@ -5864,7 +4288,7 @@ void LLFloaterModelPreview::toggleCalculateButton(bool visible)
}
mUploadBtn->setVisible(!visible);
- mUploadBtn->setEnabled(mHasUploadPerm && !mUploadModelUrl.empty());
+ mUploadBtn->setEnabled(isModelUploadAllowed());
if (visible)
{
@@ -5930,7 +4354,7 @@ void LLFloaterModelPreview::handleModelPhysicsFeeReceived()
childSetTextArg("price_breakdown", "[MODEL]", llformat("%d", result["upload_price_breakdown"]["model"].asInteger()));
childSetVisible("upload_fee", true);
childSetVisible("price_breakdown", true);
- mUploadBtn->setEnabled(mHasUploadPerm && !mUploadModelUrl.empty());
+ mUploadBtn->setEnabled(isModelUploadAllowed());
}
void LLFloaterModelPreview::setModelPhysicsFeeErrorStatus(S32 status, const std::string& reason)
@@ -5954,6 +4378,16 @@ void LLFloaterModelPreview::onModelUploadFailure()
mUploadBtn->setEnabled(true);
}
+bool LLFloaterModelPreview::isModelUploadAllowed()
+{
+ bool allow_upload = mHasUploadPerm && !mUploadModelUrl.empty();
+ if (mModelPreview)
+ {
+ allow_upload &= mModelPreview->mModelNoErrors;
+ }
+ return allow_upload;
+}
+
S32 LLFloaterModelPreview::DecompRequest::statusCallback(const char* status, S32 p1, S32 p2)
{
if (mContinue)
@@ -6003,8 +4437,8 @@ void LLFloaterModelPreview::onPermissionsReceived(const LLSD& result)
// BAP HACK: handle "" for case that MeshUploadFlag cap is broken.
mHasUploadPerm = (("" == upload_status) || ("valid" == upload_status));
- //mUploadBtn->setEnabled(mHasUploadPerm);
- mUploadBtn->setEnabled(mHasUploadPerm && !mUploadModelUrl.empty());
+ // isModelUploadAllowed() includes mHasUploadPerm
+ mUploadBtn->setEnabled(isModelUploadAllowed());
getChild<LLTextBox>("warning_title")->setVisible(!mHasUploadPerm);
getChild<LLTextBox>("warning_message")->setVisible(!mHasUploadPerm);
}
diff --git a/indra/newview/llfloatermodelpreview.h b/indra/newview/llfloatermodelpreview.h
index 618748bd4e..25c650a725 100755
--- a/indra/newview/llfloatermodelpreview.h
+++ b/indra/newview/llfloatermodelpreview.h
@@ -37,6 +37,8 @@
#include "llviewermenufile.h"
#include "llfloatermodeluploadbase.h"
+#include "lldaeloader.h"
+
class LLComboBox;
class LLJoint;
class LLViewerJointMesh;
@@ -45,103 +47,18 @@ class LLTextBox;
class LLVertexBuffer;
class LLModelPreview;
class LLFloaterModelPreview;
+class DAE;
class daeElement;
class domProfile_COMMON;
class domInstance_geometry;
class domNode;
class domTranslate;
class domController;
+class domSkin;
+class domMesh;
class LLMenuButton;
class LLToggleableMenu;
-typedef std::map<std::string, LLMatrix4> JointTransformMap;
-typedef std::map<std::string, LLMatrix4>:: iterator JointTransformMapIt;
-
-const S32 NUM_LOD = 4;
-
-class LLModelLoader : public LLThread
-{
-public:
- typedef enum
- {
- STARTING = 0,
- READING_FILE,
- CREATING_FACES,
- GENERATING_VERTEX_BUFFERS,
- GENERATING_LOD,
- DONE,
- ERROR_PARSING, //basically loading failed
- ERROR_MATERIALS,
- } eLoadState;
-
- U32 mState;
- std::string mFilename;
- S32 mLod;
- LLModelPreview* mPreview;
- LLMatrix4 mTransform;
- BOOL mFirstTransform;
- LLVector3 mExtents[2];
- bool mTrySLM;
-
- std::map<daeElement*, LLPointer<LLModel> > mModel;
-
- typedef std::vector<LLPointer<LLModel> > model_list;
- model_list mModelList;
-
- typedef std::vector<LLModelInstance> model_instance_list;
-
- typedef std::map<LLMatrix4, model_instance_list > scene;
-
- scene mScene;
-
- typedef std::queue<LLPointer<LLModel> > model_queue;
-
- //queue of models that need a physics rep
- model_queue mPhysicsQ;
-
- LLModelLoader( std::string filename, S32 lod, LLModelPreview* preview, JointTransformMap& jointMap,
- std::deque<std::string>& jointsFromNodes );
- ~LLModelLoader() ;
-
- virtual void run();
- bool doLoadModel();
- bool loadFromSLM(const std::string& filename);
- void loadModelCallback();
-
- void loadTextures() ; //called in the main thread.
- void processElement(daeElement* element, bool& badElement);
- std::map<std::string, LLImportMaterial> getMaterials(LLModel* model, domInstance_geometry* instance_geo);
- LLImportMaterial profileToMaterial(domProfile_COMMON* material);
- std::string getElementLabel(daeElement *element);
- LLColor4 getDaeColor(daeElement* element);
-
- daeElement* getChildFromElement( daeElement* pElement, std::string const & name );
-
- bool isNodeAJoint( domNode* pNode );
- void processJointNode( domNode* pNode, std::map<std::string,LLMatrix4>& jointTransforms );
- void extractTranslation( domTranslate* pTranslate, LLMatrix4& transform );
- void extractTranslationViaElement( daeElement* pTranslateElement, LLMatrix4& transform );
- void extractTranslationViaSID( daeElement* pElement, LLMatrix4& transform );
-
- void setLoadState(U32 state);
-
- void buildJointToNodeMappingFromScene( daeElement* pRoot );
- void processJointToNodeMapping( domNode* pNode );
- void processChildJoints( domNode* pParentNode );
-
- //map of avatar joints as named in COLLADA assets to internal joint names
- std::map<std::string, std::string> mJointMap;
- JointTransformMap& mJointList;
- std::deque<std::string>& mJointsFromNode;
-
- S32 mNumOfFetchingTextures ; //updated in the main thread
- bool areTexturesReady() { return !mNumOfFetchingTextures; } //called in the main thread.
-
-private:
- static std::list<LLModelLoader*> sActiveLoaderList;
- static bool isAlive(LLModelLoader* loader) ;
-};
-
class LLFloaterModelPreview : public LLFloaterModelUploadBase
{
public:
@@ -172,6 +89,7 @@ public:
BOOL handleScrollWheel(S32 x, S32 y, S32 clicks);
/*virtual*/ void onOpen(const LLSD& key);
+ /*virtual*/ void onClose(bool app_quitting);
static void onMouseCaptureLostModelPreview(LLMouseHandler*);
static void setUploadAmount(S32 amount) { sUploadAmount = amount; }
@@ -210,6 +128,8 @@ public:
/*virtual*/ void onModelUploadFailure();
+ bool isModelUploadAllowed();
+
protected:
friend class LLModelPreview;
friend class LLMeshFilePicker;
@@ -339,6 +259,7 @@ public:
virtual BOOL needsRender() { return mNeedsUpdate; }
void setPreviewLOD(S32 lod);
void clearModel(S32 lod);
+ void getLegalJointNames(JointNameSet& legal_joint_names);
void loadModel(std::string filename, S32 lod, bool force_disable_slm = false);
void loadModelCallback(S32 lod);
void genLODs(S32 which_lod = -1, U32 decimation = 3, bool enforce_tri_limit = false);
@@ -359,21 +280,14 @@ public:
void setHasPivot( bool val ) { mHasPivot = val; }
void setModelPivot( const LLVector3& pivot ) { mModelPivot = pivot; }
- //Determines the viability of an asset to be used as an avatar rig (w or w/o joint upload caps)
- void critiqueRigForUploadApplicability( const std::vector<std::string> &jointListFromAsset );
- void critiqueJointToNodeMappingFromScene( void );
//Is a rig valid so that it can be used as a criteria for allowing for uploading of joint positions
//Accessors for joint position upload friendly rigs
const bool isRigValidForJointPositionUpload( void ) const { return mRigValidJointUpload; }
void setRigValidForJointPositionUpload( bool rigValid ) { mRigValidJointUpload = rigValid; }
- bool isRigSuitableForJointPositionUpload( const std::vector<std::string> &jointListFromAsset );
- //Determines if a rig is a legacy from the joint list
- bool isRigLegacy( const std::vector<std::string> &jointListFromAsset );
+
//Accessors for the legacy rigs
const bool isLegacyRigValid( void ) const { return mLegacyRigValid; }
- void setLegacyRigValid( bool rigValid ) { mLegacyRigValid = rigValid; }
- //Verify that a controller matches vertex counts
- bool verifyController( domController* pController );
+ void setLegacyRigValid( bool rigValid ) { mLegacyRigValid = rigValid; }
static void textureLoadedCallback( BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* src_aux, S32 discard_level, BOOL final, void* userdata );
@@ -388,6 +302,16 @@ public:
LLVector3 getTranslationForJointOffset( std::string joint );
+ static bool sIgnoreLoadedCallback;
+
+protected:
+
+ static void loadedCallback(LLModelLoader::scene& scene,LLModelLoader::model_list& model_list, S32 lod, void* opaque);
+ static void stateChangedCallback(U32 state, void* opaque);
+
+ static LLJoint* lookupJointByName(const std::string&, void* opaque);
+ static U32 loadTextures(LLImportMaterial& material, void* opaque);
+
private:
//Utility function for controller vertex compare
bool verifyCount( int expected, int result );
@@ -395,6 +319,8 @@ private:
void createPreviewAvatar( void );
//Accessor for the dummy avatar
LLVOAvatar* getPreviewAvatar( void ) { return mPreviewAvatar; }
+ // Count amount of original models, excluding sub-models
+ static U32 countRootModels(LLModelLoader::model_list models);
protected:
friend class LLModelLoader;
@@ -416,13 +342,15 @@ private:
LLVector3 mPreviewTarget;
LLVector3 mPreviewScale;
S32 mPreviewLOD;
+ S32 mPhysicsSearchLOD;
U32 mResourceCost;
std::string mLODFile[LLModel::NUM_LODS];
bool mLoading;
U32 mLoadState;
bool mResetJoints;
bool mRigParityWithScene;
-
+ bool mModelNoErrors;
+
std::map<std::string, bool> mViewOption;
//GLOD object parameters (must rebuild object if these change)
@@ -459,7 +387,7 @@ private:
U32 mMaxTriangleLimit;
LLMeshUploadThread::instance_list mUploadData;
- std::set<LLViewerFetchedTexture* > mTextureSet;
+ std::set<LLViewerFetchedTexture * > mTextureSet;
//map of vertex buffers to models (one vertex buffer in vector per face in model
std::map<LLModel*, std::vector<LLPointer<LLVertexBuffer> > > mVertexBuffer[LLModel::NUM_LODS+1];
@@ -478,10 +406,9 @@ private:
bool mLastJointUpdate;
- std::deque<std::string> mMasterJointList;
- std::deque<std::string> mMasterLegacyJointList;
- std::deque<std::string> mJointsFromNode;
- JointTransformMap mJointTransformMap;
+ JointNameSet mJointsFromNode;
+ JointTransformMap mJointTransformMap;
+
LLPointer<LLVOAvatar> mPreviewAvatar;
};
diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp
index 9a0bd9d1bc..55b94aa141 100755
--- a/indra/newview/llmeshrepository.cpp
+++ b/indra/newview/llmeshrepository.cpp
@@ -493,6 +493,12 @@ void get_vertex_buffer_from_mesh(LLCDMeshData& mesh, LLModel::PhysicsMesh& res,
}
}
+LLViewerFetchedTexture* LLMeshUploadThread::FindViewerTexture(const LLImportMaterial& material)
+{
+ LLPointer< LLViewerFetchedTexture > * ppTex = static_cast< LLPointer< LLViewerFetchedTexture > * >(material.mOpaqueData);
+ return ppTex ? (*ppTex).get() : NULL;
+}
+
volatile S32 LLMeshRepoThread::sActiveHeaderRequests = 0;
volatile S32 LLMeshRepoThread::sActiveLODRequests = 0;
U32 LLMeshRepoThread::sMaxConcurrentRequests = 1;
@@ -587,16 +593,16 @@ public:
LLMeshLODHandler(const LLVolumeParams & mesh_params, S32 lod, U32 offset, U32 requested_bytes)
: LLMeshHandlerBase(offset, requested_bytes),
mLOD(lod)
- {
+ {
mMeshParams = mesh_params;
LLMeshRepoThread::incActiveLODRequests();
}
virtual ~LLMeshLODHandler();
-
+
protected:
LLMeshLODHandler(const LLMeshLODHandler &); // Not defined
void operator=(const LLMeshLODHandler &); // Not defined
-
+
public:
virtual void processData(LLCore::BufferArray * body, S32 body_offset, U8 * data, S32 data_size);
virtual void processFailure(LLCore::HttpStatus status);
@@ -796,7 +802,7 @@ LLMeshRepoThread::LLMeshRepoThread()
mHttpLargePolicyClass = app_core_http.getPolicy(LLAppCoreHttp::AP_LARGE_MESH);
}
-
+
LLMeshRepoThread::~LLMeshRepoThread()
{
LL_INFOS(LOG_MESH) << "Small GETs issued: " << LLMeshRepository::sHTTPRequestCount
@@ -865,16 +871,16 @@ void LLMeshRepoThread::run()
{
break;
}
-
+
if (! mHttpRequestSet.empty())
{
// Dispatch all HttpHandler notifications
mHttpRequest->update(0L);
}
sRequestWaterLevel = mHttpRequestSet.size(); // Stats data update
-
- // NOTE: order of queue processing intentionally favors LOD requests over header requests
+ // NOTE: order of queue processing intentionally favors LOD requests over header requests
+
while (!mLODReqQ.empty() && mHttpRequestSet.size() < sRequestHighWater)
{
if (! mMutex)
@@ -938,7 +944,7 @@ void LLMeshRepoThread::run()
mSkinRequests.erase(iter);
mMutex->unlock();
- if (!fetchMeshSkinInfo(mesh_id))
+ if (! fetchMeshSkinInfo(mesh_id))
{
incomplete.insert(mesh_id);
}
@@ -967,7 +973,7 @@ void LLMeshRepoThread::run()
mDecompositionRequests.erase(iter);
mMutex->unlock();
- if (!fetchMeshDecomposition(mesh_id))
+ if (! fetchMeshDecomposition(mesh_id))
{
incomplete.insert(mesh_id);
}
@@ -993,7 +999,7 @@ void LLMeshRepoThread::run()
mPhysicsShapeRequests.erase(iter);
mMutex->unlock();
- if (!fetchMeshPhysicsShape(mesh_id))
+ if (! fetchMeshPhysicsShape(mesh_id))
{
incomplete.insert(mesh_id);
}
@@ -1219,7 +1225,7 @@ bool LLMeshRepoThread::fetchMeshSkinInfo(const LLUUID& mesh_id)
}
++LLMeshRepository::sMeshRequestCount;
- bool ret = true ;
+ bool ret = true;
U32 header_size = mMeshHeaderSize[mesh_id];
if (header_size > 0)
@@ -1267,7 +1273,7 @@ bool LLMeshRepoThread::fetchMeshSkinInfo(const LLUUID& mesh_id)
constructUrl(mesh_id, &http_url, &cap_version);
if (!http_url.empty())
- {
+ {
LLMeshSkinInfoHandler * handler = new LLMeshSkinInfoHandler(mesh_id, offset, size);
LLCore::HttpHandle handle = getByteRange(http_url, cap_version, offset, size, handler);
if (LLCORE_HTTP_HANDLE_INVALID == handle)
@@ -1313,7 +1319,7 @@ bool LLMeshRepoThread::fetchMeshDecomposition(const LLUUID& mesh_id)
++LLMeshRepository::sMeshRequestCount;
U32 header_size = mMeshHeaderSize[mesh_id];
- bool ret = true ;
+ bool ret = true;
if (header_size > 0)
{
@@ -1359,9 +1365,9 @@ bool LLMeshRepoThread::fetchMeshDecomposition(const LLUUID& mesh_id)
int cap_version(2);
std::string http_url;
constructUrl(mesh_id, &http_url, &cap_version);
-
+
if (!http_url.empty())
- {
+ {
LLMeshDecompositionHandler * handler = new LLMeshDecompositionHandler(mesh_id, offset, size);
LLCore::HttpHandle handle = getByteRange(http_url, cap_version, offset, size, handler);
if (LLCORE_HTTP_HANDLE_INVALID == handle)
@@ -1407,7 +1413,7 @@ bool LLMeshRepoThread::fetchMeshPhysicsShape(const LLUUID& mesh_id)
++LLMeshRepository::sMeshRequestCount;
U32 header_size = mMeshHeaderSize[mesh_id];
- bool ret = true ;
+ bool ret = true;
if (header_size > 0)
{
@@ -1452,9 +1458,9 @@ bool LLMeshRepoThread::fetchMeshPhysicsShape(const LLUUID& mesh_id)
int cap_version(2);
std::string http_url;
constructUrl(mesh_id, &http_url, &cap_version);
-
+
if (!http_url.empty())
- {
+ {
LLMeshPhysicsShapeHandler * handler = new LLMeshPhysicsShapeHandler(mesh_id, offset, size);
LLCore::HttpHandle handle = getByteRange(http_url, cap_version, offset, size, handler);
if (LLCORE_HTTP_HANDLE_INVALID == handle)
@@ -1543,11 +1549,11 @@ bool LLMeshRepoThread::fetchMeshHeader(const LLVolumeParams& mesh_params)
}
//either cache entry doesn't exist or is corrupt, request header from simulator
- bool retval = true ;
+ bool retval = true;
int cap_version(2);
std::string http_url;
constructUrl(mesh_params.getSculptID(), &http_url, &cap_version);
-
+
if (!http_url.empty())
{
//grab first 4KB if we're going to bother with a fetch. Cache will prevent future fetches if a full mesh fits
@@ -1635,9 +1641,9 @@ bool LLMeshRepoThread::fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod)
int cap_version(2);
std::string http_url;
constructUrl(mesh_id, &http_url, &cap_version);
-
+
if (!http_url.empty())
- {
+ {
LLMeshLODHandler * handler = new LLMeshLODHandler(mesh_params, lod, offset, size);
LLCore::HttpHandle handle = getByteRange(http_url, cap_version, offset, size, handler);
if (LLCORE_HTTP_HANDLE_INVALID == handle)
@@ -1909,7 +1915,7 @@ LLMeshUploadThread::LLMeshUploadThread(LLMeshUploadThread::instance_list& data,
mOrigin += gAgent.getAtAxis() * scale.magVec();
- mMeshUploadTimeOut = gSavedSettings.getS32("MeshUploadTimeOut") ;
+ mMeshUploadTimeOut = gSavedSettings.getS32("MeshUploadTimeOut");
mHttpRequest = new LLCore::HttpRequest;
mHttpOptions = new LLCore::HttpOptions;
@@ -1977,14 +1983,14 @@ void LLMeshUploadThread::preStart()
void LLMeshUploadThread::discard()
{
- LLMutexLock lock(mMutex) ;
+ LLMutexLock lock(mMutex);
mDiscarded = true;
}
bool LLMeshUploadThread::isDiscarded() const
{
- LLMutexLock lock(mMutex) ;
- return mDiscarded ;
+ LLMutexLock lock(mMutex);
+ return mDiscarded;
}
void LLMeshUploadThread::run()
@@ -2049,6 +2055,14 @@ void LLMeshUploadThread::wholeModelToLLSD(LLSD& dest, bool include_textures)
{
LLMeshUploadData data;
data.mBaseModel = iter->first;
+
+ if (data.mBaseModel->mSubmodelID)
+ {
+ // These are handled below to insure correct parenting order on creation
+ // due to map walking being based on model address (aka random)
+ continue;
+ }
+
LLModelInstance& first_instance = *(iter->second.begin());
for (S32 i = 0; i < 5; i++)
{
@@ -2086,7 +2100,10 @@ void LLMeshUploadThread::wholeModelToLLSD(LLSD& dest, bool include_textures)
data.mModel[LLModel::LOD_IMPOSTOR],
decomp,
mUploadSkin,
- mUploadJoints);
+ mUploadJoints,
+ FALSE,
+ FALSE,
+ data.mBaseModel->mSubmodelID);
data.mAssetData = ostr.str();
std::string str = ostr.str();
@@ -2120,17 +2137,26 @@ void LLMeshUploadThread::wholeModelToLLSD(LLSD& dest, bool include_textures)
instance_entry["scale"] = ll_sd_from_vector3(scale);
instance_entry["material"] = LL_MCODE_WOOD;
- instance_entry["physics_shape_type"] = (U8)(LLViewerObject::PHYSICS_SHAPE_CONVEX_HULL);
+ instance_entry["physics_shape_type"] = data.mModel[LLModel::LOD_PHYSICS].notNull() ? (U8)(LLViewerObject::PHYSICS_SHAPE_PRIM) : (U8)(LLViewerObject::PHYSICS_SHAPE_CONVEX_HULL);
instance_entry["mesh"] = mesh_index[data.mBaseModel];
instance_entry["face_list"] = LLSD::emptyArray();
- S32 end = llmin((S32)data.mBaseModel->mMaterialList.size(), data.mBaseModel->getNumVolumeFaces()) ;
+ // We want to be able to allow more than 8 materials...
+ //
+ S32 end = llmin((S32)instance.mMaterial.size(), instance.mModel->getNumVolumeFaces()) ;
+
for (S32 face_num = 0; face_num < end; face_num++)
{
LLImportMaterial& material = instance.mMaterial[data.mBaseModel->mMaterialList[face_num]];
LLSD face_entry = LLSD::emptyMap();
- LLViewerFetchedTexture *texture = material.mDiffuseMap.get();
+
+ LLViewerFetchedTexture *texture = NULL;
+
+ if (material.mDiffuseMapFilename.size())
+ {
+ texture = FindViewerTexture(material);
+ }
if ((texture != NULL) &&
(textures.find(texture) == textures.end()))
@@ -2145,9 +2171,171 @@ void LLMeshUploadThread::wholeModelToLLSD(LLSD& dest, bool include_textures)
{
LLPointer<LLImageJ2C> upload_file =
LLViewerTextureList::convertToUploadFile(texture->getSavedRawImage());
+
+ if (!upload_file.isNull() && upload_file->getDataSize())
+ {
+ texture_str.write((const char*) upload_file->getData(), upload_file->getDataSize());
+ }
+ }
+ }
+
+ if (texture != NULL &&
+ mUploadTextures &&
+ texture_index.find(texture) == texture_index.end())
+ {
+ texture_index[texture] = texture_num;
+ std::string str = texture_str.str();
+ res["texture_list"][texture_num] = LLSD::Binary(str.begin(),str.end());
+ texture_num++;
+ }
+
+ // Subset of TextureEntry fields.
+ if (texture != NULL && mUploadTextures)
+ {
+ face_entry["image"] = texture_index[texture];
+ face_entry["scales"] = 1.0;
+ face_entry["scalet"] = 1.0;
+ face_entry["offsets"] = 0.0;
+ face_entry["offsett"] = 0.0;
+ face_entry["imagerot"] = 0.0;
+ }
+ face_entry["diffuse_color"] = ll_sd_from_color4(material.mDiffuseColor);
+ face_entry["fullbright"] = material.mFullbright;
+ instance_entry["face_list"][face_num] = face_entry;
+ }
+
+ res["instance_list"][instance_num] = instance_entry;
+ instance_num++;
+ }
+ }
+
+ for (instance_map::iterator iter = mInstance.begin(); iter != mInstance.end(); ++iter)
+ {
+ LLMeshUploadData data;
+ data.mBaseModel = iter->first;
+
+ if (!data.mBaseModel->mSubmodelID)
+ {
+ // These were handled above already...
+ //
+ continue;
+ }
+
+ LLModelInstance& first_instance = *(iter->second.begin());
+ for (S32 i = 0; i < 5; i++)
+ {
+ data.mModel[i] = first_instance.mLOD[i];
+ }
+
+ if (mesh_index.find(data.mBaseModel) == mesh_index.end())
+ {
+ // Have not seen this model before - create a new mesh_list entry for it.
+ if (model_name.empty())
+ {
+ model_name = data.mBaseModel->getName();
+ }
+
+ if (model_metric.empty())
+ {
+ model_metric = data.mBaseModel->getMetric();
+ }
+
+ std::stringstream ostr;
+
+ LLModel::Decomposition& decomp =
+ data.mModel[LLModel::LOD_PHYSICS].notNull() ?
+ data.mModel[LLModel::LOD_PHYSICS]->mPhysics :
+ data.mBaseModel->mPhysics;
+
+ decomp.mBaseHull = mHullMap[data.mBaseModel];
+
+ LLSD mesh_header = LLModel::writeModel(
+ ostr,
+ data.mModel[LLModel::LOD_PHYSICS],
+ data.mModel[LLModel::LOD_HIGH],
+ data.mModel[LLModel::LOD_MEDIUM],
+ data.mModel[LLModel::LOD_LOW],
+ data.mModel[LLModel::LOD_IMPOSTOR],
+ decomp,
+ mUploadSkin,
+ mUploadJoints,
+ FALSE,
+ FALSE,
+ data.mBaseModel->mSubmodelID);
+
+ data.mAssetData = ostr.str();
+ std::string str = ostr.str();
+
+ res["mesh_list"][mesh_num] = LLSD::Binary(str.begin(),str.end());
+ mesh_index[data.mBaseModel] = mesh_num;
+ mesh_num++;
+ }
+
+ // For all instances that use this model
+ for (instance_list::iterator instance_iter = iter->second.begin();
+ instance_iter != iter->second.end();
+ ++instance_iter)
+ {
+
+ LLModelInstance& instance = *instance_iter;
+
+ LLSD instance_entry;
+
+ for (S32 i = 0; i < 5; i++)
+ {
+ data.mModel[i] = instance.mLOD[i];
+ }
+
+ LLVector3 pos, scale;
+ LLQuaternion rot;
+ LLMatrix4 transformation = instance.mTransform;
+ decomposeMeshMatrix(transformation,pos,rot,scale);
+ instance_entry["position"] = ll_sd_from_vector3(pos);
+ instance_entry["rotation"] = ll_sd_from_quaternion(rot);
+ instance_entry["scale"] = ll_sd_from_vector3(scale);
+
+ instance_entry["material"] = LL_MCODE_WOOD;
+ instance_entry["physics_shape_type"] = (U8)(LLViewerObject::PHYSICS_SHAPE_NONE);
+ instance_entry["mesh"] = mesh_index[data.mBaseModel];
+
+ instance_entry["face_list"] = LLSD::emptyArray();
+
+ // We want to be able to allow more than 8 materials...
+ //
+ S32 end = llmin((S32)instance.mMaterial.size(), instance.mModel->getNumVolumeFaces()) ;
+
+ for (S32 face_num = 0; face_num < end; face_num++)
+ {
+ LLImportMaterial& material = instance.mMaterial[data.mBaseModel->mMaterialList[face_num]];
+ LLSD face_entry = LLSD::emptyMap();
+
+ LLViewerFetchedTexture *texture = NULL;
+
+ if (material.mDiffuseMapFilename.size())
+ {
+ texture = FindViewerTexture(material);
+ }
+
+ if ((texture != NULL) &&
+ (textures.find(texture) == textures.end()))
+ {
+ textures.insert(texture);
+ }
+
+ std::stringstream texture_str;
+ if (texture != NULL && include_textures && mUploadTextures)
+ {
+ if(texture->hasSavedRawImage())
+ {
+ LLPointer<LLImageJ2C> upload_file =
+ LLViewerTextureList::convertToUploadFile(texture->getSavedRawImage());
+
+ if (!upload_file.isNull() && upload_file->getDataSize())
+ {
texture_str.write((const char*) upload_file->getData(), upload_file->getDataSize());
}
}
+ }
if (texture != NULL &&
mUploadTextures &&
@@ -2235,7 +2423,7 @@ void LLMeshUploadThread::generateHulls()
}
}
- if(has_valid_requests)
+ if (has_valid_requests)
{
// *NOTE: Interesting livelock condition on shutdown. If there
// is an upload request in generateHulls() when shutdown starts,
@@ -2340,7 +2528,7 @@ void LLMeshUploadThread::requestWholeModelFee()
else
{
U32 sleep_time(10);
-
+
mHttpRequest->update(0);
while (! LLApp::isQuitting() && ! finished() && ! isDiscarded())
{
@@ -2435,7 +2623,7 @@ void LLMeshUploadThread::onCompleted(LLCore::HttpHandle handle, LLCore::HttpResp
// model fee case
LLWholeModelFeeObserver* observer(mFeeObserverHandle.get());
mWholeModelUploadURL.clear();
-
+
if (! status)
{
LL_WARNS(LOG_MESH) << "Fee request failed. Reason: " << reason
@@ -2465,7 +2653,7 @@ void LLMeshUploadThread::onCompleted(LLCore::HttpHandle handle, LLCore::HttpResp
LLCoreHttpUtil::responseToLLSD(response, true, body);
}
dump_llsd_to_file(body, make_dump_name("whole_model_fee_response_", dump_num));
-
+
if (body["state"].asString() == "upload")
{
mWholeModelUploadURL = body["uploader"].asString();
@@ -2536,7 +2724,7 @@ void LLMeshRepoThread::notifyLoadedMeshes()
LODRequest req = mUnavailableQ.front();
mUnavailableQ.pop();
mMutex->unlock();
-
+
update_metrics = true;
gMeshRepo.notifyMeshUnavailable(req.mMeshParams, req.mLOD);
}
@@ -2672,7 +2860,7 @@ void LLMeshRepository::cacheOutgoingMesh(LLMeshUploadData& data, LLSD& header)
void LLMeshHandlerBase::onCompleted(LLCore::HttpHandle handle, LLCore::HttpResponse * response)
{
mProcessed = true;
-
+
unsigned int retries(0U);
response->getRetries(NULL, &retries);
LLMeshRepository::sHTTPRetryCount += retries;
@@ -2728,7 +2916,7 @@ void LLMeshHandlerBase::onCompleted(LLCore::HttpHandle handle, LLCore::HttpRespo
// 200 case, typically
offset = 0;
}
-
+
// *DEBUG: To test validation below
// offset += 1;
@@ -2844,7 +3032,7 @@ void LLMeshHeaderHandler::processData(LLCore::BufferArray * /* body */, S32 /* b
const std::string & lod_name = header_lod[i];
lod_bytes = llmax(lod_bytes, header[lod_name]["offset"].asInteger()+header[lod_name]["size"].asInteger());
}
-
+
// just in case skin info or decomposition is at the end of the file (which it shouldn't be)
lod_bytes = llmax(lod_bytes, header["skin"]["offset"].asInteger() + header["skin"]["size"].asInteger());
lod_bytes = llmax(lod_bytes, header["physics_convex"]["offset"].asInteger() + header["physics_convex"]["size"].asInteger());
@@ -2852,7 +3040,7 @@ void LLMeshHeaderHandler::processData(LLCore::BufferArray * /* body */, S32 /* b
S32 header_bytes = (S32) gMeshRepo.mThread->mMeshHeaderSize[mesh_id];
S32 bytes = lod_bytes + header_bytes;
-
+
// It's possible for the remote asset to have more data than is needed for the local cache
// only allocate as much space in the VFS as is needed for the local cache
data_size = llmin(data_size, bytes);
@@ -2864,11 +3052,11 @@ void LLMeshHeaderHandler::processData(LLCore::BufferArray * /* body */, S32 /* b
++LLMeshRepository::sCacheWrites;
file.write(data, data_size);
-
+
// zero out the rest of the file
U8 block[MESH_HEADER_SIZE];
memset(block, 0, sizeof(block));
-
+
while (bytes-file.tell() > sizeof(block))
{
file.write(block, sizeof(block));
@@ -2894,8 +3082,8 @@ LLMeshLODHandler::~LLMeshLODHandler()
gMeshRepo.mThread->lockAndLoadMeshLOD(mMeshParams, mLOD);
}
LLMeshRepoThread::decActiveLODRequests();
- }
}
+}
void LLMeshLODHandler::processFailure(LLCore::HttpStatus status)
{
@@ -2913,7 +3101,7 @@ void LLMeshLODHandler::processData(LLCore::BufferArray * /* body */, S32 /* body
{
if ((! MESH_LOD_PROCESS_FAILED) && gMeshRepo.mThread->lodReceived(mMeshParams, mLOD, data, data_size))
{
- //good fetch from sim, write to VFS for caching
+ // good fetch from sim, write to VFS for caching
LLVFile file(gVFS, mMeshParams.getSculptID(), LLAssetType::AT_MESH, LLVFile::WRITE);
S32 offset = mOffset;
@@ -2958,7 +3146,7 @@ void LLMeshSkinInfoHandler::processData(LLCore::BufferArray * /* body */, S32 /*
{
if ((! MESH_SKIN_INFO_PROCESS_FAILED) && gMeshRepo.mThread->skinInfoReceived(mMeshID, data, data_size))
{
- //good fetch from sim, write to VFS for caching
+ // good fetch from sim, write to VFS for caching
LLVFile file(gVFS, mMeshID, LLAssetType::AT_MESH, LLVFile::WRITE);
S32 offset = mOffset;
@@ -3282,7 +3470,7 @@ void LLMeshRepository::notifyLoadedMeshes()
REQUEST2_LOW_WATER_MIN,
REQUEST2_LOW_WATER_MAX);
}
-
+
//clean up completed upload threads
for (std::vector<LLMeshUploadThread*>::iterator iter = mUploads.begin(); iter != mUploads.end(); )
{
@@ -3359,7 +3547,7 @@ void LLMeshRepository::notifyLoadedMeshes()
//call completed callbacks on finished decompositions
mDecompThread->notifyCompleted();
-
+
// For major operations, attempt to get the required locks
// without blocking and punt if they're not available. The
// longest run of holdoffs is kept in sMaxLockHoldoffs just
@@ -3378,12 +3566,12 @@ void LLMeshRepository::notifyLoadedMeshes()
return;
}
hold_offs = 0;
-
+
if (gAgent.getRegion())
{
// Update capability urls
static std::string region_name("never name a region this");
-
+
if (gAgent.getRegion()->getName() != region_name && gAgent.getRegion()->capabilitiesReceived())
{
region_name = gAgent.getRegion()->getName();
@@ -3399,7 +3587,7 @@ void LLMeshRepository::notifyLoadedMeshes()
<< LL_ENDL;
}
}
-
+
//popup queued error messages from background threads
while (!mUploadErrorQ.empty())
{
@@ -3754,7 +3942,7 @@ LLSD& LLMeshRepoThread::getMeshHeader(const LLUUID& mesh_id)
void LLMeshRepository::uploadModel(std::vector<LLModelInstance>& data, LLVector3& scale, bool upload_textures,
- bool upload_skin, bool upload_joints, std::string upload_url, bool do_upload,
+ bool upload_skin, bool upload_joints, std::string upload_url, bool do_upload,
LLHandle<LLWholeModelFeeObserver> fee_observer, LLHandle<LLWholeModelUploadObserver> upload_observer)
{
LLMeshUploadThread* thread = new LLMeshUploadThread(data, scale, upload_textures, upload_skin, upload_joints, upload_url,
@@ -3825,37 +4013,6 @@ void LLMeshUploadThread::decomposeMeshMatrix(LLMatrix4& transformation,
result_rot = quat_rotation;
}
-bool LLImportMaterial::operator<(const LLImportMaterial &rhs) const
-{
- if (mDiffuseMap != rhs.mDiffuseMap)
- {
- return mDiffuseMap < rhs.mDiffuseMap;
- }
-
- if (mDiffuseMapFilename != rhs.mDiffuseMapFilename)
- {
- return mDiffuseMapFilename < rhs.mDiffuseMapFilename;
- }
-
- if (mDiffuseMapLabel != rhs.mDiffuseMapLabel)
- {
- return mDiffuseMapLabel < rhs.mDiffuseMapLabel;
- }
-
- if (mDiffuseColor != rhs.mDiffuseColor)
- {
- return mDiffuseColor < rhs.mDiffuseColor;
- }
-
- if (mBinding != rhs.mBinding)
- {
- return mBinding < rhs.mBinding;
- }
-
- return mFullbright < rhs.mFullbright;
-}
-
-
void LLMeshRepository::updateInventory(inventory_data data)
{
LLMutexLock lock(mMeshMutex);
@@ -4253,7 +4410,7 @@ void LLPhysicsDecomp::doDecompositionSingleHull()
setMeshData(mesh, true);
LLCDResult ret = decomp->buildSingleHull() ;
- if(ret)
+ if (ret)
{
LL_WARNS(LOG_MESH) << "Could not execute decomposition stage when attempting to create single hull." << LL_ENDL;
make_box(mCurRequest);
@@ -4441,60 +4598,6 @@ void LLPhysicsDecomp::Request::setStatusMessage(const std::string& msg)
mStatusMessage = msg;
}
-LLModelInstance::LLModelInstance(LLSD& data)
-{
- mLocalMeshID = data["mesh_id"].asInteger();
- mLabel = data["label"].asString();
- mTransform.setValue(data["transform"]);
-
- for (U32 i = 0; i < data["material"].size(); ++i)
- {
- LLImportMaterial mat(data["material"][i]);
- mMaterial[mat.mBinding] = mat;
- }
-}
-
-
-LLSD LLModelInstance::asLLSD()
-{
- LLSD ret;
-
- ret["mesh_id"] = mModel->mLocalID;
- ret["label"] = mLabel;
- ret["transform"] = mTransform.getValue();
-
- U32 i = 0;
- for (std::map<std::string, LLImportMaterial>::iterator iter = mMaterial.begin(); iter != mMaterial.end(); ++iter)
- {
- ret["material"][i++] = iter->second.asLLSD();
- }
-
- return ret;
-}
-
-LLImportMaterial::LLImportMaterial(LLSD& data)
-{
- mDiffuseMapFilename = data["diffuse"]["filename"].asString();
- mDiffuseMapLabel = data["diffuse"]["label"].asString();
- mDiffuseColor.setValue(data["diffuse"]["color"]);
- mFullbright = data["fullbright"].asBoolean();
- mBinding = data["binding"].asString();
-}
-
-
-LLSD LLImportMaterial::asLLSD()
-{
- LLSD ret;
-
- ret["diffuse"]["filename"] = mDiffuseMapFilename;
- ret["diffuse"]["label"] = mDiffuseMapLabel;
- ret["diffuse"]["color"] = mDiffuseColor.getValue();
- ret["fullbright"] = mFullbright;
- ret["binding"] = mBinding;
-
- return ret;
-}
-
void LLMeshRepository::buildPhysicsMesh(LLModel::Decomposition& decomp)
{
decomp.mMesh.resize(decomp.mHull.size());
diff --git a/indra/newview/llmeshrepository.h b/indra/newview/llmeshrepository.h
index 39280bea3a..688cd01a87 100755
--- a/indra/newview/llmeshrepository.h
+++ b/indra/newview/llmeshrepository.h
@@ -90,54 +90,6 @@ public:
}
};
-class LLImportMaterial
-{
-public:
- LLPointer<LLViewerFetchedTexture> mDiffuseMap;
- std::string mDiffuseMapFilename;
- std::string mDiffuseMapLabel;
- std::string mBinding;
- LLColor4 mDiffuseColor;
- bool mFullbright;
-
- bool operator<(const LLImportMaterial &params) const;
-
- LLImportMaterial()
- : mFullbright(false)
- {
- mDiffuseColor.set(1,1,1,1);
- }
-
- LLImportMaterial(LLSD& data);
-
- LLSD asLLSD();
-};
-
-class LLModelInstance
-{
-public:
- LLPointer<LLModel> mModel;
- LLPointer<LLModel> mLOD[5];
-
- std::string mLabel;
-
- LLUUID mMeshID;
- S32 mLocalMeshID;
-
- LLMatrix4 mTransform;
- std::map<std::string, LLImportMaterial> mMaterial;
-
- LLModelInstance(LLModel* model, const std::string& label, LLMatrix4& transform, std::map<std::string, LLImportMaterial>& materials)
- : mModel(model), mLabel(label), mTransform(transform), mMaterial(materials)
- {
- mLocalMeshID = -1;
- }
-
- LLModelInstance(LLSD& data);
-
- LLSD asLLSD();
-};
-
class LLPhysicsDecomp : public LLThread
{
public:
@@ -483,6 +435,8 @@ public:
// Inherited from LLCore::HttpHandler
virtual void onCompleted(LLCore::HttpHandle handle, LLCore::HttpResponse * response);
+ LLViewerFetchedTexture* FindViewerTexture(const LLImportMaterial& material);
+
private:
LLHandle<LLWholeModelFeeObserver> mFeeObserverHandle;
LLHandle<LLWholeModelUploadObserver> mUploadObserverHandle;
diff --git a/indra/newview/llpreviewanim.cpp b/indra/newview/llpreviewanim.cpp
index 35ac0537a3..f83532ea83 100755
--- a/indra/newview/llpreviewanim.cpp
+++ b/indra/newview/llpreviewanim.cpp
@@ -37,6 +37,7 @@
#include "lllineeditor.h"
#include "lluictrlfactory.h"
#include "lluictrlfactory.h"
+#include "lldatapacker.h"
extern LLAgent gAgent;
@@ -109,6 +110,13 @@ void LLPreviewAnim::play(const LLSD& param)
}
else
{
+ // BENTO TEMP
+ LLKeyframeMotion *motionp = dynamic_cast<LLKeyframeMotion*>(gAgentAvatarp->findMotion(itemID));
+ if (motionp && motionp->isLoaded())
+ {
+ //motionp->dumpToFile(item->getName());
+ }
+
gAgentAvatarp->startMotion(item->getAssetUUID());
}
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index d2050aec3e..09cd4bb6f7 100755
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -1260,7 +1260,7 @@ bool idle_startup()
LLPostProcess::initClass();
display_startup();
- LLAvatarAppearance::initClass();
+ LLAvatarAppearance::initClass(gSavedSettings.getString("AvatarFileName"),gSavedSettings.getString("SkeletonFileName"));
display_startup();
LLViewerObject::initVOClasses();
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index f753448770..202b63dec0 100755
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -5153,7 +5153,10 @@ void LLVOAvatar::clearAttachmentPosOverrides()
for (; iter != end; ++iter)
{
LLJoint* pJoint = (*iter);
- pJoint->clearAttachmentPosOverrides();
+ if (pJoint)
+ {
+ pJoint->clearAttachmentPosOverrides();
+ }
}
}
@@ -5435,8 +5438,14 @@ BOOL LLVOAvatar::loadSkeletonNode ()
LLViewerJointAttachment* attachment = new LLViewerJointAttachment();
attachment->setName(info->mName);
- LLJoint *parentJoint = getJoint(info->mJointName);
- if (!parentJoint)
+ LLJoint *parent_joint = getJoint(info->mJointName);
+ if (!parent_joint)
+ {
+ // If the intended location for attachment point is unavailable, stick it in a default location.
+ LL_INFOS() << "attachment pt " << info->mName << " using mPelvis as default parent" << LL_ENDL;
+ parent_joint = getJoint("mPelvis");
+ }
+ if (!parent_joint)
{
LL_WARNS() << "No parent joint by name " << info->mJointName << " found for attachment point " << info->mName << LL_ENDL;
delete attachment;
@@ -5491,7 +5500,7 @@ BOOL LLVOAvatar::loadSkeletonNode ()
mAttachmentPoints[attachmentID] = attachment;
// now add attachment joint
- parentJoint->addChild(attachment);
+ parent_joint->addChild(attachment);
}
}
diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp
index 0432f6f27c..5e010a4712 100755
--- a/indra/newview/llvovolume.cpp
+++ b/indra/newview/llvovolume.cpp
@@ -4163,21 +4163,12 @@ void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, cons
}
//build matrix palette
- static const size_t kMaxJoints = 64;
+ // BENTO JOINT COUNT LIMIT
+ static const size_t kMaxJoints = LL_MAX_JOINTS_PER_MESH_OBJECT;
- LLMatrix4a mp[kMaxJoints];
- LLMatrix4* mat = (LLMatrix4*) mp;
-
+ LLMatrix4a mat[kMaxJoints];
U32 maxJoints = llmin(skin->mJointNames.size(), kMaxJoints);
- for (U32 j = 0; j < maxJoints; ++j)
- {
- LLJoint* joint = avatar->getJoint(skin->mJointNames[j]);
- if (joint)
- {
- mat[j] = skin->mInvBindMatrix[j];
- mat[j] *= joint->getWorldMatrix();
- }
- }
+ LLDrawPoolAvatar::initSkinningMatrixPalette((LLMatrix4*)mat, maxJoints, skin, avatar);
for (S32 i = 0; i < volume->getNumVolumeFaces(); ++i)
{
@@ -4201,36 +4192,7 @@ void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, cons
for (U32 j = 0; j < dst_face.mNumVertices; ++j)
{
LLMatrix4a final_mat;
- final_mat.clear();
-
- S32 idx[4];
-
- LLVector4 wght;
-
- F32 scale = 0.f;
- for (U32 k = 0; k < 4; k++)
- {
- F32 w = weight[j][k];
-
- idx[k] = (S32) floorf(w);
- wght[k] = w - floorf(w);
- scale += wght[k];
- }
-
- wght *= 1.f/scale;
-
- for (U32 k = 0; k < 4; k++)
- {
- F32 w = wght[k];
-
- LLMatrix4a src;
- // Insure ref'd bone is in our clamped array of mats
- llassert(idx[k] < kMaxJoints);
- // clamp k to kMaxJoints to avoid reading garbage off stack in release
- src.setMul(mp[idx[(k < kMaxJoints) ? k : 0]], w);
- final_mat.add(src);
- }
-
+ LLDrawPoolAvatar::getPerVertexSkinMatrix(weight[j].getF32ptr(), mat, false, final_mat);
LLVector4a& v = vol_face.mPositions[j];
LLVector4a t;
diff --git a/indra/newview/skins/default/xui/en/floater_model_preview.xml b/indra/newview/skins/default/xui/en/floater_model_preview.xml
index a4acd1df78..7183b2f1f9 100755
--- a/indra/newview/skins/default/xui/en/floater_model_preview.xml
+++ b/indra/newview/skins/default/xui/en/floater_model_preview.xml
@@ -31,6 +31,7 @@
<string name="mesh_status_too_many_vertices">Level of detail has too many vertices.</string>
<string name="mesh_status_missing_lod">Missing required level of detail.</string>
<string name="mesh_status_invalid_material_list">LOD materials are not a subset of reference model.</string>
+ <string name="phys_status_vertex_limit_exceeded">Some physical hulls exceed vertex limitations.</string>
<string name="layer_all">All</string> <!-- Text to display in physics layer combo box for "all layers" -->
<string name="decomposing">Analyzing...</string>
<string name="simplifying">Simplifying...</string>
@@ -66,7 +67,7 @@
follows="top|left"
layout="topleft"
height="19"
- max_length_bytes="64"
+ max_length_bytes="63"
name="description_form"
prevalidate_callback="ascii"
top_pad="5"
@@ -1027,19 +1028,19 @@
bg_alpha_color="0 0 0 0"
bg_opaque_color="0 0 0 0.3"
follows="left|top"
- height="16"
+ height="19"
layout="topleft"
left="18"
name="physics info"
- top_pad="15"
- width="589">
+ top_pad="12"
+ width="319">
<text
follows="top|left"
height="15"
layout="topleft"
left="0"
text_color="White"
- top_pad="0"
+ top_pad="3"
name="results_text"
width="50">
Results:
@@ -1077,6 +1078,33 @@
Hulls: [HULLS]
</text>
</panel>
+ <panel
+ bg_alpha_color="0 0 0 0"
+ bg_opaque_color="0 0 0 0.3"
+ follows="left|top"
+ height="19"
+ layout="topleft"
+ left_pad="5"
+ top_delta="0"
+ name="physics message"
+ width="270">
+ <icon
+ follows="left|top"
+ height="16"
+ left="0"
+ layout="topleft"
+ name="physics_status_message_icon"
+ top_pad="0"
+ width="16" />
+ <text
+ follows="left|top"
+ height="15"
+ layout="topleft"
+ left_pad="2"
+ name="physics_status_message_text"
+ width="252"
+ top_delta="3"/>
+ </panel>
</panel>
<!-- MODIFIERS PANEL -->
<panel