DMX model
Jump to navigation
Jump to search
For sanity's sake, the data structure is expressed in pseudo-C++.
- Todo: Are names case sensitive?
class DmeModelRoot
{
// model and skeleton should point to the same object
DmeModel* model;
DmeModel* skeleton;
DmeCombinationOperator* combinationOperator; // flex animations only
};
class DmeCombinationOperator // flex controller global settings
{
DmeCombinationInputControl controls[];
Vector controlValues[]; // rest position...but why a 3D vector?
Vector controlValuesLagged[]; // unknown
bool usesLaggedValues;
DmeMesh* dominators[]; // unknown
DmeMesh* targets[]; // mesh with the shapes on
};
class DmeCombinationInputControl // a flex controller
{
CUtlString rawControlNames[]; // which controls are being wrapped
bool stereo; // equivalent to QC 'split'?
bool eyelid; // flags as an eyelid used by AI for blinking
float wrinkleScales[]; // wrinkle map, a recent tech that is not documented yet. One value for each named control.
};
class DmeModel
{
DmeTransform* transform; // global model transform? DAG not supported here?
DmeAttachment* shape;
bool visible;
DmeModel children[];
DmeJoint jointList[];
DmeVertexData BaseStates[];
CUtlString upAxis; // uppercase character
};
// A "DAG" is a generic Maya container, appearing here in order to transform objects.
// It can take the place of a DmeMesh, DmeJoint or DmeAttachment at any time.
class DmeDag
{
DmeTransform* transform;
bool visible;
void children[]; // never seen used
// One of the following:
CUtlString name // of a DmeJoint
DmeMesh* shape;
DmeAttachment* shape;
};
class DmeJoint // a bone
{
DmeTransform* transform;
void* shape; // only seen empty
bool visible;
DmeJoint children[];
bool lockInfluenceWeights;
class DmeTransform // name is of a defined model if there are children, otherwise blank
{
Vector position;
Quaternion orientation;
};
class DmeAttachment // an attachment
{
bool visible;
bool IsRigid; // does not animate with associated bone
bool isWorldAligned; // transform in world co-ords
};
class DmeMesh
{
bool visible;
DmeVertexData bindState; // needs confirmation - only seen empty
DmeVertexData* currentState; // pointer to default baseState
DmeVertexData baseStates[]; // never seen with more than one member
DmeVertexData deltaStates[]; // unknown
DmeFaceSet faceSets[];
Vector2D deltaStateWeights[];
Vector2D deltaStateWeightsLagged[];
};
class DmeVertexData // mesh data
{
CUtlString vertexFormat[]; // positions, normals, textureCoordinates
int jointCount; // what is this doing here?
bool flipVCoordinates; // left-hand to right hand?
// In each of the below cases, the "Indicies" value contains one entry for each vertex.
// the indice value defines which value from the 'real' array the vertex takes. In this
// way, vertices can share data. This is a useful optimisation since each poly has its
// own three verts, even if they overlap other verts.
Vector positions[]; // location of each vertex
int positionsIndicies[]; // unknown
Vector normals[]; // normal of each vertex
int normalsIndicies[]; // unknown
Vector2D textureCoordinates[]; // UV co-ord of each vertex
int textureCoordinatesIndicies[]; // the vertex that each value applies to -
};
class DmeFaceSet // defines faces, including their material
{
DmeMaterial* material; // the material this face is drawn with
int faces[]; // the vertices that make up each face, delimited by -1. Supports quads.
};
class DmeMaterial // a material
{
CUtlString mtlName; // relative to \game\materials\, no extension
};