X3D HAnim Displacer Operation

From Web3D.org
Revision as of 21:47, 16 January 2014 by Joedwil (Talk | contribs)

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

HAnim skin with Displacer

Example is here:

[1]http://www.hypermultimedia.com/x3d/hanim/JoeLevel2LOA3SSPYRWRJKDNoGeometry.x3dv

The example combines the single mesh skin animated by joint(s) binding, with a Displacer providing additional animation for specific vertices.

In this case, the 10 standard feature points of the head are 'expanded' by the Displacer.

In practice, Displacer animations for the skin mesh are contained by the first Joint that references the skinCoordIndex of the skin. Following shows the insertion of the Displacer node into the skullBase.

... 
DEF hanim_skullbase HAnimJoint { name "skullbase"    center 0.0 1.63 -0.01 
skinCoordIndex [ 0 1 2 3 4 5 6 7 8 9 ] 
skinCoordWeight [ 1 1 1 1 1 1 1 1 1 1 ] 
 displacers [
    DEF Joe_skull_tipTest Displacer { 
     weight 0 
     name "skull_tip_raiser_action" 
     coordIndex [ 0 1 2 3 4 5 6 7 8 9 ] 
     displacements [ 
0 0.15 0, 
0 0 0.15, 
-0.1 0 0.15,
0.1 0 0.05, 
0 -0.02 0.05, 
-0.15 0 0,
-0.05 0 0, 
0.15 0 0, 
0.05 0 0, 
0 0 -0.15 
  ]
 }
]
children [ ... 

The Displacer is initialized by the weight, coordIndex, and displacements fields as follows:

HAnimDisplacer
 coordIndex   [
  numerical index of each 
  parent geometry vertex 
  to be animated
  index is order of appearance of vertex 
  in user code for parent mesh 
              ]
displacements [
  maximum relative x,y,z displacement 
  in skeleton space 
  of each vertex at maximum weight 
  same order as coordIndex
              ]
weight        0 to 1 
  animation control 
 (from  ScalarInterpolator)
 (linear interpolation)
 0 = same location as parent mesh initial vertex 
 1 = defined maximum relative displacment of parent       mesh vertex 

So, the main idea is to establish displacements that represent the final position of the specified vertex relative to the initial position of the vertex. If the weight value is defined as 0 then there is no added displacement. If the weight is 1 then the vertex is displaced the maximum relative position. If the vertex has been animated by Joint(s) rotation, then this displacement is added to the vertex in the animated position.

Please notice the definitions used in this skin field:

 skin [ ...
0.0 1.77 0.0               #0 skull_tip 
0.0 1.665 0.09             #1 sellion 
-0.033 1.62 0.087          #2 r_infraorbitale 
0.033 1.62 0.087           #3 l_infraorbitale 
0.0 1.55 0.097             #4 supramenton 
-0.077 1.64 -0.01          #5 r_tragion 
-0.0527 1.58 0.015         #6 r_gonion 
0.077 1.64 -0.01           #7 l_tragion 
0.0527 1.58 0.015          #8 l_gonion 
0.0 1.625 -0.0925          #9 nuchale 
  ]... 

Both the initial skin vertex locations and the displacements are given in skeleton space.

For this example, when the Displacer weight is 0, then the skull_tip vertex is animated only as a result of various Joint rotations applied to the skeleton and thus to the skin vertices. If the weight is not 0, then the Displacer displacement value is added to the skull_tip location.

In this example the Displacer is controlled by the following timer and ScalerInterpolator to provide weight values to the Displacer node.

DEF DisplacersAnimation Group {
 children [
DEF skull_tipTestTimer TimeSensor { 
 cycleInterval 5.73 loop TRUE enabled TRUE }
DEF skull_tipTest_Run ScalarInterpolator { 
 key      [ 0 0.1 0.2 0.35 0.65 0.7 0.85 0.95 0.98 1   ] 
 keyValue [ 0 0.2 0.4 0.6  1    1   0.85 0.55 0.25 0 ] }
ROUTE skull_tipTestTimer.fraction_changed TO skull_tipTest_Run.set_fraction
ROUTE skull_tipTest_Run.value_changed TO Joe_skull_tipTest.weight
 ]
}

Sorry I didn't make a button to turn on/off the Displacer timer yet. When you run the example and select Default, only the Displacer animation is running.

Joe