Flex animation: Difference between revisions

From Valve Developer Community
Jump to navigation Jump to search
Line 199: Line 199:
** For example: having the jaw open (OpenJaw shape, used in the JawV controller) is set to cancel out cheeks puffing in/out (CheekH controller = DeflateCheek & InflateCheek shapes).
** For example: having the jaw open (OpenJaw shape, used in the JawV controller) is set to cancel out cheeks puffing in/out (CheekH controller = DeflateCheek & InflateCheek shapes).
* There is a set of about 100 (!!) corrective shapes, made on a "if you see it break" basis.
* There is a set of about 100 (!!) corrective shapes, made on a "if you see it break" basis.
** The naming convention is [base controller]_[names of shapes it will blend with]_[separated]_[with]_[underscores]
*** For example: openJaw_openLips will fade in whenever both openJaw and openLips shapes are being used, but there are also ones such as OpenJaw_OpenLowerLip_OpenUpperLip_Platysmus_SmileFull!!
** Corrective shapes aren't made for the flexes which can't be seen together (due to domination rules), which somewhat reduce the number of combinations.
** Corrective shapes aren't made for the flexes which can't be seen together (due to domination rules), which somewhat reduce the number of combinations.
** The naming convention is <code>[base controller]_[names of shapes it will blend with]_[separated]_[with]_[underscores]</code>
*** For example: <code>openJaw_openLips</code> will fade in whenever both openJaw and openLips shapes are being used, but there are also ones such as <code>OpenJaw_OpenLowerLip_OpenUpperLip_Platysmus_SmileFull</code>!!
* There is a maximum of 128 controllers. There is no known limit of the number of shapes (it is probably much higher)


