Avatar Appearance

From Second Life Wiki
Revision as of 19:46, 16 December 2008 by Mm Alder (talk | contribs) (→‎Linden binary mesh file: comment about the vertex ordering)
Jump to navigation Jump to search


For a good introduction to the elements of 3D character graphics, including meshes, morphs, bones, rendering, quaternions, and more see Martin Garstenauer's thesis.

Packets

  • AgentWearablesRequest
    • This is where it starts. The viewer asks the simulator what it is wearing, and an AgentWearablesUpdate packet is returned.
  • AgentWearablesUpdate
    • A mapping of wearable types to asset IDs and item IDs is returned to the client. There are currently 13 different wearable types and all 13 will always be returned in this packet. If your avatar is not wearing a wearable type the asset ID and item ID for that type will be null IDs (all zeros). The next step is to request an asset transfer for all of the non-null asset IDs and download the wearable assets.
  • AgentIsNowWearing
    • Like the AgentWearablesUpdate packet but in the other direction. The viewer sends a list of the 13 wearable types and their associated item IDs, or null if nothing is being worn in that wearable slot. This is typically sent right before AgentSetAppearance.
  • AgentSetAppearance
    • Serves two purposes, to tell the server how our avatar mesh is deformed (with visual parameters) and what textures we are wearing. There are currently 218 VisualParam blocks sent with each AgentSetAppearance describing everything from the color of the avatar eyes to the gender slider. A TextureEntry is also sent that uses the same TextureEntry format objects use, but each "face" is hard-coded to describe a particular texture. This may or may not include baked textures for the five different baked layers (head, upper, lower, eyes, and skirt).
    • The ParamValue fields do not have parameter IDs associated with them in the packet, as it's assumed all viewers have the same parameter map in the same sequence. The parameters are stored internally as a floating point integer, and are converted to a single byte by inputting the value along with minimum and maximum weights for that parameter to a conversion function.

Linden avatar definition file

The parameters affecting avatar appearance are defined in an XML file located in the executable at

SecondLife\character\avatar_lad.xml

and in the source code at

linden\indra\newview\character\avatar_lad.xml


With a few exceptions

genepool.xml
rouge_alpha.tga
underpants_trial_female.tga
underpants_trial_male.tga
undershirt_trial_female.tga
upperbodyfreckles_alpha.tga

all of the other files in the same directory are referenced by avatar_lad.xml. These include the mesh files (.llm), the texture files (.tga) and the avatar_skeleton.xml file (see below).

genepool.xml contains parameter sets for wearable types WT_SHAPE, WT_SKIN, WT_HAIR, and WT_EYES for several archetypal avatar definitions. You can see the current parameter set for your own avatar by invoking the debug menus (Ctrl-Alt-D) and selecting Client->Character->Character Tests->Appearance To XML. This will create a file

SecondLife\character\new archetype.xml

in the same format as genepool.xml.


The avatar definition file affects the appearances on your viewer only. Any change to the file will not affect how others see the avatars. You can set value_default="1" for "Express_Tongue_Out" to make the avatars on your viewer give you the raspberries, but no one else will notice.

The interesting thing is that this file defines parameters that can be used in animations.


File structure

<?xml version="1.0" encoding="US-ASCII" standalone="yes"?>

<linden_avatar version="1.0" wearable_definition_version="22">

<skeleton file_name="avatar_skeleton.xml">
<attachment_point id="1" group="6" name="Chest" joint="mChest"
position="0.15 0 -0.1" rotation="0 90 90" visible_in_first_person="true"
pie_slice="2" hud="true" max_attachment_offset="1.5" />
<param ... >
<param_skeleton>
<bone name="mNeck" scale="0 0 .2" offset="0 0 .004" />
</param_skeleton>
</param>
</skeleton>


Sets of
<mesh type="hairMesh" lod="0" file_name="avatar_hair.llm"
min_pixel_width="320" min_pixel_area="0.1" >
<param ... >
<param_morph />
or
<param_morph>
<volume_morph name="HEAD" scale="-0.008 -0.006 0.015"
pos="0.07 0 -0.07" />
</param_morph>
</param>
</mesh>
<mesh type="hairMesh" lod="1" file_name="avatar_hair_1.llm"
min_pixel_width="160" min_pixel_area="0.1" reference="avatar_hair.llm">
</mesh>


