Mesh/Mesh Asset Format

Click to Enlarge
Click to Enlarge

Overview

This document is a specification of the mesh asset format used by Second Life. At its highest level, a mesh asset is a collection of data blocks spread across a file. The sizes, locations, and types of the data elements are described in the header at the beginning of the file. This document will describe the format of the header and each of the data block types it may reference.

Header

The header is an uncompressed, binary encoded LLSD map containing the following elements:

Versioning and Creator Information

Level of Detail

Up to four level of detail blocks may be specified. Level of detail block names are:


Each level of detail entry must contain the following elements:

Physics

Each physics entry must contain a "hash" for validation purposes. The hash is filled in by the simulator at the time of upload and used for every subsequent load to verify that the asset is valid. Each of these entries must also contain an "offset" and "size" as described by the "Level of Detail" section above. There are four physics data blocks:

Skin

A "skin" block may be present and must contain an "offset" and "size" as described in the Level of Detail section above. See below for details.

Mesh Level of Detail Block

Each level of detail block is a gzip'd binary encoded LLSD list of submeshes. Each submesh will map to a "face" in Second Life, and each level of detail MUST have the same number of submeshes. Each level of detail must have a lower triangle count than any higher level of detail. Each submesh contains the following fields:

Vertex Weight Encoding

Each weight entry corresponds to a position in the Position array. Each entry may contain up to 4 influences. Each influence is defined as a 8-bit unsigned joint index followed by a 16-bit unsigned weight value (least significant byte first). A joint index of “0xFF” indicates there are no more influences for this entry. Other than 0xFF, no joint index may have a value >31. If 4 influences have been read for the current entry, it is assumed there are no more influences for this entry.

For example, an entry denoting weights to joints 2 and 3 would contain the values:

0x02 0xWWWW 0x03 0xWWWW 0xFF

Where 0xWWWW represents some arbitrary weight value. An entry denoting weights to joints 1, 2, 3, and 5 would contain the values:

0x01 0xWWWW 0x02 0xWWWW 0x03 0xWWWW 0x05 0xWWWW

No terminating joint index is needed when 4 values are specified. The number of joint influence entries must match the number of positions from the "Position" array above.

Skin Block

The skin block may optionally alter all or part of the default Second Life skeleton. A partial joint list will contain a subset of these joints: mPelvis, mTorso, mChest, mNeck, mHead, mCollarLeft, mShoulderLeft, mElbowLeft, mWristLeft, mCollarRight, mShoulderRight, mElbowRight, mWristRight, mHipRight, mKneeRight, mFootRight, mHipLeft, mKneeLeft, mFootLeft where a full avatar replacement will contain and reference all of these joints.

The skin block is a gzip'd binary encoded LLSD map with the following entries:

Physics Mesh Block

A physics mesh block is the same as a Level of Detail block above, but with the additional constraint that it must not contain any degenerate triangles at 0.5x0.5x0.5 scale as defined by the function ll_is_degenerate in llfloatermodelpreview.cpp.

Physics Convex Block

This block define a single convex hull in "BoundingVerts" and a list of convex hulls in "HullList" and "Positions". Setting the physics shape type of a mesh object to "Prim" will use (in order of preference) the "HullList", the "physics_mesh" level of detail, or the "BoundingVerts" as the physical shape of the object.


"HullList" and "Positions" must NOT be present if header contains a "physics_mesh" entry.

Physics Havok Block

Filled in and used only by simulator.

Physics Cost Data