/* chara.c - Don Yang (uguu.org) 05/19/03 */ /*@ -realcompare -usedef @*/ #include"global.h" #include"chara.h" #include"core.h" /* Keyframe data. See core.c and gen_ssa.pl */ enum /* Interpolation types */ { iZR = 0, iLN, iQI, iQO /* Constant, linear, quadratic in, quadratic out */ }; enum /* Parameter indexes */ { kTime = 0, kX, kY, kXZScale, kYScale, kRotateY, kRotateZ, kParamCount }; typedef struct { float x[kParamCount]; int i[kParamCount - 1]; } KPARAM; static const KPARAM KeyframeParamNULL[3] = { {{0.0f,0.0f,0.0f,1.2f,0.8f,0.0f,0.0f}, {iZR,iZR,iLN,iLN,iZR,iZR}}, {{0.5f,0.0f,0.0f,1.0f,1.0f,0.0f,0.0f}, {iZR,iZR,iLN,iLN,iZR,iZR}}, {{1.0f,0.0f,0.0f,1.2f,0.8f,0.0f,0.0f}, {iZR,iZR,iZR,iZR,iZR,iZR}} }; static const KPARAM KeyframeParam1[22] = /* duun doobi doowa shoobi... */ { /* time x y sxz sy ry rz */ /* 0*/ {{0.0000f, 0.0000f, 0.0f, 1.2f, 0.8f, 0.0f, 0.0f}, /* duun */ { iZR, iQI, iQI, iQI, iZR, iZR}}, /* 1*/ {{0.0625f, 0.0000f, 2.0f, 0.8f, 1.3f, 0.0f, 0.0f}, { iZR, iQO, iQO, iQO, iZR, iZR}}, /* 2*/ {{0.1250f, 0.0000f, 0.0f, 1.2f, 0.8f, 0.0f, 0.0f}, /* doobi */ { iZR, iQI, iQI, iQI, iZR, iZR}}, /* 3*/ {{0.1875f, 0.0000f, 1.5f, 0.8f, 1.3f, 0.0f, 0.0f}, { iZR, iQO, iQO, iQO, iZR, iZR}}, /* 4*/ {{0.2500f, 0.0000f, 0.0f, 1.2f, 0.8f, 0.0f, 0.0f}, /* doowa */ { iZR, iQI, iQI, iQI, iZR, iZR}}, /* 5*/ {{0.3125f, 0.0000f, 1.5f, 0.8f, 1.3f, 0.0f, 0.0f}, { iZR, iQO, iQO, iQO, iZR, iZR}}, /* 6*/ {{0.3750f, 0.0000f, 0.0f, 1.2f, 0.8f, 0.0f, 0.0f}, { iLN, iZR, iLN, iLN, iZR, iZR}}, /* 7*/ {{0.3900f,-0.0150f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f}, { iLN, iZR, iZR, iZR, iZR, iZR}}, /* 8*/ {{0.4225f,-0.0475f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f}, { iLN, iZR, iLN, iLN, iZR, iZR}}, /* 9*/ {{0.4375f,-0.0625f, 0.0f, 1.2f, 0.8f, 0.0f, 0.0f}, /* shoo */ { iLN, iQI, iQI, iQI, iZR, iZR}}, /*10*/ {{0.4766f,-0.0200f, 1.8f, 0.8f, 1.3f, 0.0f, 0.0f}, { iLN, iQO, iQO, iQO, iZR, iZR}}, /*11*/ {{0.5156f, 0.0000f, 0.0f, 1.2f, 0.8f, 0.0f, 0.0f}, /* bi */ { iZR, iQI, iQI, iQI, iZR, iZR}}, /*12*/ {{0.5547f, 0.0000f, 1.1f, 0.8f, 1.3f, 0.0f, 0.0f}, { iZR, iQO, iQO, iQO, iZR, iZR}}, /*13*/ {{0.5938f, 0.0000f, 0.0f, 1.2f, 0.8f, 0.0f, 0.0f}, /* doo */ { iZR, iQI, iQI, iQI, iZR, iZR}}, /*14*/ {{0.6328f, 0.0000f, 1.1f, 0.8f, 1.3f, 0.0f, 0.0f}, { iZR, iQO, iQO, iQO, iZR, iZR}}, /*15*/ {{0.6719f, 0.0000f, 0.0f, 1.2f, 0.8f, 0.0f, 0.0f}, /* bi */ { iZR, iQI, iQI, iQI, iZR, iZR}}, /*16*/ {{0.7109f, 0.0000f, 1.1f, 0.8f, 1.3f, 0.0f, 0.0f}, { iZR, iQO, iQO, iQO, iZR, iZR}}, /*17*/ {{0.7500f, 0.0000f, 0.0f, 1.2f, 0.8f, 0.0f, 0.0f}, /* dan */ { iZR, iQI, iQI, iQI, iZR, iZR}}, /*18*/ {{0.8125f, 0.0000f, 1.5f, 0.8f, 1.3f, 0.0f, 0.0f}, { iZR, iQO, iQO, iQO, iZR, iZR}}, /*19*/ {{0.8750f, 0.0000f, 0.0f, 1.2f, 0.8f, 0.0f, 0.0f}, /* dan */ { iZR, iQI, iQI, iQI, iZR, iZR}}, /*20*/ {{0.9375f, 0.0000f, 1.5f, 0.8f, 1.3f, 0.0f, 0.0f}, { iZR, iQO, iQO, iQO, iZR, iZR}}, /*21*/ {{1.0000f, 0.0000f, 0.0f, 1.2f, 0.8f, 0.0f, 0.0f}, { iZR, iZR, iZR, iZR, iZR, iZR}} }; static const KPARAM KeyframeParam2[19] = { /* time x y sxz sy ry rz */ /* 0*/ {{0.0000f, 0.0000f, 0.0f, 1.2f, 0.8f, 0.0f, 0.0f}, /* shoo */ { iZR, iQI, iQI, iQI, iZR, iZR}}, /* 1*/ {{0.0313f, 0.0000f, 0.5f, 0.8f, 1.3f, 0.0f, 0.0f}, { iZR, iQO, iQO, iQO, iZR, iZR}}, /* 2*/ {{0.0625f, 0.0000f, 0.0f, 1.2f, 0.8f, 0.0f, 0.0f}, /* bi */ { iZR, iQI, iQI, iQI, iZR, iZR}}, /* 3*/ {{0.0938f, 0.0000f, 0.5f, 0.8f, 1.3f, 0.0f, 0.0f}, { iZR, iQO, iQO, iQO, iZR, iZR}}, /* 4*/ {{0.1250f, 0.0000f, 0.0f, 1.2f, 0.8f, 0.0f, 0.0f}, /* doo */ { iZR, iQI, iQI, iQI, iZR, iZR}}, /* 5*/ {{0.1563f, 0.0000f, 0.5f, 0.8f, 1.3f, 0.0f, 0.0f}, { iZR, iQO, iQO, iQO, iZR, iZR}}, /* 6*/ {{0.1875f, 0.0000f, 0.0f, 1.2f, 0.8f, 0.0f, 0.0f}, /* bi */ { iZR, iQI, iQI, iQI, iZR, iZR}}, /* 7*/ {{0.2188f, 0.0000f, 0.5f, 0.8f, 1.3f, 0.0f, 0.0f}, { iZR, iQO, iQO, iQO, iZR, iZR}}, /* 8*/ {{0.2500f, 0.0000f, 0.0f, 1.2f, 0.8f, 0.0f, 0.0f}, /* du */ { iZR, iQI, iQI, iQI, iZR, iZR}}, /* 9*/ {{0.2813f, 0.0000f, 0.5f, 0.8f, 1.3f, 0.0f, 0.0f}, { iZR, iQO, iQO, iQO, iZR, iZR}}, /*10*/ {{0.3125f, 0.0000f, 0.0f, 1.2f, 0.8f, 0.0f, 0.0f}, /* dan */ { iZR, iQI, iQI, iQI, iZR, iZR}}, /*11*/ {{0.3750f, 0.0000f, 1.3f, 0.8f, 1.3f, 0.0f, 0.0f}, { iZR, iQO, iQO, iQO, iZR, iZR}}, /*12*/ {{0.4375f, 0.0000f, 0.0f, 1.2f, 0.8f, 0.0f, 0.0f}, /* dan */ { iZR, iQI, iQI, iQI, iZR, iZR}}, /*13*/ {{0.5000f, 0.0000f, 1.3f, 0.8f, 1.3f, 0.0f, 0.0f}, { iZR, iQO, iQO, iQO, iZR, iZR}}, /*14*/ {{0.5625f, 0.0000f, 0.0f, 1.2f, 0.8f, 0.0f, 0.0f}, { iZR, iLN, iLN, iLN, iZR, iLN}}, /*15*/ {{0.6250f, 0.0000f, 0.6f, 1.0f, 1.0f, 0.0f, -51.4f}, { iZR, iLN, iZR, iZR, iZR, iLN}}, /*16*/ {{0.7813f, 0.0000f, 1.5f, 1.0f, 1.0f, 0.0f, -180.0f}, { iZR, iLN, iZR, iZR, iZR, iLN}}, /*17*/ {{0.9375f, 0.0000f, 0.6f, 1.0f, 1.0f, 0.0f, -308.6f}, { iZR, iLN, iLN, iLN, iZR, iLN}}, /*18*/ {{1.0000f, 0.0000f, 0.0f, 1.2f, 0.8f, 0.0f, -360.0f}, { iZR, iZR, iZR, iZR, iZR, iZR}} }; static const KPARAM KeyframeParam3[17] = /* la la la la */ { /* time x y sxz sy ry rz */ /* 0*/ {{0.0000f, 0.0000f, 0.0f, 1.2f, 0.8f, 0.0f, 0.0f}, /* la */ { iZR, iQI, iQI, iQI, iZR, iZR}}, /* 1*/ {{0.0625f, 0.0000f, 1.5f, 0.8f, 1.3f, 0.0f, 0.0f}, { iZR, iQO, iQO, iQO, iZR, iZR}}, /* 2*/ {{0.1250f, 0.0000f, 0.0f, 1.2f, 0.8f, 0.0f, 0.0f}, { iLN, iZR, iQI, iQI, iZR, iZR}}, /* 3*/ {{0.1875f,-0.0625f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f}, { iLN, iZR, iQO, iQO, iZR, iZR}}, /* 4*/ {{0.2500f,-0.1250f, 0.0f, 1.2f, 0.8f, 0.0f, 0.0f}, /* la */ { iLN, iQI, iQI, iQI, iZR, iZR}}, /* 5*/ {{0.3125f,-0.0625f, 1.5f, 0.8f, 1.3f, 0.0f, 0.0f}, { iLN, iQO, iQO, iQO, iZR, iZR}}, /* 6*/ {{0.3750f, 0.0000f, 0.0f, 1.2f, 0.8f, 0.0f, 0.0f}, { iLN, iZR, iQI, iQI, iZR, iZR}}, /* 7*/ {{0.4325f,-0.0625f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f}, { iLN, iZR, iQO, iQO, iZR, iZR}}, /* 8*/ {{0.5000f,-0.1250f, 0.0f, 1.2f, 0.8f, 0.0f, 0.0f}, /* la */ { iLN, iQI, iQI, iQI, iZR, iZR}}, /* 9*/ {{0.5625f,-0.0625f, 1.5f, 0.8f, 1.3f, 0.0f, 0.0f}, { iLN, iQO, iQO, iQO, iZR, iZR}}, /*10*/ {{0.6250f, 0.0000f, 0.0f, 1.2f, 0.8f, 0.0f, 0.0f}, { iLN, iZR, iQI, iQI, iZR, iZR}}, /*11*/ {{0.6875f,-0.0625f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f}, { iLN, iZR, iQO, iQO, iZR, iZR}}, /*12*/ {{0.7500f,-0.1250f, 0.0f, 1.2f, 0.8f, 0.0f, 0.0f}, /* la */ { iLN, iQI, iQI, iQI, iZR, iZR}}, /*13*/ {{0.8125f,-0.0625f, 1.5f, 0.8f, 1.3f, 0.0f, 0.0f}, { iLN, iQO, iQO, iQO, iZR, iZR}}, /*14*/ {{0.8750f, 0.0000f, 0.0f, 1.2f, 0.8f, 0.0f, 0.0f}, { iLN, iZR, iQI, iQI, iZR, iZR}}, /*15*/ {{0.9375f,-0.0625f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f}, { iLN, iZR, iQO, iQO, iZR, iZR}}, /*16*/ {{1.0000f,-0.1250f, 0.0f, 1.2f, 0.8f, 0.0f, 0.0f}, { iZR, iZR, iZR, iZR, iZR, iZR}}, }; static const KPARAM KeyframeParam4[8] = /* oooo la la */ { /* time x y sxz sy ry rz */ /* 0*/ {{0.0000f,-0.1250f, 0.0f, 1.2f, 0.8f, 0.0f, 360.0f}, /* oooo */ { iLN, iQI, iQI, iQI, iZR, iLN}}, /* 1*/ {{0.1000f, 0.0000f, 1.0f, 1.0f, 1.0f, 0.0f, 340.0f}, { iZR, iZR, iZR, iZR, iZR, iLN}}, /* 2*/ {{0.4000f, 0.0000f, 1.0f, 1.0f, 1.0f, 0.0f, 380.0f}, { iZR, iQO, iQO, iQO, iZR, iLN}}, /* 3*/ {{0.5000f, 0.0000f, 0.0f, 1.2f, 0.8f, 0.0f, 360.0f}, /* la */ { iZR, iQI, iQI, iQI, iZR, iZR}}, /* 4*/ {{0.6250f, 0.0000f, 1.5f, 0.8f, 1.3f, 0.0f, 0.0f}, { iZR, iQO, iQO, iQO, iZR, iZR}}, /* 5*/ {{0.7500f, 0.0000f, 0.0f, 1.2f, 0.8f, 0.0f, 0.0f}, /* la */ { iZR, iQI, iQI, iQI, iZR, iZR}}, /* 6*/ {{0.8750f, 0.0000f, 1.5f, 0.8f, 1.3f, 0.0f, 0.0f}, { iZR, iQO, iQO, iQO, iZR, iZR}}, /* 7*/ {{1.0000f, 0.0000f, 0.0f, 1.2f, 0.8f, 0.0f, 0.0f}, { iZR, iZR, iZR, iZR, iZR, iZR}}, }; static const KPARAM KeyframeParam5[16] = /* oo waa oo */ { /* time x y sxz sy ry rz */ /* 0*/ {{0.0000f,-0.1250f, 0.0f, 1.2f, 0.8f, 0.0f, 0.0f}, /* oo */ { iLN, iQI, iQI, iQI, iZR, iZR}}, /* 1*/ {{0.0625f,-0.0625f, 0.8f, 0.8f, 1.3f, 0.0f, 0.0f}, { iLN, iQO, iQO, iQO, iZR, iZR}}, /* 2*/ {{0.1250f, 0.0000f, 0.0f, 1.2f, 0.8f, 0.0f, 0.0f}, { iLN, iQI, iQI, iQI, iZR, iZR}}, /* 3*/ {{0.1875f,-0.0625f, 1.6f, 0.8f, 1.3f, 0.0f, 0.0f}, { iLN, iZR, iLN, iLN, iLN, iZR}}, /* 4*/ {{0.2500f,-0.1250f, 1.6f, 1.0f, 1.0f, 180.0f, 0.0f}, /* waa */ { iLN, iZR, iZR, iZR, iLN, iLN}}, /* 5*/ {{0.3125f,-0.1875f, 1.6f, 1.0f, 1.0f, 360.0f, 10.0f}, { iLN, iZR, iZR, iZR, iZR, iLN}}, /* 6*/ {{0.3750f,-0.2500f, 1.6f, 1.0f, 1.0f, 0.0f, 0.0f}, { iLN, iQO, iLN, iLN, iZR, iZR}}, /* 7*/ {{0.4375f,-0.3125f, 0.0f, 1.2f, 0.8f, 0.0f, 0.0f}, /* oo */ { iLN, iZR, iQI, iQI, iZR, iZR}}, /* 8*/ {{0.5625f,-0.4375f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f}, { iLN, iZR, iQO, iQO, iZR, iZR}}, /* 9*/ {{0.6250f,-0.3125f, 0.0f, 1.2f, 0.8f, 0.0f, 0.0f}, /* please */ { iLN, iQI, iQI, iQI, iZR, iZR}}, /*10*/ {{0.6875f,-0.2604f, 0.8f, 0.8f, 1.3f, 0.0f, 0.0f}, { iLN, iQO, iQO, iQO, iZR, iZR}}, /*11*/ {{0.7500f,-0.2083f, 0.0f, 1.2f, 0.8f, 0.0f, 0.0f}, /* give */ { iLN, iQI, iQI, iQI, iZR, iZR}}, /*12*/ {{0.8125f,-0.1563f, 0.8f, 0.8f, 1.3f, 0.0f, 0.0f}, { iLN, iQO, iQO, iQO, iZR, iZR}}, /*13*/ {{0.8750f,-0.1042f, 0.0f, 1.2f, 0.8f, 0.0f, 0.0f}, /* me */ { iLN, iQI, iQI, iQI, iZR, iZR}}, /*14*/ {{0.9375f,-0.0521f, 0.8f, 0.8f, 1.3f, 0.0f, 0.0f}, { iLN, iQO, iQO, iQO, iZR, iZR}}, /*15*/ {{1.0000f, 0.0000f, 0.0f, 1.2f, 0.8f, 0.0f, 0.0f}, { iZR, iZR, iZR, iZR, iZR, iZR}} }; static const KPARAM KeyframeParam6[15] = /* ooo wa ooo wa */ { /* time x y sxz sy ry rz */ /* 0*/ {{0.0000f, 0.0000f, 0.0f, 1.2f, 0.8f, 0.0f, 0.0f}, /* ooo */ { iLN, iZR, iLN, iLN, iZR, iLN}}, /* 1*/ {{0.0500f,-0.0500f, 0.0f, 0.7f, 1.4f, 0.0f, 3.0f}, { iLN, iZR, iLN, iLN, iZR, iLN}}, /* 2*/ {{0.1000f,-0.1000f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f}, { iLN, iZR, iLN, iLN, iZR, iLN}}, /* 3*/ {{0.2000f,-0.2000f, 0.0f, 1.2f, 0.8f, 0.0f, -3.0f}, /* wa */ { iLN, iQI, iQI, iQI, iZR, iLN}}, /* 4*/ {{0.2500f,-0.0313f, 1.5f, 0.8f, 1.3f, 0.0f, 0.0f}, { iLN, iQO, iQO, iQO, iZR, iZR}}, /* 5*/ {{0.3000f, 0.1375f, 0.0f, 1.2f, 0.8f, 0.0f, 0.0f}, { iLN, iZR, iLN, iLN, iZR, iZR}}, /* 6*/ {{0.4000f, 0.0375f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f}, { iLN, iZR, iLN, iLN, iZR, iZR}}, /* 7*/ {{0.5000f,-0.0625f, 0.0f, 1.2f, 0.8f, 0.0f, 0.0f}, /* ooo */ { iLN, iZR, iLN, iLN, iZR, iLN}}, /* 8*/ {{0.5500f,-0.1125f, 0.0f, 0.7f, 1.4f, 0.0f, 3.0f}, { iLN, iQI, iLN, iLN, iZR, iLN}}, /* 9*/ {{0.6000f,-0.1625f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f}, { iLN, iZR, iLN, iLN, iZR, iLN}}, /*10*/ {{0.7000f,-0.2625f, 0.0f, 1.2f, 0.8f, 0.0f, -3.0f}, /* wa */ { iLN, iQI, iQI, iQI, iZR, iLN}}, /*11*/ {{0.7500f,-0.0936f, 1.5f, 0.8f, 1.3f, 0.0f, 0.0f}, { iLN, iQO, iQO, iQO, iZR, iZR}}, /*12*/ {{0.8000f, 0.0750f, 0.0f, 1.2f, 0.8f, 0.0f, 0.0f}, { iLN, iZR, iLN, iLN, iZR, iZR}}, /*13*/ {{0.9000f,-0.0250f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f}, { iLN, iZR, iLN, iLN, iZR, iZR}}, /*14*/ {{1.0000f,-0.1250f, 0.0f, 1.2f, 0.8f, 0.0f, 0.0f}, { iZR, iZR, iZR, iZR, iZR, iZR}} }; static const KPARAM KeyframeParam7[17] = /* la la la la */ { /* time x y sxz sy ry rz */ /* 0*/ {{0.0000f,-0.1250f, 0.0f, 1.2f, 0.8f, 0.0f, 0.0f}, /* la */ { iLN, iQI, iQI, iQI, iZR, iZR}}, /* 1*/ {{0.0625f,-0.0625f, 1.5f, 0.8f, 1.3f, 0.0f, 0.0f}, { iLN, iQO, iQO, iQO, iZR, iZR}}, /* 2*/ {{0.1250f, 0.0000f, 0.0f, 1.2f, 0.8f, 0.0f, 0.0f}, { iLN, iZR, iQI, iQI, iZR, iZR}}, /* 3*/ {{0.1875f,-0.0625f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f}, { iLN, iZR, iQO, iQO, iZR, iZR}}, /* 4*/ {{0.2500f,-0.1250f, 0.0f, 1.2f, 0.8f, 0.0f, 0.0f}, /* la */ { iLN, iQI, iQI, iQI, iZR, iZR}}, /* 5*/ {{0.3125f,-0.0625f, 1.5f, 0.8f, 1.3f, 0.0f, 0.0f}, { iLN, iQO, iQO, iQO, iZR, iZR}}, /* 6*/ {{0.3750f, 0.0000f, 0.0f, 1.2f, 0.8f, 0.0f, 0.0f}, { iLN, iZR, iQI, iQI, iZR, iZR}}, /* 7*/ {{0.4325f,-0.0625f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f}, { iLN, iZR, iQO, iQO, iZR, iZR}}, /* 8*/ {{0.5000f,-0.1250f, 0.0f, 1.2f, 0.8f, 0.0f, 0.0f}, /* la */ { iLN, iQI, iQI, iQI, iZR, iZR}}, /* 9*/ {{0.5625f,-0.0625f, 1.5f, 0.8f, 1.3f, 0.0f, 0.0f}, { iLN, iQO, iQO, iQO, iZR, iZR}}, /*10*/ {{0.6250f, 0.0000f, 0.0f, 1.2f, 0.8f, 0.0f, 0.0f}, { iLN, iZR, iQI, iQI, iZR, iZR}}, /*11*/ {{0.6875f,-0.0625f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f}, { iLN, iZR, iQO, iQO, iZR, iZR}}, /*12*/ {{0.7500f,-0.1250f, 0.0f, 1.2f, 0.8f, 0.0f, 0.0f}, /* la */ { iLN, iQI, iQI, iQI, iZR, iZR}}, /*13*/ {{0.8125f,-0.0625f, 1.5f, 0.8f, 1.3f, 0.0f, 0.0f}, { iLN, iQO, iQO, iQO, iZR, iZR}}, /*14*/ {{0.8750f, 0.0000f, 0.0f, 1.2f, 0.8f, 0.0f, 0.0f}, { iLN, iZR, iQI, iQI, iZR, iZR}}, /*15*/ {{0.9375f,-0.0625f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f}, { iLN, iZR, iQO, iQO, iZR, iZR}}, /*16*/ {{1.0000f,-0.1250f, 0.0f, 1.2f, 0.8f, 0.0f, 0.0f}, { iZR, iZR, iZR, iZR, iZR, iZR}}, }; static const KPARAM KeyframeParam8[15] = /* ooo wa ooo wa */ { /* time x y sxz sy ry rz */ /* 0*/ {{0.0000f,-0.1250f, 0.0f, 1.2f, 0.8f, 0.0f, 0.0f}, /* ooo */ { iLN, iZR, iLN, iLN, iZR, iLN}}, /* 1*/ {{0.0500f,-0.1750f, 0.0f, 0.7f, 1.4f, 0.0f, 3.0f}, { iLN, iZR, iLN, iLN, iZR, iLN}}, /* 2*/ {{0.1000f,-0.2250f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f}, { iLN, iZR, iLN, iLN, iZR, iLN}}, /* 3*/ {{0.2000f,-0.3250f, 0.0f, 1.2f, 0.8f, 0.0f, -3.0f}, /* wa */ { iLN, iQI, iQI, iQI, iZR, iLN}}, /* 4*/ {{0.2500f,-0.1250f, 1.5f, 0.8f, 1.3f, 0.0f, 0.0f}, { iLN, iQO, iQO, iQO, iZR, iZR}}, /* 5*/ {{0.3000f, 0.0750f, 0.0f, 1.2f, 0.8f, 0.0f, 0.0f}, { iLN, iZR, iLN, iLN, iZR, iZR}}, /* 6*/ {{0.4000f,-0.0250f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f}, { iLN, iZR, iLN, iLN, iZR, iZR}}, /* 7*/ {{0.5000f,-0.1250f, 0.0f, 1.2f, 0.8f, 0.0f, 0.0f}, /* ooo */ { iLN, iZR, iLN, iLN, iZR, iLN}}, /* 8*/ {{0.5500f,-0.1750f, 0.0f, 0.7f, 1.4f, 0.0f, 3.0f}, { iLN, iQI, iLN, iLN, iZR, iLN}}, /* 9*/ {{0.6000f,-0.2250f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f}, { iLN, iZR, iLN, iLN, iZR, iLN}}, /*10*/ {{0.7000f,-0.3250f, 0.0f, 1.2f, 0.8f, 0.0f, -3.0f}, /* wa */ { iLN, iQI, iQI, iQI, iZR, iLN}}, /*11*/ {{0.7500f,-0.1250f, 1.5f, 0.8f, 1.3f, 0.0f, 0.0f}, { iLN, iQO, iQO, iQO, iZR, iZR}}, /*12*/ {{0.8000f, 0.0750f, 0.0f, 1.2f, 0.8f, 0.0f, 0.0f}, { iLN, iZR, iLN, iLN, iZR, iZR}}, /*13*/ {{0.9000f,-0.0250f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f}, { iLN, iZR, iLN, iLN, iZR, iZR}}, /*14*/ {{1.0000f,-0.1250f, 0.0f, 1.2f, 0.8f, 0.0f, 0.0f}, { iZR, iZR, iZR, iZR, iZR, iZR}} }; static const KPARAM *Keyframe[LINE_TYPE_COUNT] = { KeyframeParamNULL, KeyframeParam1, /* duun doobi doowa shoobi doobi dan dan (start=0, end=0) */ KeyframeParam2, /* shoobi doobi du dan dan (start=0, end=0) */ KeyframeParam3, /* la la la la (start=0, end=-0.125) */ KeyframeParam4, /* oooo la la (start=-0.125, end=0) */ KeyframeParam5, /* oo waa oo (start=-0.125, end=0) */ KeyframeParam6, /* ooo wa ooo wa (start=0, end=-0.125) */ KeyframeParam7, /* la la la la (start=-0.125, end=-0.125) */ KeyframeParam8 /* ooo wa ooo wa (start=-0.125, end=-0.125) */ }; static const int KeyframeCount[LINE_TYPE_COUNT] = { 3, 22, 19, 17, 8, 16, 15, 17, 15 }; static GLuint CharaObj = 0, CharaObjF = 0; static void CreateChara(void); static void CreateCharaF(void); static void Transform(int type, double t, /*@out@*/double *param); /*************************************************************** DrawChara */ void DrawChara(int type, double position) { static const GLfloat ambient[4] = {0.7f, 0.6f, 0.6f, 1.0f}; static const GLfloat diffuse[4] = {1.00f, 0.66f, 0.80f, 1.0f}; static const GLfloat specular[4] = {0.0f, 0.0f, 0.0f, 1.0f}; static const GLfloat emission[4] = {0.11f, 0.1f, 0.1f, 1.0f}; static const GLfloat outline[4] = {0.0f, 0.0f, 0.0f, 1.0f}; static const GLfloat shadow[4] = {0.0f, 0.0f, 0.0f, 0.8f}; static const GLfloat outlinescale = 1.09f; double param[kParamCount]; glPushMatrix(); Transform(type, position, param); /* Shadow */ glEnable(GL_POLYGON_OFFSET_FILL); glEnable(GL_BLEND); glDisable(GL_LIGHTING); glPushMatrix(); glTranslated(param[kX] * DRIFT_DISTANCE, 0.05, 0.0); glScaled(param[kXZScale], 0.0, param[kXZScale]); glRotated(param[kRotateZ], 0.0, 0.0, 0.1); glRotated(param[kRotateY], 0.0, 1.0, 0.0); glPolygonOffset(0.0f, -5.0f); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glColor4fv(shadow); CreateChara(); glPopMatrix(); glDisable(GL_POLYGON_OFFSET_FILL); glDisable(GL_BLEND); glEnable(GL_LIGHTING); glTranslated(param[kX] * DRIFT_DISTANCE, param[kY] + 0.05, 0.0); glScaled(param[kXZScale], param[kYScale], param[kXZScale]); glRotated(param[kRotateZ], 0.0, 0.0, 0.1); glRotated(param[kRotateY], 0.0, 1.0, 0.0); /* Character */ glCullFace(GL_BACK); glMaterialfv(GL_FRONT, GL_AMBIENT, ambient); glMaterialfv(GL_FRONT, GL_DIFFUSE, diffuse); glMaterialfv(GL_FRONT, GL_SPECULAR, specular); glMaterialfv(GL_FRONT, GL_EMISSION, emission); CreateChara(); /* Outline */ glCullFace(GL_FRONT); glDisable(GL_LIGHTING); glShadeModel(GL_FLAT); glColor4fv(outline); glPushMatrix(); glScalef(outlinescale, outlinescale, outlinescale); glTranslatef(0.0f, -0.02f, 0.0f); CreateChara(); glPopMatrix(); /* Decorations */ glDisable(GL_CULL_FACE); glEnable(GL_POLYGON_OFFSET_FILL); glPolygonOffset(0.0f, -5.0f); glColor4fv(outline); CreateCharaF(); glDisable(GL_POLYGON_OFFSET_FILL); glEnable(GL_CULL_FACE); glPopMatrix(); } /* DrawChara() */ /************************************************************* UninitChara */ void UninitChara(void) { if( CharaObj != 0 ) glDeleteLists(CharaObj, 1); if( CharaObjF != 0 ) glDeleteLists(CharaObjF, 1); } /* UninitChara() */ /************************************************************* CreateChara */ static void CreateChara(void) { static const double cx[5] = {0.0, CURVE_X1, CURVE_X2, CURVE_X3, 0.0}; static const double cy[5] = {0.0, CURVE_Y1, CURVE_Y2, CURVE_Y3, 1.0}; double ox[CURVE_RESOLUTION], oy[CURVE_RESOLUTION]; double nx[CURVE_RESOLUTION], ny[CURVE_RESOLUTION]; double p1, p2, p3, p4, q1, q2, q3, q4, c0, c1, c2, c3, c4; int i, j; if( CharaObj != 0 ) { glCallList(CharaObj); return; } /* Create profile curve */ for(i = 0; i < CURVE_RESOLUTION; i++) { /* Expontiate */ p1 = 1 - (q1 = ((double)(i + 1)) / (CURVE_RESOLUTION + 1)); p4 = p1 * (p3 = p1 * (p2 = p1 * p1)); q4 = q1 * (q3 = q1 * (q2 = q1 * q1)); /* Curve points */ ox[i] = cx[0] * p4 + cx[1] * (c1 = p3 * q1 * 4.0) + cx[2] * (c2 = p2 * q2 * 6.0) + cx[3] * (c3 = p1 * q3 * 4.0) + cx[4] * q4; oy[i] = cy[0] * p4 + cy[1] * c1 + cy[2] * c2 + cy[3] * c3 + cy[4] * q4; /* Curve normals */ ny[i] = - cx[0] * (c0 = -4.0 * p3) - cx[1] * (c1 = -12.0 * p2 * q1 + 4.0 * p3) - cx[2] * (c2 = -12.0 * p1 * q2 + 12.0 * p2 * q1) - cx[3] * (c3 = -4.0 * q3 + 12.0 * p1 * q2) - cx[4] * (c4 = 4.0 * q3); nx[i] = cy[0] * c0 + cy[1] * c1 + cy[2] * c2 + cy[3] * c3 + cy[4] * c4; } /* Create object (surface of revolution) */ glNewList(CharaObj = glGenLists(1), GL_COMPILE_AND_EXECUTE); /* Bottom cap */ glBegin(GL_TRIANGLE_FAN); glNormal3d(0.0,-1.0, 0.0); glVertex3d(0.0, 0.0, 0.0); for(i = 0; i < REV_RESOLUTION; i++) { c0 = (double)(2 * i) * PI / REV_RESOLUTION; p1 = cos(c0); q1 = sin(c0); glNormal3d(nx[0] * p1, ny[0], nx[0] * q1); glVertex3d(ox[0] * p1, oy[0], ox[0] * q1); } glNormal3d(nx[0], ny[0], 0.0); glVertex3d(ox[0], oy[0], 0.0); glEnd(); /* Middle */ for(i = 0; i < CURVE_RESOLUTION - 1; i++) { glBegin(GL_QUAD_STRIP); for(j = 0; j < REV_RESOLUTION; j++) { c0 = (double)(2 * j) * PI / REV_RESOLUTION; p1 = cos(c0); q1 = sin(c0); glNormal3d(nx[i] * p1, ny[i], nx[i] * q1); glVertex3d(ox[i] * p1, oy[i], ox[i] * q1); glNormal3d(nx[i + 1] * p1, ny[i + 1], nx[i + 1] * q1); glVertex3d(ox[i + 1] * p1, oy[i + 1], ox[i + 1] * q1); } glNormal3d(nx[i], ny[i], 0.0); glVertex3d(ox[i], oy[i], 0.0); glNormal3d(nx[i + 1], ny[i + 1], 0.0); glVertex3d(ox[i + 1], oy[i + 1], 0.0); glEnd(); } /* Top cap */ glBegin(GL_TRIANGLE_FAN); glNormal3d(0.0, 1.0, 0.0); glVertex3d(0.0, 1.0, 0.0); for(i = 0; i < REV_RESOLUTION; i++) { c0 = (double)(-2 * i) * PI / REV_RESOLUTION; p1 = cos(c0); q1 = sin(c0); glNormal3d(nx[CURVE_RESOLUTION - 1] * p1, ny[CURVE_RESOLUTION - 1], nx[CURVE_RESOLUTION - 1] * q1); glVertex3d(ox[CURVE_RESOLUTION - 1] * p1, oy[CURVE_RESOLUTION - 1], ox[CURVE_RESOLUTION - 1] * q1); } glNormal3d(nx[CURVE_RESOLUTION - 1], ny[CURVE_RESOLUTION - 1], 0.0); glVertex3d(ox[CURVE_RESOLUTION - 1], oy[CURVE_RESOLUTION - 1], 0.0); glEnd(); glEndList(); } /* CreateChara() */ /************************************************************ CreateCharaF */ static void CreateCharaF(void) { int i; if( CharaObjF != 0 ) { glCallList(CharaObjF); return; } glNewList(CharaObjF = glGenLists(1), GL_COMPILE_AND_EXECUTE); glBegin(GL_QUADS); for(i = -1; i <= 1; i += 2) { /* r(0.5) = 0.800, r(0.6) = 0.755, x = sqrt(r(t)^2 - z(t)^2) */ glVertex3d(0.772, 0.51, i * 0.21); glVertex3d(0.784, 0.51, i * 0.16); glVertex3d(0.738, 0.61, i * 0.16); glVertex3d(0.725, 0.61, i * 0.21); } glEnd(); glEndList(); } /* CreateCharaF() */ /************************************************************** Transform1 */ static void Transform(int type, double t, /*@out@*/double *param) { double x; int key, i, j; /* Binary search for current keyframe */ key = KeyframeCount[type] / 2; i = 0; j = KeyframeCount[type] - 1; assert(Keyframe[type][i].x[kTime] == 0.0f); assert(Keyframe[type][j].x[kTime] == 1.0f); while( !(Keyframe[type][key].x[kTime] <= (float)t && Keyframe[type][key + 1].x[kTime] >= (float)t) ) { if( (float)t < Keyframe[type][key].x[kTime] ) j = key; else i = key; key = (i + j) / 2; } /* Interpolate parameters */ x = (t - (double)Keyframe[type][key].x[kTime]) / (double)(Keyframe[type][key+1].x[kTime] - Keyframe[type][key].x[kTime]); for(i = j = 1; j < kParamCount; j++) { param[i] = (double)Keyframe[type][key].x[j]; switch( Keyframe[type][key].i[i - 1] ) { case iLN: param[i++] += x * (double) (Keyframe[type][key + 1].x[j] - Keyframe[type][key].x[j]); break; case iQI: param[i++] += (1.0 - ((1.0 - x) * (1.0 - x))) * (double) (Keyframe[type][key + 1].x[j] - Keyframe[type][key].x[j]); break; case iQO: param[i++] += x * x * (double) (Keyframe[type][key + 1].x[j] - Keyframe[type][key].x[j]); break; default: i++; break; } } /* Satisfy lint (param[0] is never used elsewhere) */ assert(param[0] == param[0]); } /* Transform() */