<global_color name="skin_color">
<param ... >
<param_color operation="blend" >
<value color="252, 215, 200, 255" />
</param_color>
</param>
</global_color>


<layer_set body_region="head" width="512" height="512"
clear_alpha="false" alpha_tga_file="head_alpha.tga" >
<layer name="head bump definition" render_pass="bump"
global_color="hair_color" fixed_color="128,128,128,255"
write_all_channels="true" >
<texture local_texture="lower_jacket" local_texture_alpha_only="true" />
and if not fixed_color
<texture tga_file="bump_head_base.tga" file_is_mask="FALSE" />
<morph_mask morph_name="Displace_Loose_Upperbody" invert="FALSE" />
<param ... >
<param_alpha tga_file="bump_face_wrinkles.tga" skip_if_zero="true"
multiply_blend="false" domain="0" />
or
<param_color operation="multiply" >
<value color="0, 0, 0, 0" />
</param_color>
</param>
</layer>
</layer_set>


<driver_parameters>
<param ... >
<param_driver>
<driven id="628" min1="0.1" max1="0.5" max2="1" min2="1" />
</param_driver>
</param>
</driver_parameters>

</linden_avatar>

where bold text indicates required tags or parameters, standard text indicates a tag that can occur zero or one time, italics indicates that the tag can be repeated zero or more times, and bold italics indicates that at least one is required but more are possible.

Note that the values shown for parameters here may not be consistent. They are shown only to indicate the value type.


Parameter detail

<param ... > is

<param id="32" group="1" name="Male_Skeleton"
value_min="0" value_max="1" value_default="0"
edit_group="shape_body" edit_group_order="1"
label="Skeleton" label_min="Female" label_max="Male"
wearable="shape" clothing_morph="true" sex="male" shared="1"
show_simple="true" simple_percent_min="40" simple_percent_max="100"
camera_distance="2.2" camera_elevation=".1" camera_angle="0" >


Parameters are parsed in LLViewerVisualParamInfo::parseXml and LLVisualParamInfo::parseXml and are used by LLViewerVisualParam and LLVisualParam respectively when LLVOAvatar::loadAvatar is called.


Fields parsed in LLVisualParamInfo are used to describe the meaning of the parameters.

id -- mID
name -- mName
default ""
group -- mGroup
"0" is VISUAL_PARAM_GROUP_TWEAKABLE
"1" is VISUAL_PARAM_GROUP_ANIMATABLE
default "0"
value_min -- mMinWeight
default 0.
value_max -- mMaxWeight
default 1.
value_default -- mDefaultWeight
default 0.
sex -- mSex
"both" SEX_BOTH
"male" SEX_MALE
"female" SEX_FEMALE
default SEX_BOTH
label -- mDisplayName
default is name
label_min -- mMinName
default is "Less"
label_max -- mMaxName
default is "More"
shared
Used only by mesh params. Indicates that the param affects more than one mesh


Fields parsed in LLViewerVisualParamInfo describe the appearance of the entries on the Edit->Appearance editing panel.

wearable -- mWearableType
"shape" WT_SHAPE
"skin" WT_SKIN
"hair" WT_HAIR
"eyes" WT_EYES
"shirt" WT_SHIRT
"pants" WT_PANTS
"shoes" WT_SHOES
"socks" WT_SOCKS
"jacket" WT_JACKET
"gloves" WT_GLOVES
"undershirt" WT_UNDERSHIRT
"underpants" WT_UNDERPANTS
"skirt" WT_SKIRT
default WT_INVALID
edit_group -- mEditGroup
default ""
edit_group_order -- mEditGroupDisplayOrder
By default, value 0, parameters are displayed in the order in which they appear in the xml file. "edit_group_order" overriddes this.


Optional camera offsets from the current joint center. Used for generating "hints" (thumbnails).