Valve's Maya plugins and Varsity's datamodel.py DMX export plugin for Blender (findable [http://code.google.com/p/blender-smd/ here]) can both export shapes into this format.
Valve's Maya plugins and Varsity's datamodel.py DMX export plugin for Blender (findable [http://code.google.com/p/blender-smd/ here]) can both export shapes into this format.

Revision as of 17:15, 9 August 2012

Were you looking for Faceposer help?
Flex shapes in action. TF2 characters in have two versions, pre-authored expressions (regular models) and the HWM (hardware morph) set of shapes. Half-Life 2 characters are based on the FACS, Facial Action Coding System

Flex animation (also called vertex and shape key animation) is the direct manipulation of vertices without the involvement of a skeleton. It is generally used to create facial expressions and lip synch, but can be applied anywhere on the model; Left 4 Dead 2's infected can have their entire head shape changed through flexes.

Warning.pngWarning:Flex has some important limitations in Source:
  • Vertices cannot move more than 8 units (in any or all axes)
  • Each flex can only move vertices in straight lines
  • Flex animation cannot alter collision models
  • Flex animation is not compatible with $scale ("unmatched vertex anims")
  • No more than 10,000 vertices can be flexed per mesh

VTA format

The VTA format stores the morph shape keys separate from the mesh itself. It was used by Valve until the Orange Box. In Valve's newer games, facial animation is entirely defined within the DMX file of the mesh. There is no equivalent in .QC notation for some of the rules that take place in there. Refer to the DMX section down the page to see what has been figured out so far.

Authoring

Maya, Blender, 3DS Max, and XSI can export shape keys to VTA files. See each exporter's documentation for further details.

Valve standard flex

If you are creating a new humanoid character, your best bet is to use the same flex animation rules as Valve. These implement the Facial Action Coding System, a long-standing and widely used method of describing the full range of human expressions.

Confirm:Lip synch requires a set of FACS flexes.

You can find the scripts at sourcesdk_content/hl2/modelsrc/humans_sdk/Male_sdk/. There are two: standardflex_xsi.qci and facerules_xsi.qci. (bodyrules_xsi.qci is related, but as the name implies does not affect the face.)

For the scripts to work, you must have created and exported these standard shape keys in the order given. Then use this QC template:

$definevariable expressions "MyShapes.vta"
$definevariable headBone "ValveBiped.Bip01_Head1"

$eyeposition 0 0 70

$attachment "eyes" $headBone$ 0.043 -4.2197 67.5554 absolute
$attachment "mouth" $headBone$ 1.00 -6.30 0.00 rotate 0 -80 -90


$model facs_example "MyReference.smd" {
	eyeball righteye $headBone$ -1.2711 -4.2197 67.5593 "eyeball_r" 1 4 "pupil_r" 0.63
	eyeball lefteye $headBone$ 1.3572 -4.2197 67.5514 "eyeball_l" 1 -4 "pupil_l" 0.63

	eyelid  upper_right $expressions$ lowerer 1 -0.2621 neutral 0 0.1287 raiser 2 0.2467 split 0.1 eyeball righteye
	eyelid  lower_right $expressions$ lowerer 3 -0.3409 neutral 0 -0.2156 raiser 4 -0.0736 split 0.1 eyeball righteye
	eyelid  upper_left $expressions$ lowerer 1 -0.2621 neutral 0 0.1287 raiser 2 0.2467 split -0.1 eyeball lefteye
	eyelid  lower_left $expressions$ lowerer 3 -0.3409 neutral 0 -0.2156 raiser 4 -0.0736 split -0.1 eyeball lefteye

	mouth 0 "mouth" $headBone$ 0 1 0     // mouth illumination

	flexfile $expressions$ {
		$include "../standardflex_xsi.qci"
	}

	$include "../facerules_xsi.qci"
	// $include "../bodyrules_xsi.qci"

}

See also $model and Eyeball.

Compiling

You should have a exported a VTA and a reference SMD from your modelling package.

$model flextest "myreference.smd" {		// must use $model, not $body, and "{" must be on the same line
	flexfile "myflexanim.vta" {		// source of vertex animations
		defaultflex frame 0		// relaxed position
		flex "Frame1" frame 1
		flex "Frame2" frame 2
	}
	flexcontroller my_group "Flex1" "Flex2"		// defines controllers that will appear in Faceposer etc.
	%Frame1 = Flex1		// assigns a controller to a flex
	%Frame2 = Flex2
}

This defines two flexes and maps them directly onto two controllers.

Icon-Bug.pngBug:HLMV's flex slider boxes are populated from right to left. You will need to resize the window to see them all.  [todo tested in ?]


Defining flexes

Raw flexes are extracted from VTA frames, and support some preprocessing. They are not exposed by the model (flex controllers, below, are).

flex <name> frame <int> [position <normal>] [split <units>] [decay <normal>]
Used within a flexfile block to define a single shape. There can be up to 1024.
name
Internal name of the flex.
frame
The VTA frame the flex refers to.
position
The flex controller position (see also flexcontroller::range) at which this flex will reach full intensity.
split
Makes the flex read only vertices on one side of the mesh's Y origin. The value is the number of units (positive or negative) over which to smooth the divide. 0 disables.
decay
How fleshy the flex looks when animating. Vertex speed is a factor of distance moved: with the default of 1 those that move the most do so instantly, while those that move the least take 0.7 seconds to fully settle.
At 0, there is no lag on even the smallest movements. At over 1, the farthest-moving vertices start to lag too.
flexpair <name> <int> frame <int> [<flex options>]
Same as flex, but automatically creates two flexes with "L" and "R" appended to their names. The unlabelled integer is the equivalent of the split command (split itself is ignored).
defaultflex frame <int> [<flex options>]
Defines the model's relaxed position. The flex created is called "default".

Defining controllers

flexcontroller <group name> [range <normal> <normal>] <controller name> [<controller name> ... ]
An input into the model, used to create animations. Takes the form of a slider. There can be up to 96.
<group name>
Seen with values like eyelid, brow, nose, mouth, and phoneme. Required, but has no apparent effect.
range
Defines the low and high slider values (default 0 and 1). This does not affect the flex itself, but can be used together with flex's position value. Reversing the values makes the slider reverse, not the flex.
<controller name>
As many display names as needed. A controller will be created for each.

Assigning flexes to controllers

It can be very simple:

%myflex = myflexcontroller

Or it can be very complex:

%upper_right_raiser = right_lid_raiser * (1 - right_lid_droop * 0.8) * (1 - right_lid_closer) * (1 - blink)

The following operators are supported:

  • Multiplication (*)
  • Division (/)
  • Addition (+)
  • Subtraction (-)

In all cases, either static numbers or variable/flex/controller names can be used. Flexes will never exceed their position value.

Note.pngNote:Assigning is done outside the flexfile block, but still inside $model.
Icon-Bug.pngBug:Negative values will cause the engine to crash!  [todo tested in ?]
Tip.pngTip:localvar <name> can be used to store results of an equation for re-use later. Once you've defined one, just do %mylocalvar = val.
%mouth

This is a special variable that is read by the mouth shader. When it is 1, the mouth interior is fully illuminated.

LOD

To disable flex, add nofacial to an $lod block.

There is no need to create shapes for your LOD meshes; studiomdl will transfer them from the reference mesh as appropriate.

Stereo flexes (one slider with L/R control)

In order to be combined into a single "stereo" slider with left/right controls in Source Filmmaker or Faceposer, flexes must follow a particular naming convention; they must begin with left_ and right_. Here's an example:

	flexfile "this_is_an_example.vta" {
	  flex     "eyebrowClench" frame 1
	  flexpair "eyebrowRaise" 1.0 frame 2
	  flexpair "eyebrowFurrow" 1.0 frame 3
	  flexpair "outerEyebrowRaise" 1.0 frame 4
	}

	flexcontroller brow eyebrowClench "range" 0.000 1.000
	flexcontroller brow right_eyebrowRaise left_eyebrowRaise "range" 0.000 1.000
	flexcontroller brow right_eyebrowFurrow left_eyebrowFurrow "range" 0.000 1.000
	flexcontroller brow right_outerEyebrowRaise left_outerEyebrowRaise "range" 0.000 1.000
	
	%eyebrowClench = eyebrowClench	 
	%eyebrowRaiseL = left_eyebrowRaise
	%eyebrowRaiseR = right_eyebrowRaise
	%eyebrowFurrowL = left_eyebrowFurrow
	%eyebrowFurrowR = right_eyebrowFurrow
	%outerEyebrowRaiseL = left_outerEyebrowRaise
	%outerEyebrowRaiseR = right_outerEyebrowRaise

Here, eyebrowClench is a "mono" flex, while eyebrowRaise, eyebrowFurrow, and outerEyebrowRaise will be "stereo".

Warning.pngWarning:Your flexcontrollers need to be declared with right/left, not left/right, or else stereo flexes will be offset by one forwards in the list of all flexes, producing rather strange results.

DMX format

Beginning with the Orange Box engine branch, Valve started storing the set of morph shape keys of the models in the same .DMX file as the mesh.

What we know:

  • TF2's HWM models use a standard set of 50 shapes and 32 controllers (the numbers might vary).
    • For example: two shapes, ClenchJaw and OpenJaw, combine into one controller, JawV.
  • A container called DmeCombinationDominationRules in the DMX defines which shapes (not controllers) override others.
    • For example: having the jaw open (OpenJaw shape, used in the JawV controller) is set to cancel out cheeks puffing in/out (CheekH controller = DeflateCheek & InflateCheek shapes).
  • There is a set of about 100 (!!) corrective shapes, made on a "if you see it break" basis.
    • Corrective shapes aren't made for the flexes which can't be seen together (due to domination rules), which somewhat reduce the number of combinations.
    • The naming convention is [base controller]_[names of shapes it will blend with]_[separated]_[with]_[underscores]
      • For example: openJaw_openLips will fade in whenever both openJaw and openLips shapes are being used, but there are also ones such as OpenJaw_OpenLowerLip_OpenUpperLip_Platysmus_SmileFull!!
  • There is a maximum of 128 controllers. There is no known limit of the number of shapes (it is probably much higher)

Valve's Maya plugins and Varsity's datamodel.py DMX export plugin for Blender (findable here) can both export shapes into this format.

Varsity's DMX exporter makes a controller for each shape automatically. The only known way to make controllers using more than one shape (like JawV) and domination rules is by hand. It is assumed Valve automates this process, most likely with a Python script or an internal tool.

Using

Faceposer

See Choreography creation/Creating Events/Facial expressions.

Code

[Todo]