disfigure

Disfigure: User Guide

Figures (creating · anatomy · posture)

Motions (figure · animation · generators )

Customization (accessories · textures)

Using (world · positions · CDN · local web server · nodes)

Figures

Disfigure is a simple library for animating human figures.

Creating a figure

A figure is created as an instance of Man, Woman and Child with an optional parameter for height in meters. The default heights are 1.80 for men, 1.70 for women and 1.35 for children.

var man = new Man( );
var woman = new Woman( 1.75 );
var child = new Child( 1 );

Live examples: figure types and custom heights:

Anatomy of a figure

All figures have the same body structure with names for each body part that can be manipulated.

The central body parts are torso, head, chest and waist. Arms are arm, elbow,forearm and wrist. Legs are leg, thigh, knee, shin, ankle and foot. Hand fingers are thumb, index, middle, ring and pinky.

The names of symmetrical body parts have prefixes l_ for left and r_ for right. Leftness and rightness is always in respect to the figure itself. Fingers phalanges are named after the fingers but with suffixes _mid and _tip (note: thumbs have no middle phalanges).

figure.head        // head
figure.r_knee      // knee of right leg
figure.l_index     // index finger of left hand
figure.l_index_tip // tip phalange of index finger of left hand

Live examples: body parts and fingers with phalanges:

Figure posture

The posture property of a figure describes the rotations of all body parts. It contains version number of an array of rotation angles. The posture property can be used to push a posture to a figure. A read-only property postureString retrieves the posture as a string.

figure.posture = {version:9, angles:[[-15,44,10],[5,82,-24],...]};
figure.posture = anotherFigure.posture;

var str = figure.postureString;

A posture could be defined as a blend of other postures. Method blend mixes two postures with a blending coefficient. When the coefficient is 0 the result is the first posture, when it is 1 the result is the second and when it is between 0 and 1 the result is a posture between both postures.

figure.blend( initialPosture, finalPosture, 0.5 );

Live examples: posture data and posture blending:

Motions

The motion of a figure is done by manipulating properties of the figure or its body parts.

Figure position

The position of the figure within the 3D is controlled by its .position property with subproperties .x, .y and .z. Technically, the position is Vector3 object.

figure.position.set( 1, 0, 0.5 );
figure.position.y = -0.1;

Live examples: figure position and figure motion:

Figure motion

Each figure has three main axes:

Body parts have properties .x, .y and .z which define the rotation around the corresponding axes. Angles of rotations are in degrees.

Central body

The central body contains body parts in the middle of the figure – head, chest, waist and the torso. They have no left and right variants. The motions of central body parts follow the same axes of rotations.

figure.head.x = 40;
figure.chest.z = 10;
figure.waist.z = -30;

Live examples: axes of rotations and motion of head, chest and waist:

Legs and arms

A leg is made of leg, thigh, knee, shin, ankle and foot. An arm is made of arm, elbow, forearm and wrist. These body parts are left and right and the rotation around Y and Z axes is symmetrical and horizontally flipped as if mirrored. Note that some motions might look counterintuitive when two or three rotation are applied on the same body part. This is due to rotations being non-commutative.

figure.l_knee.x = 40;
figure.r_ankle.x = 10;
figure.l_elbow.y = 45;
figure.r_wrist.z = -20;

Live examples: motion of legs and motion of arms:

Fingers

Only hand fingers are presented as individual body parts. Fingers are thumb, index, middle, ring and pinky. They are always used with prefixes l_ or r_. Fingers have phalanges which are identified with sufix _mid (for middle) and _tip (for end) phalange. Note that the thumb has no middle phalange.

figure.l_thumb.x = 20;
figure.r_index.z = 45;
figure.r_index_mid.z = 30;
figure.r_index_tip.z = 15;

Live examples: motion of fingers and motion of phalanges:

Figure animation

A default Disfigure world manages figure animation in two ways – via animation loop or animation event. The function setAnimationLoop registers a user-defined function that is called automatically each frame. The function accepts a parameter time with the current time in milliseconds.

setAnimationLoop( animate );

function animate( time ) {
   
   // executed once per frame
   
}

Alternatively the window object may listen to animate events that are generated every frame with property event.time holds the current time in milliseconds. The animate event is also sent to individual figures and in this case the figure itself is in event.target.

window.addEventListener( 'animate', animate );

function animate ( event ) {

   var time = event.time;

   // executed once per frame
   
}

figure.addEventListener( 'animate', animate );

function animate ( event ) {

   var time = event.time,
       figure = event.target;

   // executed once per frame
   
}

Live examples: animation loop and animation event:

Number generators