camera_distance -- mCamDist
default 0.5
camera_angle -- mCamAngle
default 0.
camera_elevation -- mCamElevation
default 0.


show_simple -- mShowSimple
value is ignored
default FALSE
simple_percent_min -- mSimpleMin
value is ignored
default 0.
simple_percent_max -- mSimpleMax
value is ignored
default 100.


Loading the file

The file is parsed in LLVOAvatar::initClass() primarily by calls to LLVOAvatarInfo. Both classes are defined in indra\newview\llvoavatar.h(.cpp). There is one method for each of the major XML nodes

LLVOAvatarInfo::parseXmlSkeletonNode
LLVOAvatarInfo::parseXmlMeshNodes
LLVOAvatarInfo::parseXmlColorNodes
LLVOAvatarInfo::parseXmlLayerNodes
LLVOAvatarInfo::parseXmlDriverNodes

This data is then used to create instances of LLVOAvatar in LLVOAvatar::loadAvatar() which invokes LLVOAvatar::loadSkeletonNode() and LLVOAvatar::loadMeshNodes().


LLVisualParam

The avatar visual parameters are divided into those that define the avatar's appearance and those that are used in animations. Theoretically, they all could be used for animations, but the animations would have to start and end at the settings defined for the avatar rather than at the default values.

The group field of the <param> tag identifies those that are directly set in Edit->Appearance and sent in AgentSetAppearance messages as VISUAL_PARAM_GROUP_TWEAKABLE. The rest are identified as VISUAL_PARAM_GROUP_ANIMATABLE, but this is a bit misleading because it includes all of the driven parameters defined in the <driver_parameters> stanza. These are set by the driver parameters which are themselves directly tweakable.

Those that are not directly or indirectly tweakable include the emotes

  • 300 Express_Closed_Mouth
  • 301 Express_Tongue_Out
  • 302 Express_Surprise_Emote
  • 303 Express_Wink_Emote
  • 304 Express_Embarrassed_Emote
  • 305 Express_Shrug_Emote
  • 306 Express_Kiss
  • 307 Express_Bored_Emote
  • 308 Express_Repulsed_Emote
  • 309 Express_Disdain
  • 310 Express_Afraid_Emote
  • 311 Express_Worry_Emote
  • 312 Express_Cry_Emote
  • 313 Express_Sad_Emote
  • 314 Express_Anger_Emote
  • 315 Express_Frown
  • 316 Express_Laugh_Emote
  • 317 Express_Toothsmile
  • 318 Express_Smile
  • 632 Express_Open_Mouth

the hand morphs

  • 101 Hands_Relaxed
  • 102 Hands_Point
  • 103 Hands_Fist
  • 666 Hands_Relaxed_L
  • 667 Hands_Point_L
  • 668 Hands_Fist_L
  • 669 Hands_Relaxed_R
  • 670 Hands_Point_R
  • 671 Hands_Fist_R
  • 672 Hands_Typing
  • 766 Hands_Salute_R
  • 791 Hands_Peace_R
  • 792 Hands_Spread_R

and blinking eyes

  • 58 Blink_Left
  • 59 Blink_Right


The remaining visual params include a few useful for animations

  • 51 Furrowed_Eyebrows
  • 53 Surprised_Eyebrows
  • 54 Worried_Eyebrows
  • 55 Frown_Mouth
  • 57 Smile_Mouth

and a couple that seem to have been abandoned

  • 41 Old
  • 128 Wrinkles


Linden skeleton definition file

The skeletal structure is defined in an XML file located in the executable at

SecondLife\character\avatar_skeleton.xml

and in the source code at

linden\indra\newview\character\avatar_skeleton.xml

It is referenced through the avatar definition file (see above) and can be considered to be part of the avatar definition.


File structure

<?xml version="1.0" encoding="US-ASCII" standalone="yes"?>

<linden_skeleton version="1.0" num_bones="46" num_collision_volumes="19">

<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"/>
<bone ...>
</bone>
</bone>

</linden_skeleton>

