A complete head with facial features and expressions. More...
| Import Statement: | import Clayground.Character3D |
| Inherits: |
Head is a complex body part group containing upper head, lower head (jaw), hair, eyes, ears, nose, and mouth. It supports six animated facial expressions - neutral, joy, sadness, anger, disgust and surprise - plus talking.
The mouth is driven by a small set of continuous shape parameters (mouthOpen, mouthWide, mouthRound, mouthCornerLift, mouthSkew). The expression activities animate these parameters; a speechSource (typically a Speech instance) can take over open/wide/round for lip-synced talking while emotions keep control of the mouth corners.
Example usage:
import Clayground.Character3D Head { skinColor: "#d38d5f" hairColor: "#734120" eyeColor: "#4a3728" hairVolume: 1.2 activity: Head.Activity.ShowJoy }
See also Character, BodyPartsGroup, and Speech.
activity : int |
Current facial expression activity.
Use Head.Activity enum values.
autoBlink : bool |
Whether the eyes blink by themselves.
Off by default, and deliberately so: a lab replays a scene from a seed and compares the frames, so anything moving on its own has to be asked for. When it is on the rhythm is fixed rather than random, for the same reason.
A blink is one animated number here and nothing at all in the scene - the lids are drawn, so closing them costs no geometry and no draw call. As boxes it would have meant resizing an eye every frame of every blink, which is why the eyes never blinked before.
See also blinkInterval and eyeHood.
blinkAmount : real |
How shut the blink currently has the eyes, 0 to 1.
Composes ON TOP of eyeHood rather than replacing it, so a character can blink in the middle of a glare and come back to the glare. Writable, for a caller that would rather drive its own rhythm - a performance script cueing a blink on a line, say - with autoBlink left off.
blinkInterval : int |
Milliseconds between blinks when autoBlink is on.
blinkSeed : int |
Which irregular-but-repeatable blink rhythm this head gets.
Two heads with the same seed blink in step, which is the one thing a crowd must not do; two runs of the same sandbox blink identically, which is what keeps a clayrender comparison meaningful.
browAngle : real |
browFlash : real |
A momentary brow raise on top of whatever the face is wearing.
Additive, in the same units eyeWidth is measured in, so it composes with an emotion rather than replacing it - a listener can acknowledge a point without ceasing to look pleased about it.
See also flashBrows().
browRise : real |
browSkew : real |
How far one brow is raised above the other, as a length.
The three brow numbers are published for the same reason nodAmount is: together with the mouth parameters and the lids they are WHICH expression the face is wearing, and once the brows are shapes in a shader there is no measuring them from outside. A test that has to tell six expressions apart asserts on these rather than on pixels.
chinBottom : real |
Y of the chin, which drops below the head origin while the mouth is open.
chinPointiness : real |
How pointed the chin is (0-1).
Controls the bottom face scaling of the jaw.
crownTop : real |
Y of the top of the skull, hair not included.
detail : int |
Current level of head detail. Use the Head.Detail enum.
Set by Character.detail on a character.
earPos : vector3d |
Origin of the right ear (bottom centre of its box). The left ear is the same point with x negated.
earSize : real |
Edge length of one ear, which is a cube like the eyes.
earTop : real |
Y of the top of the ears.
eyeColor : color |
Colour of the IRISES - not of the eye as a whole.
The white around them is drawn by the face shader and is not a property: there is nothing to set it to. Setting this one white therefore does not make a pale eye, it makes a figure with no pupils.
eyeHood : real |
How far the upper lid is lowered, 0 open to 1 nearly shut.
Closes the eye from ABOVE, leaving the lower edge where it was. The other half of eyeSquint and not interchangeable with it: a lid coming down is a glare or a droop, a lid coming up is a smile.
eyeLine : real |
Y of the eye centres.
Reads the eyes' resting size, so it stays put when a lid closes.
eyeRelief : real |
How far the eyes stand proud of faceFront.
Zero, because the eyes are drawn into the face rather than built in front of it - so a spectacle rim can sit on the face plane and does not have to be pushed clear of a pair of protruding cubes. It stays published because that is the fact accessories need to know, and a head that grows something proud of its face again can say so here without every accessory being re-authored.
eyeSize : real |
Eye size multiplier (0.5 = small, 1.0 = normal, 1.5 = large).
eyeSpacing : real |
How far each eye centre sits from the head's centre line.
eyeSquint : real |
How far the lower lid is raised, 0 open to 1 nearly shut.
The eye closes from BELOW and its top edge stays put, which is what separates a smile from a stare: a face whose only happy signal is at the mouth reads as startled, because nobody smiles with their eyes wide open. Under a big moustache it may be the only signal left.
See also eyeHood.
eyeWidth : real |
Edge length of one eye. The eyes are cubes, so this is their height and depth as well.
faceBack : real |
Z of the back face of the cranium - where hair that wraps the skull has to stop.
faceDetail : int |
How much of the drawn face to draw: 1 all of it, 0 only what survives being small.
At 0 the irises, their highlights, the brows and the mouth corners are skipped and the whites, the lash lines and the lip remain. A shader branch, not a change of geometry - so unlike switching features it cannot pop, and it costs no draw calls either way.
Derived from detail; set that instead.
See also detail and Character::detail.
faceFront : real |
Z of the front face of the cranium - the plane the eyes and the nose stand on.
faceOffsetZ : real |
How far forward of the head node both head boxes sit.
features : bool |
Whether the face is drawn at all - eyes, brows, nose, ears and mouth.
On by default, and no longer something to turn off for performance: the eyes, brows and mouth are drawn into the head's own surfaces and cost no draw calls, so a face is nearly free. Off, the nose and ears go with it, which saves three.
It used to be the single biggest saving available on a character - a face was thirteen boxes out of a head's twenty - and Character.detail switched it off at a distance. That was always the wrong trade: an eye is about a thirtieth of a figure's height, so it is still a pixel or two at a hundred-pixel figure, and its absence reads as a character with no face rather than as a character far away. detail now thins the face instead of deleting it.
See also detail and Character::detail.
gaze : vector2d |
Where the eyes look, as a fraction of the irises' free travel inside the whites. (0,0) is straight ahead, (1,0) hard right.
Costs nothing and moves nothing: the irises are drawn, so aiming them is a uniform rather than a transform. Sliding a built iris sideways would carry it off its own eyeball and break from the side, which is why the head had to be turned for this before.
hairColor : color |
Color of the hair and eyebrows.
hairOuterX : real |
How far from the centre line the head's own side hair reaches.
Half the skull when hairVolume is 0. An arm routed to an ear passes through the side hair unless it is pushed out to at least this.
hairVolume : real |
Hair volume multiplier (0 = bald, 1.0 = normal, 1.5 = voluminous).
jawDrop : real |
How far the chin stretches down when mouthOpen is 1, as a fraction of the lower head height.
The jaw box stretches downward (its top edge stays attached to the upper head), so the chin visibly drops without the face splitting apart - cartoon squash-and-stretch instead of rigid jaw motion.
jawFront : real |
Z of the front face of the jaw - the plane the mouth sits on.
lowerHeadDepth : real |
Depth of the lower head (jaw).
lowerHeadHeight : real |
Height of the lower head (jaw) at rest.
The rendered jaw may momentarily be taller while the mouth is open (see jawDrop).
lowerHeadWidth : real |
Width of the lower head (jaw).
mouthBottom : real |
Y of the lowest point the mouth currently reaches - the bottom of the cavity, which grows downward as it opens.
mouthCornerLift : real |
Mouth corner position from frown (-1) over neutral (0) to smile (1).
Stays under emotion control even while a speechSource drives the other mouth parameters - characters can smile while talking.
mouthLine : real |
Y of the upper lip.
Fixed: the jaw box stretches downward as the mouth opens (see jawDrop) but the mouth line stays where it is on the face.
mouthOpen : real |
How far the mouth/jaw is opened (0 = closed, 1 = fully open).
Driven by the facial activity animations or a speechSource. Readonly on purpose: assigning it directly would break the binding that lets speech drive the mouth. For fully manual mouth control, set speechSource to any object providing speaking, mouthOpen, mouthWide and mouthRound.
mouthRound : real |
How rounded/puckered the mouth is (0-1), e.g. for "oo" sounds.
mouthSize : real |
Mouth size multiplier (0.5 = small, 1.0 = normal, 1.5 = large).
mouthSkew : real |
A one-sided lip curl, -1 to 1. A sneer, not a frown.
The whole mouth tilts and one corner climbs clear of the other, so a face can be lopsided. Everything else here is mirrored, which is why this exists: disgust is the one expression whose whole point is that the two halves disagree, and without it it comes out as a milder anger. Composes with mouthCornerLift - a sneer keeps whatever the corners were already doing.
Under emotion control while a speechSource is talking, exactly as mouthCornerLift is.
See also mouthCornerLift.
mouthWide : real |
How far the mouth is stretched sideways (0-1), e.g. for "ee" sounds.
mouthWidth : real |
Width of the closed, unstretched mouth. What mouthWide and mouthRound do to it is momentary and not included here.
nodAmount : real |
How far into a nod the head is, in degrees.
Its own channel, so it is not readable from offsetEuler - which is the point of the two being separate, and worth a property rather than an explanation.
noseBottom : real |
Y of the underside of the nose - as far down the face as spectacles can slip.
noseSize : real |
Nose size multiplier (0.5 = small, 1.0 = normal, 1.5 = large).
offsetEuler : vector3d |
poseEuler : vector3d |
Where a body animation is aiming the head.
The head is the one joint more than one thing has an opinion about. Everywhere else an animation drives eulerRotation directly, but an aim and a nod are not alternatives - the nod happens WHILE the aim holds, and has to be given back afterwards without the aim having been forgotten.
So the animators drive this, momentary things drive offsetEuler, and the head adds them to baseEuler. Anything animating a head's eulerRotation directly is writing to the sum and will have its value overwritten the next time either part changes.
See also offsetEuler, nod(), and HeadEulerAnim.
skinColor : color |
Color of the skin (face, ears, nose).
speechActive : bool |
True while the speechSource is speaking and driving the mouth.
speechSource : var |
Optional lip-sync driver, typically a Speech instance.
While speechSource.speaking is true, its mouthOpen/mouthWide/mouthRound values control the mouth.
talkDuration : int |
Duration of mouth open/close cycle when talking in milliseconds.
toEmotionDuration : int |
Duration of emotion transition animations in milliseconds.
upperHeadBottom : real |
Y of the seam between jaw and cranium - the bottom of the upper head box.
upperHeadDepth : real |
Depth of the upper head (cranium).
upperHeadHeight : real |
Height of the upper head (cranium).
upperHeadWidth : real |
Width of the upper head (cranium).
void blink() |
Blinks once, now.
Separate from autoBlink so anything that knows a blink belongs here can ask for one - a performance script on a line, or a large gaze shift, which a real face nearly always blinks through.
var expressionTargets(int activity) |
The ten numbers the face settles on for activity, with nothing running: {cornerLift, skew, open, wide, round, hood, squint, browAngle, browRise, browSkew}, in the units the readback properties report (the brow heights already scaled by eyeWidth).
Pure - the table the expression animations ease toward - so a lab can say how far apart two faces are before a frame has been drawn, and a stepped record of a face sheet does not depend on how far an animation happened to have got. An activity that is not an expression (Talk) answers the neutral face.
void flashBrows(real amount) |
Raises the brows and lets them fall.
The one gesture a face makes while somebody else is talking. Fast up, slower down - the reverse reads as a flinch.
void nod(real degrees, int times) |
Nods, and gives the head back.
Down then up, on offsetEuler, so it composes with wherever the head is already aimed - a listener can nod at someone it is looking at without losing them.
degrees defaults to 7, which is a backchannel nod rather than a bow; times defaults to 1.