Disfiure provide three number generators – these are functions that generate sequences of numbers used in animations. The random generator creates uniformly distributed random numbers within interval. The regular generator creates oscillation of values within interval. The chaotic generator combines randomness and smoothness – it creates smoothe sequence of numbers that gradually oscillate between randomly selected values in interval.

Random generator needs only interval, while regular and chaotic generators need time, offset and interval.

figure1.head.y = random( -30, 30 );
figure2.head.y = regular( time, 0, -30, 30 );
figure3.head.y = chaotic( time, 0, -30, 30 );

Live examples: generators graphs and generators animations:

Figure customization

Accessories

Accessories are Three.js objects attached to a specific body part. They do not deform, but move as if attached to the body. The accessory own position and rotation properties are in respect to the origin of the hosting body part.

figure.l_arm.attach(object);

Live examples: attach one accessory and many acccessories:

TSL textures

Disfigure is compatible with most TSL Textures – real-time textures generated via TSL. To use a TSL Texture it must be imported as well as all Three.js classex that are used. Textures are provided as functions. The result of these functions are to be assigned to material nodes, usually .colorNode.

import * as Three from "three";
import { camouflage } from "https://cdn.jsdelivr.net/npm/tsl-textures@3.0.1/dist/tsl-textures.min.js";
:
figure.material.colorNode = camouflage ( {
	scale: 3,
	colorA: new Three.Color(12762792),
	colorB: new Three.Color(10258782),
	colorC: new Three.Color(9610101),
	colorD: new Three.Color(7435617),
} );

Live examples: single texture and multiple textures:

Using Disfigure

Provisional world

Disfigure provides a predefined default 3D world with all basic options, like camera, lights, ground, user navigations and so on.

Options for the environment:

Options for figure:

new World( {ground: false, stats: true, men:100} );

If a provisional world instance is created, it adds global variables:

Depending on options initialing a world may also create:

It is not compulsory to the a provisional world. A program may dafine its custom Three.js world. In this case the figures should be added to the scene via their pool property, and the animation loop must call update method:

var man = new Man( );

scene.add( man.pool );

function animationLoop( t ) {

	man.update();
	...
	renderer.render( scene, camera );
}

Live examples: variation of default world and customized world:

Local positions

Disfigure provides additional methods for querying and managing positions besides the traditional .position property.

The pointAt method extracts the global coordinates of a point related to a body part. Each body part has own coordinate system and the point is defined in this local coordinate system.

The lockTo moves the whole figure so that the local point of a body part is mapped to the global point. This can be used to keep a figure standing on the ground (by locking its feet to level 0).

pos = figure.l_arm.pointAt(0,0.1,0);

figure.l_wrist.lockTo(0,1.5,0,0.2, -0.01,0.01);

Using with CDN

Content Delivery Network (CDN). serves as a host of the library files. At the time of writing this document it is recommended to use jsDelivr as CDN. Other CDNs are also available.

The main advantages of using a CDN are:

The main disadvantages of using a CDN are:

A minimal program that uses Disfigure.js from a CDN needs to define 4 import maps: three, three/webgpu, three/tsl and three/addons. Preferably disfigure could also be defined.

<!DOCTYPE html>

<script type="importmap">
  {
    "imports": {
      "three": "https://cdn.jsdelivr.net/npm/three@0.184.0/build/three.webgpu.min.js",
      "three/webgpu": "https://cdn.jsdelivr.net/npm/three@0.184.0/build/three.webgpu.min.js",
      "three/tsl": "https://cdn.jsdelivr.net/npm/three@0.184.0/build/three.tsl.min.js",
      "three/addons/": "https://cdn.jsdelivr.net/npm/three@0.184.0/examples/jsm/",
      "disfigure": "https://cdn.jsdelivr.net/gh/boytchev/disfigure@main/dist/disfigure.min.js"
    }
  }
</script>

<script type="module">

  import {World, Man} from 'disfigure';

  new World;
  new Man;

</script>

Live example: minimal CDN:

Note: many of the examples in this document use the script importmap.js to generate the import maps and inject them in the page. This is done solely for maintaining shorter code and to easily switch to other versions of either Three.js or Disfigure.js.

Using with local web server

A local web server could provide files just as CDN. The only change is the importmap – it should point the local files. Note that all files must be accessed via https.

The main advantages of using only local files are:

The main disadvantages of using only local files are:

Using with node.js

The library is provided as a NPM package. If node.js is installed on the user machine, it should be possible to install disfigure.js and use it directly.

The main advantages of using node.js:

The main disadvantages of using using node.js:

Note: This approach is not tested. If you find that it is not working and you know how to fix it, please get in touch.

Home · GitHub · Legacy NPM