where bold text indicates required tags or parameters, standard text indicates a tag that can occur zero or one time, and italics indicates that the tag can be repeated zero or more times.

The <bone ...> tag above is to indicate that the structure is recursive.

The "46" for num_bones is actually a typo in the file. There are only 26 bones defined.


Loading the file

The file is parsed in LLVOAvatar::initClass() using LLVOAvatarSkeletonInfo::parseXml. Both classes are defined in indra\newview\llvoavatar.h(.cpp).

This data is then used to create instances of LLVOAvatar in LLVOAvatar::loadAvatar() which invokes LLVOAvatar::buildSkeleton(). A special-purpose "screen" joint named "mScreen" is also created.


Linden binary mesh file

Meshes are defined in binary files located in the executable at

SecondLife\character\*.llm

and in the source code at

linden\indra\newview\character\*.llm

They are referenced through the avatar definition file (see above) and can be considered to be part of the avatar definition.

The morphName in the binary mesh file matches the name field of the visual params with <param_morph> tags in the <mesh> stanzas. There are a few morphs defined in the mesh files that are not used by the avatar definition file

  • Blink_Both
  • Fingernails_Long
  • Wide_Lips


There are two types of mesh files: the base mesh definition and the level of detail (LOD) mesh definition, which always references a base mesh definition file. LOD meshes are used to simplify the rendering when the avatar is distant from the camera. There are several LOD meshes with progressively decreasing resolution.

The vertex information referenced by the LOD meshes is stored at the beginning of the base mesh vertex information.


File structure

Base mesh

char[24] "Linden Binary Mesh 1.0"
U8 hasWeights
U8 hasDetailTexCoords
LLVector3 position
LLVector3 rotationAngles
U8 rotationOrder (ignored, set to 0)
LLVector3 scale
U16 numVertices
LLVector3[ numVertices ] baseCoords
LLVector3[ numVertices ] baseNormals
LLVector3[ numVertices ] baseBinormals
LLVector2[ numVertices ] texCoords
if (hasDetailTexCoords)
LLVector2[ numVertices ] detailTexCoords
if (hasWeights)
F32[ numVertices ] weights
U16 numFaces
struct faces[ numFaces ]
{
S16[3] face
}
if ( hasWeights )
{
U16 numSkinJoints
struct skinJoints[ numSkinJoints ]
{
char[64] jointName
}
}
struct morph []
{
char[64] morphName
S32 numVertices
struct vertices[ numVertices ]
{
U32 vertexIndex
LLVector3 coord
LLVector3 normal
LLVector3 binormal
LLVector2 texCoord
}
}
char[64] "End Morphs"
S32 numRemaps (or EOF)
struct vertexRemap[ numRemaps ]
{
S32 remapSource
S32 remapDestination
}

Level Of Detail (LOD) mesh

char[24] "Linden Binary Mesh 1.0"
U8 hasWeights
U8 hasDetailTexCoords
LLVector3 position
LLVector3 rotationAngles
U8 rotationOrder (ignored, set to 0)
LLVector3 scale
U16 numFaces
struct faces[ numFaces ]
{
S16[3] face
}

where LLVector2 and LLVector3 are 2 and 3 floats respectively, and all numbers are little endian. Integers are 8, 16, or 32 bits signed (S) or unsigned (U).

Each weight actually contains two pieces of information. The number to the left of the decimal point is the index of the joint and also implicitly indexes to the following joint. The actual weight is to the right of the decimal point and interpolates between these two joints. The index is into an "expanded" list of joints, not just a linear array of the joints as defined in the skeleton file. In particular, any joint that has more than one child will be repeated in the list for each of its children.

Loading the file

This data is used to create instances of LLVOAvatar in LLVOAvatar::loadAvatar() through LLVOAvatar::loadMeshNodes, LLPolyMesh::getMesh, LLPolyMeshSharedData::loadMesh, and LLPolyMorphData::loadBinary. These are found in indra\newview\llvoavatar.h(.cpp), indra\newview\llpolymesh.h(.cpp), and indra\newview\llpolymorph.h(.cpp).