001: /*
002: * Copyright (c) 2000-2001 Silvere Martin-Michiellot All Rights Reserved.
003: *
004: * Silvere Martin-Michiellot grants you ("Licensee") a non-exclusive,
005: * royalty free, license to use, but not to modify or redistribute this
006: * software in source and binary code form,
007: * provided that i) this copyright notice and license appear on all copies of
008: * the software; and ii) Licensee does not utilize the software in a manner
009: * which is disparaging to Silvere Martin-Michiellot.
010: *
011: * This software is provided "AS IS," without a warranty of any kind. ALL
012: * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY
013: * IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
014: * NON-INFRINGEMENT, ARE HEREBY EXCLUDED. Silvere Martin-Michiellot
015: * AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES
016: * SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
017: * OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL
018: * Silvere Martin-Michiellot OR ITS LICENSORS BE LIABLE
019: * FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT,
020: * INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
021: * CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF
022: * OR INABILITY TO USE SOFTWARE, EVEN IF Silvere Martin-Michiellot HAS BEEN
023: * ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
024: *
025: * This software is not designed or intended for use in on-line control of
026: * aircraft, air traffic, aircraft navigation or aircraft communications; or in
027: * the design, construction, operation or maintenance of any nuclear
028: * facility. Licensee represents and warrants that it will not use or
029: * redistribute the Software for such purposes.
030: *
031: * @Author: Silvere Martin-Michiellot for Digital Biosphere
032: * @Version: 1.1 (to stay in touch with h-anim)
033: *
034: */
035:
036: package com.db.hanim;
037:
038: import javax.vecmath.*;
039:
040: /**
041: * This class is to implement the H-Anim proposed Displacer. It's implementation for Java3D has been mimicked on the VRML97 field description.
042: *
043: * A displacer should be added to one and only one segment in a humanoid hierarchy. This condition is up to be checked by user but should be fairly rare that's why there is no reference to corresponding segment.
044: *
045: * @author Silvere Martin-Michiellot
046: * @version 1.1
047: */
048:
049: public class Displacer {
050:
051: public static final int viseme = 1;
052: public static final int expression = 2;
053: public static final int open_jaw = 3;
054: public static final int lower_t_midlip = 4;
055: public static final int raise_b_midlip = 5;
056: public static final int stretch_l_cornerlip = 6;
057: public static final int stretch_r_cornerlip = 7;
058: public static final int lower_t_lip_lm = 8;
059: public static final int lower_t_lip_rm = 9;
060: public static final int raise_b_lip_lm = 10;
061: public static final int raise_b_lip_rm = 11;
062: public static final int raise_l_cornerlip = 12;
063: public static final int raise_r_cornerlip = 13;
064: public static final int thrust_jaw = 14;
065: public static final int shift_jaw = 15;
066: public static final int push_b_lip = 16;
067: public static final int push_t_lip = 17;
068: public static final int depress_chin = 18;
069: public static final int close_t_l_eyelid = 19;
070: public static final int close_t_r_eyelid = 20;
071: public static final int close_b_l_eyelid = 21;
072: public static final int close_b_r_eyelid = 22;
073: public static final int yaw_l_eyeball = 23;
074: public static final int yaw_r_eyeball = 24;
075: public static final int pitch_l_eyeball = 25;
076: public static final int pitch_r_eyeball = 26;
077: public static final int thrust_l_eyeball = 27;
078: public static final int thrust_r_eyeball = 28;
079: public static final int dilate_l_pupil = 29;
080: public static final int dilate_r_pupil = 30;
081: public static final int raise_l_i_eyebrow = 31;
082: public static final int raise_r_i_eyebrow = 32;
083: public static final int raise_l_m_eyebrow = 33;
084: public static final int raise_r_m_eyebrow = 34;
085: public static final int raise_l_o_eyebrow = 35;
086: public static final int raise_r_o_eyebrow = 36;
087: public static final int squeeze_l_eyebrow = 37;
088: public static final int squeeze_r_eyebrow = 38;
089: public static final int puff_l_cheek = 39;
090: public static final int puff_r_cheek = 40;
091: public static final int lift_l_cheek = 41;
092: public static final int lift_r_cheek = 42;
093: public static final int shift_tongue_tip = 43;
094: public static final int raise_tongue_tip = 44;
095: public static final int thrust_tongue_tip = 45;
096: public static final int raise_tongue = 46;
097: public static final int tongue_roll = 47;
098: public static final int head_pitch = 48;
099: public static final int head_yaw = 49;
100: public static final int head_roll = 50;
101: public static final int lower_t_midlip_o = 51;
102: public static final int raise_b_midlip_o = 52;
103: public static final int stretch_l_cornerlip_o = 53;
104: public static final int stretch_r_cornerlip_o = 54;
105: public static final int lower_t_lip_lm_o = 55;
106: public static final int lower_t_lip_rm_o = 56;
107: public static final int raise_b_lip_lm_o = 57;
108: public static final int raise_b_lip_rm_o = 58;
109: public static final int raise_l_cornerlip_o = 59;
110: public static final int raise_r_cornerlip_o = 60;
111: public static final int stretch_l_nose = 61;
112: public static final int stretch_r_nose = 62;
113: public static final int raise_nose = 63;
114: public static final int bend_nose = 64;
115: public static final int raise_l_ear = 65;
116: public static final int raise_r_ear = 66;
117: public static final int pull_l_ear = 67;
118: public static final int pull_r_ear = 68;
119: public static final int NonStandard = 69;
120:
121: public static final int not_a_default_viseme = 0;
122: public static final int viseme_pbm = 1;
123: public static final int viseme_fv = 2;
124: public static final int viseme_th = 3;
125: public static final int viseme_td = 4;
126: public static final int viseme_kg = 5;
127: public static final int viseme_ts = 6;
128: public static final int viseme_sz = 7;
129: public static final int viseme_nl = 8;
130: public static final int viseme_r = 9;
131: public static final int viseme_a = 10;
132: public static final int viseme_e = 11;
133: public static final int viseme_i = 12;
134: public static final int viseme_q = 13;
135: public static final int viseme_u = 14;
136:
137: public static final int not_a_default_expression = 0;
138: public static final int joy = 1;
139: public static final int sadness = 2;
140: public static final int anger = 3;
141: public static final int fear = 4;
142: public static final int disgust = 5;
143: public static final int surprise = 6;
144:
145: protected String displacerName;
146: protected int[] coordIndex;
147: protected Point3d[] displacements;
148:
149: protected int visemeselect = Displacer.not_a_default_viseme;
150: protected int expressionselect = Displacer.not_a_default_expression;
151:
152: /**
153: * Constructs a new Displacer
154: * @param displacerName the name of the Displacer that describes in a human readable manner the Displacer
155: */
156:
157: public Displacer(String displacerName) {
158:
159: super ();
160: this .setName(displacerName);
161: coordIndex = new int[0];
162: displacements = new Point3d[0];
163:
164: }
165:
166: /**
167: * Gets the Displacer name that describes in a human readable manner the Displacer
168: * @return the String name of this Displacer
169: */
170: public String getName() {
171:
172: return this .displacerName;
173:
174: }
175:
176: /**
177: * Sets the Displacer name that describes in a human readable manner the Displacer
178: * @param displacerName the name of this Displacer
179: */
180: public void setName(String displacerName) {
181:
182: this .displacerName = displacerName;
183:
184: }
185:
186: /**
187: * Gets the Displacer Double array of index coordinates. Please consult H-Anim for the official description of this field.
188: * @return the index coordinates.
189: */
190: public int[] getCoordIndex() {
191:
192: return this .coordIndex;
193:
194: }
195:
196: /**
197: * Sets the Displacer Double array of index coordinates. Please consult H-Anim for the official description of this field.
198: * @param coordIndex index coordinates.
199: */
200: public void setCoordIndex(int[] coordIndex) {
201:
202: this .coordIndex = coordIndex;
203:
204: }
205:
206: /**
207: * Gets the Displacer Point3D array of displacements. Please consult H-Anim for the official description of this field.
208: * @return the displacements.
209: */
210: public Point3d[] getDisplacements() {
211:
212: return this .displacements;
213:
214: }
215:
216: /**
217: * Sets the Displacer Point3D array of displacements. Please consult H-Anim for the official description of this field.
218: * @param displacements the displacements.
219: */
220: public void setDisplacements(Point3d[] displacements) {
221:
222: this .displacements = displacements;
223:
224: }
225:
226: /**
227: * Gets the Displacer description for standard Displacers. See the methods setVisemeSelect() and setExpressionSelect() for special cases Displacer.viseme and Displacer.expression
228: * @return the String official description for the corresponding Displacer
229: */
230: public static String getDisplacerIdentifierDescription(int value) {
231:
232: switch (value) {
233: case Displacer.viseme:
234: return new String(
235: "Set of values determining the mixture of two visemes for this frame (e.g. pbm, fv, th).");
236: case Displacer.expression:
237: return new String(
238: "A set of values determining the mixture of two facial expression.");
239: case Displacer.open_jaw:
240: return new String(
241: "Vertical jaw displacement (does not affect mouth opening).");
242: case Displacer.lower_t_midlip:
243: return new String(
244: "Vertical top middle inner lip displacement.");
245: case Displacer.raise_b_midlip:
246: return new String(
247: "Vertical bottom middle inner lip displacement.");
248: case Displacer.stretch_l_cornerlip:
249: return new String(
250: "Horizontal displacement of left inner lip corner.");
251: case Displacer.stretch_r_cornerlip:
252: return new String(
253: "Horizontal displacement of right inner lip corner.");
254: case Displacer.lower_t_lip_lm:
255: return new String(
256: "Vertical displacement of midpoint between left corner and middle of top inner lip.");
257: case Displacer.lower_t_lip_rm:
258: return new String(
259: "Vertical displacement of midpoint between right corner and middle of top inner lip.");
260: case Displacer.raise_b_lip_lm:
261: return new String(
262: "Vertical displacement of midpoint between left corner and middle of bottom inner lip.");
263: case Displacer.raise_b_lip_rm:
264: return new String(
265: "Vertical displacement of midpoint between right corner and middle of bottom inner lip.");
266: case Displacer.raise_l_cornerlip:
267: return new String(
268: "Vertical displacement of left inner lip corner.");
269: case Displacer.raise_r_cornerlip:
270: return new String(
271: "Vertical displacement of right inner lip corner.");
272: case Displacer.thrust_jaw:
273: return new String("Depth displacement of jaw.");
274: case Displacer.shift_jaw:
275: return new String("Side to side displacement of jaw.");
276: case Displacer.push_b_lip:
277: return new String(
278: "Depth displacement of bottom middle lip.");
279: case Displacer.push_t_lip:
280: return new String("Depth displacement of top middle lip.");
281: case Displacer.depress_chin:
282: return new String(
283: "Upward and compressing movement of the chin (like in sadness).");
284: case Displacer.close_t_l_eyelid:
285: return new String(
286: "Vertical displacement of top left eyelid.");
287: case Displacer.close_t_r_eyelid:
288: return new String(
289: "Vertical displacement of top right eyelid.");
290: case Displacer.close_b_l_eyelid:
291: return new String(
292: "Vertical displacement of bottom left eyelid.");
293: case Displacer.close_b_r_eyelid:
294: return new String(
295: "Vertical displacement of bottom right eyelid.");
296: case Displacer.yaw_l_eyeball:
297: return new String("Horizontal orientation of left eyeball.");
298: case Displacer.yaw_r_eyeball:
299: return new String(
300: "Horizontal orientation of right eyeball.");
301: case Displacer.pitch_l_eyeball:
302: return new String("Vertical orientation of left eyeball.");
303: case Displacer.pitch_r_eyeball:
304: return new String("Vertical orientation of right eyeball.");
305: case Displacer.thrust_l_eyeball:
306: return new String("Depth displacement of left eyeball.");
307: case Displacer.thrust_r_eyeball:
308: return new String("Depth displacement of right eyeball.");
309: case Displacer.dilate_l_pupil:
310: return new String("Dilation of left pupil.");
311: case Displacer.dilate_r_pupil:
312: return new String("Dilation of right pupil.");
313: case Displacer.raise_l_i_eyebrow:
314: return new String(
315: "Vertical displacement of left inner eyebrow.");
316: case Displacer.raise_r_i_eyebrow:
317: return new String(
318: "Vertical displacement of right inner eyebrow.");
319: case Displacer.raise_l_m_eyebrow:
320: return new String(
321: "Vertical displacement of left middle eyebrow.");
322: case Displacer.raise_r_m_eyebrow:
323: return new String(
324: "Vertical displacement of right middle eyebrow.");
325: case Displacer.raise_l_o_eyebrow:
326: return new String(
327: "Vertical displacement of left outer eyebrow.");
328: case Displacer.raise_r_o_eyebrow:
329: return new String(
330: "Vertical displacement of right outer eyebrow.");
331: case Displacer.squeeze_l_eyebrow:
332: return new String(
333: "Horizontal displacement of left eyebrow.");
334: case Displacer.squeeze_r_eyebrow:
335: return new String(
336: "Horizontal displacement of right eyebrow.");
337: case Displacer.puff_l_cheek:
338: return new String("Horizontal displacement of left cheek.");
339: case Displacer.puff_r_cheek:
340: return new String("Horizontal displacement of right cheek.");
341: case Displacer.lift_l_cheek:
342: return new String("Vertical displacement of left cheek.");
343: case Displacer.lift_r_cheek:
344: return new String("Vertical displacement of right cheek.");
345: case Displacer.shift_tongue_tip:
346: return new String("Horizontal displacement of tongue tip.");
347: case Displacer.raise_tongue_tip:
348: return new String("Vertical displacement of tongue tip.");
349: case Displacer.thrust_tongue_tip:
350: return new String("Depth displacement of tongue tip.");
351: case Displacer.raise_tongue:
352: return new String("Vertical displacement of tongue.");
353: case Displacer.tongue_roll:
354: return new String("Rolling of the tongue into U shape.");
355: case Displacer.head_pitch:
356: return new String("Head pitch angle from top of spine.");
357: case Displacer.head_yaw:
358: return new String("Head yaw angle from top of spine.");
359: case Displacer.head_roll:
360: return new String("Head roll angle from top of spine.");
361: case Displacer.lower_t_midlip_o:
362: return new String(
363: "Vertical top middle outer lip displacement.");
364: case Displacer.raise_b_midlip_o:
365: return new String(
366: "Vertical bottom middle outer lip displacement.");
367: case Displacer.stretch_l_cornerlip_o:
368: return new String(
369: "Horizontal displacement of left outer lip corner.");
370: case Displacer.stretch_r_cornerlip_o:
371: return new String(
372: "Horizontal displacement of right outer lip corner.");
373: case Displacer.lower_t_lip_lm_o:
374: return new String(
375: "Vertical displacement of midpoint between left corner and middle of top outer lip.");
376: case Displacer.lower_t_lip_rm_o:
377: return new String(
378: "Vertical displacement of midpoint between right corner and middle of top outer lip.");
379: case Displacer.raise_b_lip_lm_o:
380: return new String(
381: "Vertical displacement of midpoint between left corner and middle of bottom outer lip.");
382: case Displacer.raise_b_lip_rm_o:
383: return new String(
384: "Vertical displacement of midpoint between right corner and middle of bottom outer lip.");
385: case Displacer.raise_l_cornerlip_o:
386: return new String(
387: "Vertical displacement of left outer lip corner.");
388: case Displacer.raise_r_cornerlip_o:
389: return new String(
390: "Vertical displacement of right outer lip corner.");
391: case Displacer.stretch_l_nose:
392: return new String(
393: "Horizontal displacement of left side of nose.");
394: case Displacer.stretch_r_nose:
395: return new String(
396: "Horizontal displacement of right side of nose.");
397: case Displacer.raise_nose:
398: return new String("Vertical displacement of nose tip.");
399: case Displacer.bend_nose:
400: return new String("Horizontal displacement of nose tip.");
401: case Displacer.raise_l_ear:
402: return new String("Vertical displacement of left ear.");
403: case Displacer.raise_r_ear:
404: return new String("Vertical displacement of right ear.");
405: case Displacer.pull_l_ear:
406: return new String("Horizontal displacement of left ear.");
407: case Displacer.pull_r_ear:
408: return new String("Horizontal displacement of right ear.");
409: default:
410: return new String("");
411:
412: }
413:
414: }
415:
416: /**
417: * Gets the Displacer description for expression Displacers. (there is no corresponding official description for viseme displacers that are phonemes in essence)
418: * @return the String official description for the corresponding Displacer
419: */
420: public static String getDisplacerExpressionDescription(int value) {
421:
422: switch (value) {
423: case Displacer.not_a_default_expression:
424: return new String("");
425: case Displacer.joy:
426: return new String(
427: "The eyebrows are relaxed. The mouth is open and the mouth corners pulled back toward the ears.");
428: case Displacer.sadness:
429: return new String(
430: "The inner eyebrows are bent upward. The eyes are slightly closed. The mouth is relaxed.");
431: case Displacer.anger:
432: return new String(
433: "The inner eyebrows are pulled downward and together. The eyes are wide open. The lips are pressed against each other or opened to expose the teeth.");
434: case Displacer.fear:
435: return new String(
436: "The eyebrows are raised and pulled together. The inner eyebrows are bent upward. The eyes are tense and alert.");
437: case Displacer.disgust:
438: return new String(
439: "The eyebrows and eyelids are relaxed. The upper lip is raised and curled, often asymmetrically.");
440: case Displacer.surprise:
441: return new String(
442: "The eyebrows are raised. The upper eyelids are wide open, the lower relaxed. The jaw is opened.");
443: default:
444: return new String("");
445: }
446:
447: }
448:
449: /**
450: * When the Displacer is a viseme, and setVisemeSelect() has been applied, the corresponding viseme is retrieved.
451: * @return the viseme that precisely defines this displacer (if you are using this Diplacer as a viseme)
452: */
453: public int getVisemeSelect() {
454: //name of the displacer must contain expression otherwise returns Displacer.not_a_default_viseme
455:
456: if (contains(this .getName(), "viseme")) {
457: return visemeselect;
458: } else
459: return Displacer.not_a_default_viseme;
460:
461: }
462:
463: /**
464: * If you are using this Diplacer as a viseme use this method to describe the precise viseme you want to use.
465: * @param value the viseme that precisely defines this displacer
466: */
467: public void setVisemeSelect(int value) {
468: //name of the displacer must contain viseme otherwise nothing happens
469:
470: if (contains(this .getName(), "viseme")) {
471: visemeselect = value;
472: }
473:
474: }
475:
476: /**
477: * When the Displacer is an expression, and setVisemeSelect() has been applied, the corresponding expression is retrieved.
478: * @return the expression that precisely defines this displacer (if you are using this Diplacer as an expression)
479: */
480: public int getExpressionSelect() {
481: //name of the displacer must contain expression otherwise returns Displacer.not_a_default_expression
482:
483: if (contains(this .getName(), "expression")) {
484: return expressionselect;
485: } else
486: return Displacer.not_a_default_expression;
487:
488: }
489:
490: /**
491: * If you are using this Diplacer as an expression use this method to describe the precise expression you want to use.
492: * @param value the expression that precisely defines this displacer
493: */
494: public void setExpressionSelect(int value) {
495: //name of the displacer must contain expression otherwise nothing happens
496:
497: if (contains(this .getName(), "expression")) {
498: expressionselect = value;
499: }
500:
501: }
502:
503: private boolean contains(String string1, String string2) {
504: //returns true if string1 contains string2 (ex: orbite contains or) otherwise false
505:
506: boolean found;
507: int i;
508: int margin;
509:
510: found = false;
511: i = 0;
512: margin = string1.length() - string2.length();
513: while (((margin - i) >= 0) && (!found)) {
514: found = string1.regionMatches(i, string2, 0, string2
515: .length());
516: i++;
517: }
518:
519: return found;
520:
521: }
522:
523: }
|