/*
* Copyright (c) 2000-2001 Silvere Martin-Michiellot All Rights Reserved.
*
* Silvere Martin-Michiellot grants you ("Licensee") a non-exclusive,
* royalty free, license to use, but not to modify or redistribute this
* software in source and binary code form,
* provided that i) this copyright notice and license appear on all copies of
* the software; and ii) Licensee does not utilize the software in a manner
* which is disparaging to Silvere Martin-Michiellot.
*
* This software is provided "AS IS," without a warranty of any kind. ALL
* EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY
* IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
* NON-INFRINGEMENT, ARE HEREBY EXCLUDED. Silvere Martin-Michiellot
* AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES
* SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
* OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL
* Silvere Martin-Michiellot OR ITS LICENSORS BE LIABLE
* FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT,
* INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
* CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF
* OR INABILITY TO USE SOFTWARE, EVEN IF Silvere Martin-Michiellot HAS BEEN
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
*
* This software is not designed or intended for use in on-line control of
* aircraft, air traffic, aircraft navigation or aircraft communications; or in
* the design, construction, operation or maintenance of any nuclear
* facility. Licensee represents and warrants that it will not use or
* redistribute the Software for such purposes.
*
* @Author: Silvere Martin-Michiellot for Digital Biosphere
* @Version: 1.1 (to stay in touch with h-anim)
*
*/
package com.db.hanim;
import java.util.*;
import javax.media.j3d.Interpolator;
/**
* This class is to implement a GestureLevelsOfAnimation checker. Basically, given a humanoid, it ouputs an integer that gives the level of compliance of this humanoid against a standard pre-defined set of Joints and Sites. This integer ranges from -1 to 3, -1 meaning that it does not comply with any level of animation. This is feature that did not exist in H-Anim specification but we felt it would be useful if implemented. It's behavior is similar to HAnimLevelsOfAnimation. See also HAnimLevelsOfAnimation for compliance of humanoids against the same set of pre-defined Joints and Sites.
* Please read the H-Anim specification for more information.
*
* Please note that there is a problem in H-Anim with sites since:
* 1. a H-Anim level 1 compatible avatar should contain:
* l_middistal_tip, r_middistal_tip, l_hand_tip, r_hand_tip (among others)
* 2. a H-Anim level 2 compatible avatar should contain:
* l_forefoot_tip, r_forefoot_tip, l_middle_distal_tip, r_middle_distal_tip (among others)
* but not the four Sites given in 1.
* This is a problem since levels of articulation are given in ascendant order
* however, l_middistal_tip is just the same name for l_forefoot_tip (and so on for the other three).
*
* Therefore we assume that an avatar is level 1 compatible if it contains either of each pair
* (both of a pair could be considered as an error but we assume that users won't use both)
* (same conditions applies for higher order levels).
*
* The following joints are not included in the loa also they are defined by H-Anim
* it is assumed they are level 4 (all non standard joints):
* Joint.l_eyelid_joint;
* Joint.r_eyelid_joint;
* Joint.l_eyebrow_joint;
* Joint.r_eyebrow_joint;
* Joint.temporomandibular;
* Joint.NonStandard;
*
* @author Silvere Martin-Michiellot
* @version 1.1
*/
public final class GestureLevelsOfAnimation {
//indexes for loaJoints given in ascendant order
//Joint.HumanoidRoot, Joint.sacroiliac, Joint.l_hip, Joint.l_knee, Joint.l_ankle, Joint.l_subtalar,
//Joint.l_midtarsal, Joint.l_metatarsal, Joint.r_hip, Joint.r_knee, Joint.r_ankle, Joint.r_subtalar,
//Joint.r_midtarsal, Joint.r_metatarsal, Joint.vl5, Joint.vl4, Joint.vl3, Joint.vl2, Joint.vl1,
//Joint.vt12, Joint.vt11, Joint.vt10, Joint.vt9, Joint.vt8, Joint.vt7, Joint.vt6, Joint.vt5, Joint.vt4,
//Joint.vt3, Joint.vt2, Joint.vt1, Joint.vc7, Joint.vc6, Joint.vc5, Joint.vc4, Joint.vc3, Joint.vc2,
//Joint.vc1, Joint.skullbase, Joint.l_eyelid_joint, Joint.r_eyelid_joint, Joint.l_eyeball_joint,
//Joint.r_eyeball_joint, Joint.l_eyebrow_joint, Joint.r_eyebrow_joint, Joint.temporomandibular,
//Joint.l_sternoclavicular, Joint.l_acromioclavicular, Joint.l_shoulder, Joint.l_elbow, Joint.l_wrist,
//Joint.l_thumb1, Joint.l_thumb2, Joint.l_thumb3, Joint.l_index0, Joint.l_index1, Joint.l_index2,
//Joint.l_index3, Joint.l_middle0, Joint.l_middle1, Joint.l_middle2, Joint.l_middle3, Joint.l_ring0,
//Joint.l_ring1, Joint.l_ring2, Joint.l_ring3, Joint.l_pinky0, Joint.l_pinky1, Joint.l_pinky2,
//Joint.l_pinky3, Joint.r_sternoclavicular, Joint.r_acromioclavicular, Joint.r_shoulder, Joint.r_elbow,
//Joint.r_wrist, Joint.r_thumb1, Joint.r_thumb2, Joint.r_thumb3, Joint.r_index0, Joint.r_index1,
//Joint.r_index2, Joint.r_index3, Joint.r_middle0, Joint.r_middle1, Joint.r_middle2, Joint.r_middle3,
//Joint.r_ring0, Joint.r_ring1, Joint.r_ring2, Joint.r_ring3, Joint.r_pinky0, Joint.r_pinky1,
//Joint.r_pinky2, Joint.r_pinky3, Joint.NonStandard
//the following joints are not included in the loa also they are defined by h-anim
//it is assumed they are level 4 (all non standard joints)
//Joint.l_eyelid_joint;
//Joint.r_eyelid_joint;
//Joint.l_eyebrow_joint;
//Joint.r_eyebrow_joint;
//Joint.temporomandibular;
//Joint.NonStandard;
static int[] loaJointsTable = {
0, 1, 1, 1, 1, 2, 1, 2, 1, 1,
1, 2, 1, 2, 1, 3, 2, 3, 2, 3,
3, 2, 3, 3, 3, 2, 3, 3, 3, 3,
2, 3, 3, 3, 2, 3, 2, 3, 1, 4,
4, 3, 3, 4, 4, 4, 2, 2, 1, 1,
1, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 1, 1, 1, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 4};
//Sites are not used for Gestures, only Joints move and the rest follows
static int loa0Joints, loa1Joints, loa2Joints, loa3Joints, loa4Joints;
static boolean[] definedJoints;
/**
* Construct a new GestureLevelsOfAnimation. This class has only to be instanciated once.
*/
public GestureLevelsOfAnimation() {
//static because of method: beware of concurrent access !
definedJoints = new boolean[loaJointsTable.length];
loa0Joints = 0;
loa1Joints = 0;
loa2Joints = 0;
loa3Joints = 0;
loa4Joints = 0;
//recompute the number of joints per level just in case a developper (you ?) modify the standard list of joints
for (int i=0; i<loaJointsTable.length; i++) {
switch (loaJointsTable[i]) {
case 0: loa0Joints++;
break;
case 1: loa1Joints++;
break;
case 2: loa2Joints++;
break;
case 3: loa3Joints++;
break;
default: loa4Joints++;
break;
}
}
}
/**
* Gets the int level of compatibility of this gesture. See com.db.hanim.HAnimLevelsOfAnimation for more details.
* There must be at least one Position, Rotation, Rotation & Position Interpolator for each Joint
* defined in a Level Of Animation for the Gesture to be of that Level Of Animation.
* There is no check about the duration of any Interpolator.
*
* @param gesture the Gesture to check the level of compatibility
* @return the int from -1 to 3 certifying corresponding level of compatibility
*/
public static int getLevelOfCompatibility(Gesture gesture) {
//there must be at least one Position, Rotation, Rotation & Position Interpolator for each Joint
//defined in a Level Of Animation for the Gesture to be of that Level Of Animation
//there is no check about the duration of any Interpolator
//we can sum the number of joints for each level to compare with the standard number for each level
//doing this saves a lot of computer time
int loa0FoundJoints, loa1FoundJoints, loa2FoundJoints, loa3FoundJoints, loa4FoundJoints;
Enumeration enumeration;
if (gesture!=null) {
//clear definedJoints
for (int i=0; i<definedJoints.length; i++) {
definedJoints[i]=false;
}
loa0FoundJoints = 0;
loa1FoundJoints = 0;
loa2FoundJoints = 0;
loa3FoundJoints = 0;
loa4FoundJoints = 0;
//browse the BranchGroup
enumeration = gesture.getBranchGroup().getAllChildren();
while (enumeration.hasMoreElements()) {
definedJoints[Joint.getJointIdentifierNumber((String)(((Interpolator)enumeration.nextElement()).getUserData()))] = true;
}
//compute the sums for Joints
for (int i=0; i<definedJoints.length;i++) {
if (definedJoints[i]) {
switch (loaJointsTable[i]) {
case 0: loa0FoundJoints++;
break;
case 1: loa1FoundJoints++;
break;
case 2: loa2FoundJoints++;
break;
case 3: loa3FoundJoints++;
break;
default: loa4FoundJoints++;
break;
}
}
}
//return loa
if (loa0Joints==loa0FoundJoints) {
if (loa1Joints==loa1FoundJoints) {
if (loa2Joints==loa2FoundJoints) {
if (loa3Joints==loa3FoundJoints) {
return 3;
}
else return 2;
}
else return 1;
}
else return 0;
}
else return -1;
}
else return -1;
}
}
|