diff options
author | Erik Kundiman <erik@megapahit.org> | 2024-05-16 13:52:40 +0800 |
---|---|---|
committer | Erik Kundiman <erik@megapahit.org> | 2024-05-16 13:52:40 +0800 |
commit | 6d51e91895a7f2435c46a876410ccc6c63fe8c82 (patch) | |
tree | f2b48ebd99cb414227bf365f47665b8d4baa752b /indra/llcharacter | |
parent | d1b5917bb9c92e4e47eba19b43781e4d1328b1ca (diff) | |
parent | 094dcc07f8c1d90ae723dbe60eddacb90a09eae8 (diff) |
Merge tag '7.1.7-release'
source for viewer 7.1.7.8974243247
Diffstat (limited to 'indra/llcharacter')
45 files changed, 10668 insertions, 10665 deletions
diff --git a/indra/llcharacter/llanimationstates.cpp b/indra/llcharacter/llanimationstates.cpp index 2e78e30405..b44dccbe6c 100644 --- a/indra/llcharacter/llanimationstates.cpp +++ b/indra/llcharacter/llanimationstates.cpp @@ -1,25 +1,25 @@ -/** +/** * @file llanimationstates.cpp * @brief Implementation of animation state related functions. * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -195,150 +195,150 @@ LLAnimationLibrary gAnimLibrary; // LLAnimationLibrary() //----------------------------------------------------------------------------- LLAnimationLibrary::LLAnimationLibrary() : - mAnimStringTable(16384) + mAnimStringTable(16384) { - //add animation names to animmap - mAnimMap[ANIM_AGENT_AFRAID]= mAnimStringTable.addString("express_afraid"); - mAnimMap[ANIM_AGENT_AIM_BAZOOKA_R]= mAnimStringTable.addString("aim_r_bazooka"); - mAnimMap[ANIM_AGENT_AIM_BOW_L]= mAnimStringTable.addString("aim_l_bow"); - mAnimMap[ANIM_AGENT_AIM_HANDGUN_R]= mAnimStringTable.addString("aim_r_handgun"); - mAnimMap[ANIM_AGENT_AIM_RIFLE_R]= mAnimStringTable.addString("aim_r_rifle"); - mAnimMap[ANIM_AGENT_ANGRY]= mAnimStringTable.addString("express_anger"); - mAnimMap[ANIM_AGENT_AWAY]= mAnimStringTable.addString("away"); - mAnimMap[ANIM_AGENT_BACKFLIP]= mAnimStringTable.addString("backflip"); - mAnimMap[ANIM_AGENT_BELLY_LAUGH]= mAnimStringTable.addString("express_laugh"); - mAnimMap[ANIM_AGENT_BLOW_KISS]= mAnimStringTable.addString("blowkiss"); - mAnimMap[ANIM_AGENT_BORED]= mAnimStringTable.addString("express_bored"); - mAnimMap[ANIM_AGENT_BOW]= mAnimStringTable.addString("bow"); - mAnimMap[ANIM_AGENT_BRUSH]= mAnimStringTable.addString("brush"); - mAnimMap[ANIM_AGENT_DO_NOT_DISTURB]= mAnimStringTable.addString("busy"); - mAnimMap[ANIM_AGENT_CLAP]= mAnimStringTable.addString("clap"); - mAnimMap[ANIM_AGENT_COURTBOW]= mAnimStringTable.addString("courtbow"); - mAnimMap[ANIM_AGENT_CROUCH]= mAnimStringTable.addString("crouch"); - mAnimMap[ANIM_AGENT_CROUCHWALK]= mAnimStringTable.addString("crouchwalk"); - mAnimMap[ANIM_AGENT_CRY]= mAnimStringTable.addString("express_cry"); - mAnimMap[ANIM_AGENT_CUSTOMIZE]= mAnimStringTable.addString("turn_180"); - mAnimMap[ANIM_AGENT_CUSTOMIZE_DONE]= mAnimStringTable.addString("turnback_180"); - mAnimMap[ANIM_AGENT_DANCE1]= mAnimStringTable.addString("dance1"); - mAnimMap[ANIM_AGENT_DANCE2]= mAnimStringTable.addString("dance2"); - mAnimMap[ANIM_AGENT_DANCE3]= mAnimStringTable.addString("dance3"); - mAnimMap[ANIM_AGENT_DANCE4]= mAnimStringTable.addString("dance4"); - mAnimMap[ANIM_AGENT_DANCE5]= mAnimStringTable.addString("dance5"); - mAnimMap[ANIM_AGENT_DANCE6]= mAnimStringTable.addString("dance6"); - mAnimMap[ANIM_AGENT_DANCE7]= mAnimStringTable.addString("dance7"); - mAnimMap[ANIM_AGENT_DANCE8]= mAnimStringTable.addString("dance8"); - mAnimMap[ANIM_AGENT_DEAD]= mAnimStringTable.addString("dead"); - mAnimMap[ANIM_AGENT_DRINK]= mAnimStringTable.addString("drink"); - mAnimMap[ANIM_AGENT_EMBARRASSED]= mAnimStringTable.addString("express_embarrased"); - mAnimMap[ANIM_AGENT_EXPRESS_AFRAID]= mAnimStringTable.addString("express_afraid_emote"); - mAnimMap[ANIM_AGENT_EXPRESS_ANGER]= mAnimStringTable.addString("express_anger_emote"); - mAnimMap[ANIM_AGENT_EXPRESS_BORED]= mAnimStringTable.addString("express_bored_emote"); - mAnimMap[ANIM_AGENT_EXPRESS_CRY]= mAnimStringTable.addString("express_cry_emote"); - mAnimMap[ANIM_AGENT_EXPRESS_DISDAIN]= mAnimStringTable.addString("express_disdain"); - mAnimMap[ANIM_AGENT_EXPRESS_EMBARRASSED]= mAnimStringTable.addString("express_embarrassed_emote"); - mAnimMap[ANIM_AGENT_EXPRESS_FROWN]= mAnimStringTable.addString("express_frown"); - mAnimMap[ANIM_AGENT_EXPRESS_KISS]= mAnimStringTable.addString("express_kiss"); - mAnimMap[ANIM_AGENT_EXPRESS_LAUGH]= mAnimStringTable.addString("express_laugh_emote"); - mAnimMap[ANIM_AGENT_EXPRESS_OPEN_MOUTH]= mAnimStringTable.addString("express_open_mouth"); - mAnimMap[ANIM_AGENT_EXPRESS_REPULSED]= mAnimStringTable.addString("express_repulsed_emote"); - mAnimMap[ANIM_AGENT_EXPRESS_SAD]= mAnimStringTable.addString("express_sad_emote"); - mAnimMap[ANIM_AGENT_EXPRESS_SHRUG]= mAnimStringTable.addString("express_shrug_emote"); - mAnimMap[ANIM_AGENT_EXPRESS_SMILE]= mAnimStringTable.addString("express_smile"); - mAnimMap[ANIM_AGENT_EXPRESS_SURPRISE]= mAnimStringTable.addString("express_surprise_emote"); - mAnimMap[ANIM_AGENT_EXPRESS_TONGUE_OUT]= mAnimStringTable.addString("express_tongue_out"); - mAnimMap[ANIM_AGENT_EXPRESS_TOOTHSMILE]= mAnimStringTable.addString("express_toothsmile"); - mAnimMap[ANIM_AGENT_EXPRESS_WINK]= mAnimStringTable.addString("express_wink_emote"); - mAnimMap[ANIM_AGENT_EXPRESS_WORRY]= mAnimStringTable.addString("express_worry_emote"); - mAnimMap[ANIM_AGENT_FALLDOWN]= mAnimStringTable.addString("falldown"); - mAnimMap[ANIM_AGENT_FEMALE_RUN_NEW]= mAnimStringTable.addString("female_run_new"); - mAnimMap[ANIM_AGENT_FEMALE_WALK]= mAnimStringTable.addString("female_walk"); - mAnimMap[ANIM_AGENT_FEMALE_WALK_NEW]= mAnimStringTable.addString("female_walk_new"); - mAnimMap[ANIM_AGENT_FINGER_WAG]= mAnimStringTable.addString("angry_fingerwag"); - mAnimMap[ANIM_AGENT_FIST_PUMP]= mAnimStringTable.addString("fist_pump"); - mAnimMap[ANIM_AGENT_FLY]= mAnimStringTable.addString("fly"); - mAnimMap[ANIM_AGENT_FLYSLOW]= mAnimStringTable.addString("flyslow"); - mAnimMap[ANIM_AGENT_HELLO]= mAnimStringTable.addString("hello"); - mAnimMap[ANIM_AGENT_HOLD_BAZOOKA_R]= mAnimStringTable.addString("hold_r_bazooka"); - mAnimMap[ANIM_AGENT_HOLD_BOW_L]= mAnimStringTable.addString("hold_l_bow"); - mAnimMap[ANIM_AGENT_HOLD_HANDGUN_R]= mAnimStringTable.addString("hold_r_handgun"); - mAnimMap[ANIM_AGENT_HOLD_RIFLE_R]= mAnimStringTable.addString("hold_r_rifle"); - mAnimMap[ANIM_AGENT_HOLD_THROW_R]= mAnimStringTable.addString("hold_throw_r"); - mAnimMap[ANIM_AGENT_HOVER]= mAnimStringTable.addString("hover"); - mAnimMap[ANIM_AGENT_HOVER_DOWN]= mAnimStringTable.addString("hover_down"); - mAnimMap[ANIM_AGENT_HOVER_UP]= mAnimStringTable.addString("hover_up"); - mAnimMap[ANIM_AGENT_IMPATIENT]= mAnimStringTable.addString("impatient"); - mAnimMap[ANIM_AGENT_JUMP]= mAnimStringTable.addString("jump"); - mAnimMap[ANIM_AGENT_JUMP_FOR_JOY]= mAnimStringTable.addString("jumpforjoy"); - mAnimMap[ANIM_AGENT_KISS_MY_BUTT]= mAnimStringTable.addString("kissmybutt"); - mAnimMap[ANIM_AGENT_LAND]= mAnimStringTable.addString("land"); - mAnimMap[ANIM_AGENT_LAUGH_SHORT]= mAnimStringTable.addString("laugh_short"); - mAnimMap[ANIM_AGENT_MEDIUM_LAND]= mAnimStringTable.addString("soft_land"); - mAnimMap[ANIM_AGENT_MOTORCYCLE_SIT]= mAnimStringTable.addString("motorcycle_sit"); - mAnimMap[ANIM_AGENT_MUSCLE_BEACH]= mAnimStringTable.addString("musclebeach"); - mAnimMap[ANIM_AGENT_NO]= mAnimStringTable.addString("no_head"); - mAnimMap[ANIM_AGENT_NO_UNHAPPY]= mAnimStringTable.addString("no_unhappy"); - mAnimMap[ANIM_AGENT_NYAH_NYAH]= mAnimStringTable.addString("nyanya"); - mAnimMap[ANIM_AGENT_ONETWO_PUNCH]= mAnimStringTable.addString("punch_onetwo"); - mAnimMap[ANIM_AGENT_PEACE]= mAnimStringTable.addString("peace"); - mAnimMap[ANIM_AGENT_POINT_ME]= mAnimStringTable.addString("point_me"); - mAnimMap[ANIM_AGENT_POINT_YOU]= mAnimStringTable.addString("point_you"); - mAnimMap[ANIM_AGENT_PRE_JUMP]= mAnimStringTable.addString("prejump"); - mAnimMap[ANIM_AGENT_PUNCH_LEFT]= mAnimStringTable.addString("punch_l"); - mAnimMap[ANIM_AGENT_PUNCH_RIGHT]= mAnimStringTable.addString("punch_r"); - mAnimMap[ANIM_AGENT_REPULSED]= mAnimStringTable.addString("express_repulsed"); - mAnimMap[ANIM_AGENT_ROUNDHOUSE_KICK]= mAnimStringTable.addString("kick_roundhouse_r"); - mAnimMap[ANIM_AGENT_RPS_COUNTDOWN]= mAnimStringTable.addString("rps_countdown"); - mAnimMap[ANIM_AGENT_RPS_PAPER]= mAnimStringTable.addString("rps_paper"); - mAnimMap[ANIM_AGENT_RPS_ROCK]= mAnimStringTable.addString("rps_rock"); - mAnimMap[ANIM_AGENT_RPS_SCISSORS]= mAnimStringTable.addString("rps_scissors"); - mAnimMap[ANIM_AGENT_RUN]= mAnimStringTable.addString("run"); - mAnimMap[ANIM_AGENT_RUN_NEW]= mAnimStringTable.addString("run_new"); - mAnimMap[ANIM_AGENT_SAD]= mAnimStringTable.addString("express_sad"); - mAnimMap[ANIM_AGENT_SALUTE]= mAnimStringTable.addString("salute"); - mAnimMap[ANIM_AGENT_SHOOT_BOW_L]= mAnimStringTable.addString("shoot_l_bow"); - mAnimMap[ANIM_AGENT_SHOUT]= mAnimStringTable.addString("shout"); - mAnimMap[ANIM_AGENT_SHRUG]= mAnimStringTable.addString("express_shrug"); - mAnimMap[ANIM_AGENT_SIT]= mAnimStringTable.addString("sit"); - mAnimMap[ANIM_AGENT_SIT_FEMALE]= mAnimStringTable.addString("sit_female"); - mAnimMap[ANIM_AGENT_SIT_GROUND]= mAnimStringTable.addString("sit_ground"); - mAnimMap[ANIM_AGENT_SIT_GROUND_CONSTRAINED]= mAnimStringTable.addString("sit_ground_constrained"); - mAnimMap[ANIM_AGENT_SIT_GENERIC]= mAnimStringTable.addString("sit_generic"); - mAnimMap[ANIM_AGENT_SIT_TO_STAND]= mAnimStringTable.addString("sit_to_stand"); - mAnimMap[ANIM_AGENT_SLEEP]= mAnimStringTable.addString("sleep"); - mAnimMap[ANIM_AGENT_SMOKE_IDLE]= mAnimStringTable.addString("smoke_idle"); - mAnimMap[ANIM_AGENT_SMOKE_INHALE]= mAnimStringTable.addString("smoke_inhale"); - mAnimMap[ANIM_AGENT_SMOKE_THROW_DOWN]= mAnimStringTable.addString("smoke_throw_down"); - mAnimMap[ANIM_AGENT_SNAPSHOT]= mAnimStringTable.addString("snapshot"); - mAnimMap[ANIM_AGENT_STAND]= mAnimStringTable.addString("stand"); - mAnimMap[ANIM_AGENT_STANDUP]= mAnimStringTable.addString("standup"); - mAnimMap[ANIM_AGENT_STAND_1]= mAnimStringTable.addString("stand_1"); - mAnimMap[ANIM_AGENT_STAND_2]= mAnimStringTable.addString("stand_2"); - mAnimMap[ANIM_AGENT_STAND_3]= mAnimStringTable.addString("stand_3"); - mAnimMap[ANIM_AGENT_STAND_4]= mAnimStringTable.addString("stand_4"); - mAnimMap[ANIM_AGENT_STRETCH]= mAnimStringTable.addString("stretch"); - mAnimMap[ANIM_AGENT_STRIDE]= mAnimStringTable.addString("stride"); - mAnimMap[ANIM_AGENT_SURF]= mAnimStringTable.addString("surf"); - mAnimMap[ANIM_AGENT_SURPRISE]= mAnimStringTable.addString("express_surprise"); - mAnimMap[ANIM_AGENT_SWORD_STRIKE]= mAnimStringTable.addString("sword_strike_r"); - mAnimMap[ANIM_AGENT_TALK]= mAnimStringTable.addString("talk"); - mAnimMap[ANIM_AGENT_TANTRUM]= mAnimStringTable.addString("angry_tantrum"); - mAnimMap[ANIM_AGENT_THROW_R]= mAnimStringTable.addString("throw_r"); - mAnimMap[ANIM_AGENT_TRYON_SHIRT]= mAnimStringTable.addString("tryon_shirt"); - mAnimMap[ANIM_AGENT_TURNLEFT]= mAnimStringTable.addString("turnleft"); - mAnimMap[ANIM_AGENT_TURNRIGHT]= mAnimStringTable.addString("turnright"); - mAnimMap[ANIM_AGENT_TYPE]= mAnimStringTable.addString("type"); - mAnimMap[ANIM_AGENT_WALK]= mAnimStringTable.addString("walk"); - mAnimMap[ANIM_AGENT_WALK_NEW]= mAnimStringTable.addString("walk_new"); - mAnimMap[ANIM_AGENT_WHISPER]= mAnimStringTable.addString("whisper"); - mAnimMap[ANIM_AGENT_WHISTLE]= mAnimStringTable.addString("whistle"); - mAnimMap[ANIM_AGENT_WINK]= mAnimStringTable.addString("express_wink"); - mAnimMap[ANIM_AGENT_WINK_HOLLYWOOD]= mAnimStringTable.addString("wink_hollywood"); - mAnimMap[ANIM_AGENT_WORRY]= mAnimStringTable.addString("express_worry"); - mAnimMap[ANIM_AGENT_YES]= mAnimStringTable.addString("yes_head"); - mAnimMap[ANIM_AGENT_YES_HAPPY]= mAnimStringTable.addString("yes_happy"); - mAnimMap[ANIM_AGENT_YOGA_FLOAT]= mAnimStringTable.addString("yoga_float"); + //add animation names to animmap + mAnimMap[ANIM_AGENT_AFRAID]= mAnimStringTable.addString("express_afraid"); + mAnimMap[ANIM_AGENT_AIM_BAZOOKA_R]= mAnimStringTable.addString("aim_r_bazooka"); + mAnimMap[ANIM_AGENT_AIM_BOW_L]= mAnimStringTable.addString("aim_l_bow"); + mAnimMap[ANIM_AGENT_AIM_HANDGUN_R]= mAnimStringTable.addString("aim_r_handgun"); + mAnimMap[ANIM_AGENT_AIM_RIFLE_R]= mAnimStringTable.addString("aim_r_rifle"); + mAnimMap[ANIM_AGENT_ANGRY]= mAnimStringTable.addString("express_anger"); + mAnimMap[ANIM_AGENT_AWAY]= mAnimStringTable.addString("away"); + mAnimMap[ANIM_AGENT_BACKFLIP]= mAnimStringTable.addString("backflip"); + mAnimMap[ANIM_AGENT_BELLY_LAUGH]= mAnimStringTable.addString("express_laugh"); + mAnimMap[ANIM_AGENT_BLOW_KISS]= mAnimStringTable.addString("blowkiss"); + mAnimMap[ANIM_AGENT_BORED]= mAnimStringTable.addString("express_bored"); + mAnimMap[ANIM_AGENT_BOW]= mAnimStringTable.addString("bow"); + mAnimMap[ANIM_AGENT_BRUSH]= mAnimStringTable.addString("brush"); + mAnimMap[ANIM_AGENT_DO_NOT_DISTURB]= mAnimStringTable.addString("busy"); + mAnimMap[ANIM_AGENT_CLAP]= mAnimStringTable.addString("clap"); + mAnimMap[ANIM_AGENT_COURTBOW]= mAnimStringTable.addString("courtbow"); + mAnimMap[ANIM_AGENT_CROUCH]= mAnimStringTable.addString("crouch"); + mAnimMap[ANIM_AGENT_CROUCHWALK]= mAnimStringTable.addString("crouchwalk"); + mAnimMap[ANIM_AGENT_CRY]= mAnimStringTable.addString("express_cry"); + mAnimMap[ANIM_AGENT_CUSTOMIZE]= mAnimStringTable.addString("turn_180"); + mAnimMap[ANIM_AGENT_CUSTOMIZE_DONE]= mAnimStringTable.addString("turnback_180"); + mAnimMap[ANIM_AGENT_DANCE1]= mAnimStringTable.addString("dance1"); + mAnimMap[ANIM_AGENT_DANCE2]= mAnimStringTable.addString("dance2"); + mAnimMap[ANIM_AGENT_DANCE3]= mAnimStringTable.addString("dance3"); + mAnimMap[ANIM_AGENT_DANCE4]= mAnimStringTable.addString("dance4"); + mAnimMap[ANIM_AGENT_DANCE5]= mAnimStringTable.addString("dance5"); + mAnimMap[ANIM_AGENT_DANCE6]= mAnimStringTable.addString("dance6"); + mAnimMap[ANIM_AGENT_DANCE7]= mAnimStringTable.addString("dance7"); + mAnimMap[ANIM_AGENT_DANCE8]= mAnimStringTable.addString("dance8"); + mAnimMap[ANIM_AGENT_DEAD]= mAnimStringTable.addString("dead"); + mAnimMap[ANIM_AGENT_DRINK]= mAnimStringTable.addString("drink"); + mAnimMap[ANIM_AGENT_EMBARRASSED]= mAnimStringTable.addString("express_embarrased"); + mAnimMap[ANIM_AGENT_EXPRESS_AFRAID]= mAnimStringTable.addString("express_afraid_emote"); + mAnimMap[ANIM_AGENT_EXPRESS_ANGER]= mAnimStringTable.addString("express_anger_emote"); + mAnimMap[ANIM_AGENT_EXPRESS_BORED]= mAnimStringTable.addString("express_bored_emote"); + mAnimMap[ANIM_AGENT_EXPRESS_CRY]= mAnimStringTable.addString("express_cry_emote"); + mAnimMap[ANIM_AGENT_EXPRESS_DISDAIN]= mAnimStringTable.addString("express_disdain"); + mAnimMap[ANIM_AGENT_EXPRESS_EMBARRASSED]= mAnimStringTable.addString("express_embarrassed_emote"); + mAnimMap[ANIM_AGENT_EXPRESS_FROWN]= mAnimStringTable.addString("express_frown"); + mAnimMap[ANIM_AGENT_EXPRESS_KISS]= mAnimStringTable.addString("express_kiss"); + mAnimMap[ANIM_AGENT_EXPRESS_LAUGH]= mAnimStringTable.addString("express_laugh_emote"); + mAnimMap[ANIM_AGENT_EXPRESS_OPEN_MOUTH]= mAnimStringTable.addString("express_open_mouth"); + mAnimMap[ANIM_AGENT_EXPRESS_REPULSED]= mAnimStringTable.addString("express_repulsed_emote"); + mAnimMap[ANIM_AGENT_EXPRESS_SAD]= mAnimStringTable.addString("express_sad_emote"); + mAnimMap[ANIM_AGENT_EXPRESS_SHRUG]= mAnimStringTable.addString("express_shrug_emote"); + mAnimMap[ANIM_AGENT_EXPRESS_SMILE]= mAnimStringTable.addString("express_smile"); + mAnimMap[ANIM_AGENT_EXPRESS_SURPRISE]= mAnimStringTable.addString("express_surprise_emote"); + mAnimMap[ANIM_AGENT_EXPRESS_TONGUE_OUT]= mAnimStringTable.addString("express_tongue_out"); + mAnimMap[ANIM_AGENT_EXPRESS_TOOTHSMILE]= mAnimStringTable.addString("express_toothsmile"); + mAnimMap[ANIM_AGENT_EXPRESS_WINK]= mAnimStringTable.addString("express_wink_emote"); + mAnimMap[ANIM_AGENT_EXPRESS_WORRY]= mAnimStringTable.addString("express_worry_emote"); + mAnimMap[ANIM_AGENT_FALLDOWN]= mAnimStringTable.addString("falldown"); + mAnimMap[ANIM_AGENT_FEMALE_RUN_NEW]= mAnimStringTable.addString("female_run_new"); + mAnimMap[ANIM_AGENT_FEMALE_WALK]= mAnimStringTable.addString("female_walk"); + mAnimMap[ANIM_AGENT_FEMALE_WALK_NEW]= mAnimStringTable.addString("female_walk_new"); + mAnimMap[ANIM_AGENT_FINGER_WAG]= mAnimStringTable.addString("angry_fingerwag"); + mAnimMap[ANIM_AGENT_FIST_PUMP]= mAnimStringTable.addString("fist_pump"); + mAnimMap[ANIM_AGENT_FLY]= mAnimStringTable.addString("fly"); + mAnimMap[ANIM_AGENT_FLYSLOW]= mAnimStringTable.addString("flyslow"); + mAnimMap[ANIM_AGENT_HELLO]= mAnimStringTable.addString("hello"); + mAnimMap[ANIM_AGENT_HOLD_BAZOOKA_R]= mAnimStringTable.addString("hold_r_bazooka"); + mAnimMap[ANIM_AGENT_HOLD_BOW_L]= mAnimStringTable.addString("hold_l_bow"); + mAnimMap[ANIM_AGENT_HOLD_HANDGUN_R]= mAnimStringTable.addString("hold_r_handgun"); + mAnimMap[ANIM_AGENT_HOLD_RIFLE_R]= mAnimStringTable.addString("hold_r_rifle"); + mAnimMap[ANIM_AGENT_HOLD_THROW_R]= mAnimStringTable.addString("hold_throw_r"); + mAnimMap[ANIM_AGENT_HOVER]= mAnimStringTable.addString("hover"); + mAnimMap[ANIM_AGENT_HOVER_DOWN]= mAnimStringTable.addString("hover_down"); + mAnimMap[ANIM_AGENT_HOVER_UP]= mAnimStringTable.addString("hover_up"); + mAnimMap[ANIM_AGENT_IMPATIENT]= mAnimStringTable.addString("impatient"); + mAnimMap[ANIM_AGENT_JUMP]= mAnimStringTable.addString("jump"); + mAnimMap[ANIM_AGENT_JUMP_FOR_JOY]= mAnimStringTable.addString("jumpforjoy"); + mAnimMap[ANIM_AGENT_KISS_MY_BUTT]= mAnimStringTable.addString("kissmybutt"); + mAnimMap[ANIM_AGENT_LAND]= mAnimStringTable.addString("land"); + mAnimMap[ANIM_AGENT_LAUGH_SHORT]= mAnimStringTable.addString("laugh_short"); + mAnimMap[ANIM_AGENT_MEDIUM_LAND]= mAnimStringTable.addString("soft_land"); + mAnimMap[ANIM_AGENT_MOTORCYCLE_SIT]= mAnimStringTable.addString("motorcycle_sit"); + mAnimMap[ANIM_AGENT_MUSCLE_BEACH]= mAnimStringTable.addString("musclebeach"); + mAnimMap[ANIM_AGENT_NO]= mAnimStringTable.addString("no_head"); + mAnimMap[ANIM_AGENT_NO_UNHAPPY]= mAnimStringTable.addString("no_unhappy"); + mAnimMap[ANIM_AGENT_NYAH_NYAH]= mAnimStringTable.addString("nyanya"); + mAnimMap[ANIM_AGENT_ONETWO_PUNCH]= mAnimStringTable.addString("punch_onetwo"); + mAnimMap[ANIM_AGENT_PEACE]= mAnimStringTable.addString("peace"); + mAnimMap[ANIM_AGENT_POINT_ME]= mAnimStringTable.addString("point_me"); + mAnimMap[ANIM_AGENT_POINT_YOU]= mAnimStringTable.addString("point_you"); + mAnimMap[ANIM_AGENT_PRE_JUMP]= mAnimStringTable.addString("prejump"); + mAnimMap[ANIM_AGENT_PUNCH_LEFT]= mAnimStringTable.addString("punch_l"); + mAnimMap[ANIM_AGENT_PUNCH_RIGHT]= mAnimStringTable.addString("punch_r"); + mAnimMap[ANIM_AGENT_REPULSED]= mAnimStringTable.addString("express_repulsed"); + mAnimMap[ANIM_AGENT_ROUNDHOUSE_KICK]= mAnimStringTable.addString("kick_roundhouse_r"); + mAnimMap[ANIM_AGENT_RPS_COUNTDOWN]= mAnimStringTable.addString("rps_countdown"); + mAnimMap[ANIM_AGENT_RPS_PAPER]= mAnimStringTable.addString("rps_paper"); + mAnimMap[ANIM_AGENT_RPS_ROCK]= mAnimStringTable.addString("rps_rock"); + mAnimMap[ANIM_AGENT_RPS_SCISSORS]= mAnimStringTable.addString("rps_scissors"); + mAnimMap[ANIM_AGENT_RUN]= mAnimStringTable.addString("run"); + mAnimMap[ANIM_AGENT_RUN_NEW]= mAnimStringTable.addString("run_new"); + mAnimMap[ANIM_AGENT_SAD]= mAnimStringTable.addString("express_sad"); + mAnimMap[ANIM_AGENT_SALUTE]= mAnimStringTable.addString("salute"); + mAnimMap[ANIM_AGENT_SHOOT_BOW_L]= mAnimStringTable.addString("shoot_l_bow"); + mAnimMap[ANIM_AGENT_SHOUT]= mAnimStringTable.addString("shout"); + mAnimMap[ANIM_AGENT_SHRUG]= mAnimStringTable.addString("express_shrug"); + mAnimMap[ANIM_AGENT_SIT]= mAnimStringTable.addString("sit"); + mAnimMap[ANIM_AGENT_SIT_FEMALE]= mAnimStringTable.addString("sit_female"); + mAnimMap[ANIM_AGENT_SIT_GROUND]= mAnimStringTable.addString("sit_ground"); + mAnimMap[ANIM_AGENT_SIT_GROUND_CONSTRAINED]= mAnimStringTable.addString("sit_ground_constrained"); + mAnimMap[ANIM_AGENT_SIT_GENERIC]= mAnimStringTable.addString("sit_generic"); + mAnimMap[ANIM_AGENT_SIT_TO_STAND]= mAnimStringTable.addString("sit_to_stand"); + mAnimMap[ANIM_AGENT_SLEEP]= mAnimStringTable.addString("sleep"); + mAnimMap[ANIM_AGENT_SMOKE_IDLE]= mAnimStringTable.addString("smoke_idle"); + mAnimMap[ANIM_AGENT_SMOKE_INHALE]= mAnimStringTable.addString("smoke_inhale"); + mAnimMap[ANIM_AGENT_SMOKE_THROW_DOWN]= mAnimStringTable.addString("smoke_throw_down"); + mAnimMap[ANIM_AGENT_SNAPSHOT]= mAnimStringTable.addString("snapshot"); + mAnimMap[ANIM_AGENT_STAND]= mAnimStringTable.addString("stand"); + mAnimMap[ANIM_AGENT_STANDUP]= mAnimStringTable.addString("standup"); + mAnimMap[ANIM_AGENT_STAND_1]= mAnimStringTable.addString("stand_1"); + mAnimMap[ANIM_AGENT_STAND_2]= mAnimStringTable.addString("stand_2"); + mAnimMap[ANIM_AGENT_STAND_3]= mAnimStringTable.addString("stand_3"); + mAnimMap[ANIM_AGENT_STAND_4]= mAnimStringTable.addString("stand_4"); + mAnimMap[ANIM_AGENT_STRETCH]= mAnimStringTable.addString("stretch"); + mAnimMap[ANIM_AGENT_STRIDE]= mAnimStringTable.addString("stride"); + mAnimMap[ANIM_AGENT_SURF]= mAnimStringTable.addString("surf"); + mAnimMap[ANIM_AGENT_SURPRISE]= mAnimStringTable.addString("express_surprise"); + mAnimMap[ANIM_AGENT_SWORD_STRIKE]= mAnimStringTable.addString("sword_strike_r"); + mAnimMap[ANIM_AGENT_TALK]= mAnimStringTable.addString("talk"); + mAnimMap[ANIM_AGENT_TANTRUM]= mAnimStringTable.addString("angry_tantrum"); + mAnimMap[ANIM_AGENT_THROW_R]= mAnimStringTable.addString("throw_r"); + mAnimMap[ANIM_AGENT_TRYON_SHIRT]= mAnimStringTable.addString("tryon_shirt"); + mAnimMap[ANIM_AGENT_TURNLEFT]= mAnimStringTable.addString("turnleft"); + mAnimMap[ANIM_AGENT_TURNRIGHT]= mAnimStringTable.addString("turnright"); + mAnimMap[ANIM_AGENT_TYPE]= mAnimStringTable.addString("type"); + mAnimMap[ANIM_AGENT_WALK]= mAnimStringTable.addString("walk"); + mAnimMap[ANIM_AGENT_WALK_NEW]= mAnimStringTable.addString("walk_new"); + mAnimMap[ANIM_AGENT_WHISPER]= mAnimStringTable.addString("whisper"); + mAnimMap[ANIM_AGENT_WHISTLE]= mAnimStringTable.addString("whistle"); + mAnimMap[ANIM_AGENT_WINK]= mAnimStringTable.addString("express_wink"); + mAnimMap[ANIM_AGENT_WINK_HOLLYWOOD]= mAnimStringTable.addString("wink_hollywood"); + mAnimMap[ANIM_AGENT_WORRY]= mAnimStringTable.addString("express_worry"); + mAnimMap[ANIM_AGENT_YES]= mAnimStringTable.addString("yes_head"); + mAnimMap[ANIM_AGENT_YES_HAPPY]= mAnimStringTable.addString("yes_happy"); + mAnimMap[ANIM_AGENT_YOGA_FLOAT]= mAnimStringTable.addString("yoga_float"); } - + //----------------------------------------------------------------------------- // ~LLAnimationLibrary() //----------------------------------------------------------------------------- @@ -351,16 +351,16 @@ LLAnimationLibrary::~LLAnimationLibrary() //----------------------------------------------------------------------------- const char *LLAnimationLibrary::animStateToString( const LLUUID& state ) { - if (state.isNull()) - { - return NULL; - } - if (mAnimMap.count(state)) - { - return mAnimMap[state]; - } + if (state.isNull()) + { + return NULL; + } + if (mAnimMap.count(state)) + { + return mAnimMap[state]; + } - return NULL; + return NULL; } @@ -369,32 +369,32 @@ const char *LLAnimationLibrary::animStateToString( const LLUUID& state ) //----------------------------------------------------------------------------- LLUUID LLAnimationLibrary::stringToAnimState( const std::string& name, BOOL allow_ids ) { - std::string lower_case_name(name); - LLStringUtil::toLower(lower_case_name); + std::string lower_case_name(name); + LLStringUtil::toLower(lower_case_name); - char *true_name = mAnimStringTable.checkString(lower_case_name.c_str()); + char *true_name = mAnimStringTable.checkString(lower_case_name.c_str()); - LLUUID id; - id.setNull(); + LLUUID id; + id.setNull(); - if (true_name) - { - for (anim_map_t::value_type& anim_pair : mAnimMap) - { - if (anim_pair.second == true_name) - { - id = anim_pair.first; - break; - } - } - } - else if (allow_ids) - { - // try to convert string to LLUUID - id.set(name, FALSE); - } + if (true_name) + { + for (anim_map_t::value_type& anim_pair : mAnimMap) + { + if (anim_pair.second == true_name) + { + id = anim_pair.first; + break; + } + } + } + else if (allow_ids) + { + // try to convert string to LLUUID + id.set(name, FALSE); + } - return id; + return id; } //----------------------------------------------------------------------------- @@ -402,90 +402,90 @@ LLUUID LLAnimationLibrary::stringToAnimState( const std::string& name, BOOL allo //----------------------------------------------------------------------------- void LLAnimationLibrary::animStateSetString( const LLUUID& state, const std::string& name) { - mAnimMap[state] = mAnimStringTable.addString(name); + mAnimMap[state] = mAnimStringTable.addString(name); } std::string LLAnimationLibrary::animationName( const LLUUID& id ) const { - const char *cptr = gAnimLibrary.animStateToString(id); - if (cptr) - return std::string(cptr); - else - return std::string("[") + id.asString() + std::string("]"); + const char *cptr = gAnimLibrary.animStateToString(id); + if (cptr) + return std::string(cptr); + else + return std::string("[") + id.asString() + std::string("]"); } // Animation states that the user can trigger as part of a gesture // See struct LLAnimStateEntry in header for label location information const LLAnimStateEntry gUserAnimStates[] = { - LLAnimStateEntry("express_afraid", ANIM_AGENT_AFRAID), - LLAnimStateEntry("express_anger", ANIM_AGENT_ANGRY), - LLAnimStateEntry("away", ANIM_AGENT_AWAY), - LLAnimStateEntry("backflip", ANIM_AGENT_BACKFLIP), - LLAnimStateEntry("express_laugh", ANIM_AGENT_BELLY_LAUGH), - LLAnimStateEntry("express_toothsmile", ANIM_AGENT_EXPRESS_TOOTHSMILE), - LLAnimStateEntry("blowkiss", ANIM_AGENT_BLOW_KISS), - LLAnimStateEntry("express_bored", ANIM_AGENT_BORED), - LLAnimStateEntry("bow", ANIM_AGENT_BOW), - LLAnimStateEntry("clap", ANIM_AGENT_CLAP), - LLAnimStateEntry("courtbow", ANIM_AGENT_COURTBOW), - LLAnimStateEntry("express_cry", ANIM_AGENT_CRY), - LLAnimStateEntry("dance1", ANIM_AGENT_DANCE1), - LLAnimStateEntry("dance2", ANIM_AGENT_DANCE2), - LLAnimStateEntry("dance3", ANIM_AGENT_DANCE3), - LLAnimStateEntry("dance4", ANIM_AGENT_DANCE4), - LLAnimStateEntry("dance5", ANIM_AGENT_DANCE5), - LLAnimStateEntry("dance6", ANIM_AGENT_DANCE6), - LLAnimStateEntry("dance7", ANIM_AGENT_DANCE7), - LLAnimStateEntry("dance8", ANIM_AGENT_DANCE8), - LLAnimStateEntry("express_disdain", ANIM_AGENT_EXPRESS_DISDAIN), - LLAnimStateEntry("drink", ANIM_AGENT_DRINK), - LLAnimStateEntry("express_embarrased", ANIM_AGENT_EMBARRASSED), - LLAnimStateEntry("angry_fingerwag", ANIM_AGENT_FINGER_WAG), - LLAnimStateEntry("fist_pump", ANIM_AGENT_FIST_PUMP), - LLAnimStateEntry("yoga_float", ANIM_AGENT_YOGA_FLOAT), - LLAnimStateEntry("express_frown", ANIM_AGENT_EXPRESS_FROWN), - LLAnimStateEntry("impatient", ANIM_AGENT_IMPATIENT), - LLAnimStateEntry("jumpforjoy", ANIM_AGENT_JUMP_FOR_JOY), - LLAnimStateEntry("kissmybutt", ANIM_AGENT_KISS_MY_BUTT), - LLAnimStateEntry("express_kiss", ANIM_AGENT_EXPRESS_KISS), - LLAnimStateEntry("laugh_short", ANIM_AGENT_LAUGH_SHORT), - LLAnimStateEntry("musclebeach", ANIM_AGENT_MUSCLE_BEACH), - LLAnimStateEntry("no_unhappy", ANIM_AGENT_NO_UNHAPPY), - LLAnimStateEntry("no_head", ANIM_AGENT_NO), - LLAnimStateEntry("nyanya", ANIM_AGENT_NYAH_NYAH), - LLAnimStateEntry("punch_onetwo", ANIM_AGENT_ONETWO_PUNCH), - LLAnimStateEntry("express_open_mouth", ANIM_AGENT_EXPRESS_OPEN_MOUTH), - LLAnimStateEntry("peace", ANIM_AGENT_PEACE), - LLAnimStateEntry("point_you", ANIM_AGENT_POINT_YOU), - LLAnimStateEntry("point_me", ANIM_AGENT_POINT_ME), - LLAnimStateEntry("punch_l", ANIM_AGENT_PUNCH_LEFT), - LLAnimStateEntry("punch_r", ANIM_AGENT_PUNCH_RIGHT), - LLAnimStateEntry("rps_countdown", ANIM_AGENT_RPS_COUNTDOWN), - LLAnimStateEntry("rps_paper", ANIM_AGENT_RPS_PAPER), - LLAnimStateEntry("rps_rock", ANIM_AGENT_RPS_ROCK), - LLAnimStateEntry("rps_scissors", ANIM_AGENT_RPS_SCISSORS), - LLAnimStateEntry("express_repulsed", ANIM_AGENT_EXPRESS_REPULSED), - LLAnimStateEntry("kick_roundhouse_r", ANIM_AGENT_ROUNDHOUSE_KICK), - LLAnimStateEntry("express_sad", ANIM_AGENT_SAD), - LLAnimStateEntry("salute", ANIM_AGENT_SALUTE), - LLAnimStateEntry("shout", ANIM_AGENT_SHOUT), - LLAnimStateEntry("express_shrug", ANIM_AGENT_SHRUG), - LLAnimStateEntry("express_smile", ANIM_AGENT_EXPRESS_SMILE), - LLAnimStateEntry("smoke_idle", ANIM_AGENT_SMOKE_IDLE), - LLAnimStateEntry("smoke_inhale", ANIM_AGENT_SMOKE_INHALE), - LLAnimStateEntry("smoke_throw_down", ANIM_AGENT_SMOKE_THROW_DOWN), - LLAnimStateEntry("express_surprise", ANIM_AGENT_SURPRISE), - LLAnimStateEntry("sword_strike_r", ANIM_AGENT_SWORD_STRIKE), - LLAnimStateEntry("angry_tantrum", ANIM_AGENT_TANTRUM), - LLAnimStateEntry("express_tongue_out", ANIM_AGENT_EXPRESS_TONGUE_OUT), - LLAnimStateEntry("hello", ANIM_AGENT_HELLO), - LLAnimStateEntry("whisper", ANIM_AGENT_WHISPER), - LLAnimStateEntry("whistle", ANIM_AGENT_WHISTLE), - LLAnimStateEntry("express_wink", ANIM_AGENT_WINK), - LLAnimStateEntry("wink_hollywood", ANIM_AGENT_WINK_HOLLYWOOD), - LLAnimStateEntry("express_worry", ANIM_AGENT_EXPRESS_WORRY), - LLAnimStateEntry("yes_happy", ANIM_AGENT_YES_HAPPY), - LLAnimStateEntry("yes_head", ANIM_AGENT_YES), + LLAnimStateEntry("express_afraid", ANIM_AGENT_AFRAID), + LLAnimStateEntry("express_anger", ANIM_AGENT_ANGRY), + LLAnimStateEntry("away", ANIM_AGENT_AWAY), + LLAnimStateEntry("backflip", ANIM_AGENT_BACKFLIP), + LLAnimStateEntry("express_laugh", ANIM_AGENT_BELLY_LAUGH), + LLAnimStateEntry("express_toothsmile", ANIM_AGENT_EXPRESS_TOOTHSMILE), + LLAnimStateEntry("blowkiss", ANIM_AGENT_BLOW_KISS), + LLAnimStateEntry("express_bored", ANIM_AGENT_BORED), + LLAnimStateEntry("bow", ANIM_AGENT_BOW), + LLAnimStateEntry("clap", ANIM_AGENT_CLAP), + LLAnimStateEntry("courtbow", ANIM_AGENT_COURTBOW), + LLAnimStateEntry("express_cry", ANIM_AGENT_CRY), + LLAnimStateEntry("dance1", ANIM_AGENT_DANCE1), + LLAnimStateEntry("dance2", ANIM_AGENT_DANCE2), + LLAnimStateEntry("dance3", ANIM_AGENT_DANCE3), + LLAnimStateEntry("dance4", ANIM_AGENT_DANCE4), + LLAnimStateEntry("dance5", ANIM_AGENT_DANCE5), + LLAnimStateEntry("dance6", ANIM_AGENT_DANCE6), + LLAnimStateEntry("dance7", ANIM_AGENT_DANCE7), + LLAnimStateEntry("dance8", ANIM_AGENT_DANCE8), + LLAnimStateEntry("express_disdain", ANIM_AGENT_EXPRESS_DISDAIN), + LLAnimStateEntry("drink", ANIM_AGENT_DRINK), + LLAnimStateEntry("express_embarrased", ANIM_AGENT_EMBARRASSED), + LLAnimStateEntry("angry_fingerwag", ANIM_AGENT_FINGER_WAG), + LLAnimStateEntry("fist_pump", ANIM_AGENT_FIST_PUMP), + LLAnimStateEntry("yoga_float", ANIM_AGENT_YOGA_FLOAT), + LLAnimStateEntry("express_frown", ANIM_AGENT_EXPRESS_FROWN), + LLAnimStateEntry("impatient", ANIM_AGENT_IMPATIENT), + LLAnimStateEntry("jumpforjoy", ANIM_AGENT_JUMP_FOR_JOY), + LLAnimStateEntry("kissmybutt", ANIM_AGENT_KISS_MY_BUTT), + LLAnimStateEntry("express_kiss", ANIM_AGENT_EXPRESS_KISS), + LLAnimStateEntry("laugh_short", ANIM_AGENT_LAUGH_SHORT), + LLAnimStateEntry("musclebeach", ANIM_AGENT_MUSCLE_BEACH), + LLAnimStateEntry("no_unhappy", ANIM_AGENT_NO_UNHAPPY), + LLAnimStateEntry("no_head", ANIM_AGENT_NO), + LLAnimStateEntry("nyanya", ANIM_AGENT_NYAH_NYAH), + LLAnimStateEntry("punch_onetwo", ANIM_AGENT_ONETWO_PUNCH), + LLAnimStateEntry("express_open_mouth", ANIM_AGENT_EXPRESS_OPEN_MOUTH), + LLAnimStateEntry("peace", ANIM_AGENT_PEACE), + LLAnimStateEntry("point_you", ANIM_AGENT_POINT_YOU), + LLAnimStateEntry("point_me", ANIM_AGENT_POINT_ME), + LLAnimStateEntry("punch_l", ANIM_AGENT_PUNCH_LEFT), + LLAnimStateEntry("punch_r", ANIM_AGENT_PUNCH_RIGHT), + LLAnimStateEntry("rps_countdown", ANIM_AGENT_RPS_COUNTDOWN), + LLAnimStateEntry("rps_paper", ANIM_AGENT_RPS_PAPER), + LLAnimStateEntry("rps_rock", ANIM_AGENT_RPS_ROCK), + LLAnimStateEntry("rps_scissors", ANIM_AGENT_RPS_SCISSORS), + LLAnimStateEntry("express_repulsed", ANIM_AGENT_EXPRESS_REPULSED), + LLAnimStateEntry("kick_roundhouse_r", ANIM_AGENT_ROUNDHOUSE_KICK), + LLAnimStateEntry("express_sad", ANIM_AGENT_SAD), + LLAnimStateEntry("salute", ANIM_AGENT_SALUTE), + LLAnimStateEntry("shout", ANIM_AGENT_SHOUT), + LLAnimStateEntry("express_shrug", ANIM_AGENT_SHRUG), + LLAnimStateEntry("express_smile", ANIM_AGENT_EXPRESS_SMILE), + LLAnimStateEntry("smoke_idle", ANIM_AGENT_SMOKE_IDLE), + LLAnimStateEntry("smoke_inhale", ANIM_AGENT_SMOKE_INHALE), + LLAnimStateEntry("smoke_throw_down", ANIM_AGENT_SMOKE_THROW_DOWN), + LLAnimStateEntry("express_surprise", ANIM_AGENT_SURPRISE), + LLAnimStateEntry("sword_strike_r", ANIM_AGENT_SWORD_STRIKE), + LLAnimStateEntry("angry_tantrum", ANIM_AGENT_TANTRUM), + LLAnimStateEntry("express_tongue_out", ANIM_AGENT_EXPRESS_TONGUE_OUT), + LLAnimStateEntry("hello", ANIM_AGENT_HELLO), + LLAnimStateEntry("whisper", ANIM_AGENT_WHISPER), + LLAnimStateEntry("whistle", ANIM_AGENT_WHISTLE), + LLAnimStateEntry("express_wink", ANIM_AGENT_WINK), + LLAnimStateEntry("wink_hollywood", ANIM_AGENT_WINK_HOLLYWOOD), + LLAnimStateEntry("express_worry", ANIM_AGENT_EXPRESS_WORRY), + LLAnimStateEntry("yes_happy", ANIM_AGENT_YES_HAPPY), + LLAnimStateEntry("yes_head", ANIM_AGENT_YES), }; const S32 gUserAnimStatesCount = LL_ARRAY_SIZE(gUserAnimStates); diff --git a/indra/llcharacter/llanimationstates.h b/indra/llcharacter/llanimationstates.h index 79cbcabdc1..70134c12ab 100644 --- a/indra/llcharacter/llanimationstates.h +++ b/indra/llcharacter/llanimationstates.h @@ -1,25 +1,25 @@ -/** +/** * @file llanimationstates.h * @brief Implementation of animation state support. * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -201,54 +201,54 @@ extern S32 NUM_AGENT_STAND_ANIMS; class LLAnimationLibrary { private: - LLStringTable mAnimStringTable; + LLStringTable mAnimStringTable; - typedef std::map<LLUUID, char *> anim_map_t; - anim_map_t mAnimMap; + typedef std::map<LLUUID, char *> anim_map_t; + anim_map_t mAnimMap; public: - LLAnimationLibrary(); - ~LLAnimationLibrary(); + LLAnimationLibrary(); + ~LLAnimationLibrary(); - //----------------------------------------------------------------------------- - // Return the text name of a single animation state, - // Return NULL if the state is invalid - //----------------------------------------------------------------------------- - const char *animStateToString( const LLUUID& state ); + //----------------------------------------------------------------------------- + // Return the text name of a single animation state, + // Return NULL if the state is invalid + //----------------------------------------------------------------------------- + const char *animStateToString( const LLUUID& state ); - //----------------------------------------------------------------------------- - // Return the animation state for the given name. - // Retun NULL if the name is invalid. - //----------------------------------------------------------------------------- - LLUUID stringToAnimState( const std::string& name, BOOL allow_ids = TRUE ); + //----------------------------------------------------------------------------- + // Return the animation state for the given name. + // Retun NULL if the name is invalid. + //----------------------------------------------------------------------------- + LLUUID stringToAnimState( const std::string& name, BOOL allow_ids = TRUE ); - //----------------------------------------------------------------------------- - // Associate an anim state with a name - //----------------------------------------------------------------------------- - void animStateSetString( const LLUUID& state, const std::string& name); + //----------------------------------------------------------------------------- + // Associate an anim state with a name + //----------------------------------------------------------------------------- + void animStateSetString( const LLUUID& state, const std::string& name); - //----------------------------------------------------------------------------- - // Find the name for a given animation, or UUID string if none defined. - //----------------------------------------------------------------------------- - std::string animationName( const LLUUID& id ) const; + //----------------------------------------------------------------------------- + // Find the name for a given animation, or UUID string if none defined. + //----------------------------------------------------------------------------- + std::string animationName( const LLUUID& id ) const; }; struct LLAnimStateEntry { - LLAnimStateEntry(const char* name, const LLUUID& id) : - mName(name), - mID(id) - { - // LABELS: - // Look to newview/LLAnimStateLabels.* for how to get the labels. - // The labels should no longer be stored in this structure. The server - // shouldn't care about the local friendly name of an animation, and - // this is common code. - } + LLAnimStateEntry(const char* name, const LLUUID& id) : + mName(name), + mID(id) + { + // LABELS: + // Look to newview/LLAnimStateLabels.* for how to get the labels. + // The labels should no longer be stored in this structure. The server + // shouldn't care about the local friendly name of an animation, and + // this is common code. + } - const char* mName; - const LLUUID mID; + const char* mName; + const LLUUID mID; }; // Animation states that the user can trigger diff --git a/indra/llcharacter/llbvhconsts.h b/indra/llcharacter/llbvhconsts.h index b06c279b8f..3f353fe2cc 100644 --- a/indra/llcharacter/llbvhconsts.h +++ b/indra/llcharacter/llbvhconsts.h @@ -1,25 +1,25 @@ -/** +/** * @file llbvhconsts.h * @brief Consts and types useful to BVH files and LindenLabAnimation format. * * $LicenseInfo:firstyear=2004&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -30,17 +30,17 @@ const F32 MAX_ANIM_DURATION = 60.f; typedef enum e_constraint_type - { - CONSTRAINT_TYPE_POINT, - CONSTRAINT_TYPE_PLANE, - NUM_CONSTRAINT_TYPES - } EConstraintType; + { + CONSTRAINT_TYPE_POINT, + CONSTRAINT_TYPE_PLANE, + NUM_CONSTRAINT_TYPES + } EConstraintType; typedef enum e_constraint_target_type - { - CONSTRAINT_TARGET_TYPE_BODY, - CONSTRAINT_TARGET_TYPE_GROUND, - NUM_CONSTRAINT_TARGET_TYPES - } EConstraintTargetType; + { + CONSTRAINT_TARGET_TYPE_BODY, + CONSTRAINT_TARGET_TYPE_GROUND, + NUM_CONSTRAINT_TARGET_TYPES + } EConstraintTargetType; #endif // LL_LLBVHCONSTS_H diff --git a/indra/llcharacter/llbvhloader.cpp b/indra/llcharacter/llbvhloader.cpp index 5b1b28bf4f..3aa2c86aad 100644 --- a/indra/llcharacter/llbvhloader.cpp +++ b/indra/llcharacter/llbvhloader.cpp @@ -1,25 +1,25 @@ -/** +/** * @file llbvhloader.cpp * @brief Translates a BVH files to LindenLabAnimation format. * * $LicenseInfo:firstyear=2004&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful,7 * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -58,43 +58,43 @@ const F32 ROTATION_KEYFRAME_THRESHOLD = 0.01f; const F32 POSITION_MOTION_THRESHOLD_SQUARED = 0.001f * 0.001f; const F32 ROTATION_MOTION_THRESHOLD = 0.001f; -char gInFile[1024]; /* Flawfinder: ignore */ -char gOutFile[1024]; /* Flawfinder: ignore */ +char gInFile[1024]; /* Flawfinder: ignore */ +char gOutFile[1024]; /* Flawfinder: ignore */ /* //------------------------------------------------------------------------ // Status Codes //------------------------------------------------------------------------ -const char *LLBVHLoader::ST_OK = "Ok"; -const char *LLBVHLoader::ST_EOF = "Premature end of file."; -const char *LLBVHLoader::ST_NO_CONSTRAINT = "Can't read constraint definition."; -const char *LLBVHLoader::ST_NO_FILE = "Can't open BVH file."; -const char *LLBVHLoader::ST_NO_HIER = "Invalid HIERARCHY header."; -const char *LLBVHLoader::ST_NO_JOINT = "Can't find ROOT or JOINT."; -const char *LLBVHLoader::ST_NO_NAME = "Can't get JOINT name."; -const char *LLBVHLoader::ST_NO_OFFSET = "Can't find OFFSET."; -const char *LLBVHLoader::ST_NO_CHANNELS = "Can't find CHANNELS."; -const char *LLBVHLoader::ST_NO_ROTATION = "Can't get rotation order."; -const char *LLBVHLoader::ST_NO_AXIS = "Can't get rotation axis."; -const char *LLBVHLoader::ST_NO_MOTION = "Can't find MOTION."; -const char *LLBVHLoader::ST_NO_FRAMES = "Can't get number of frames."; -const char *LLBVHLoader::ST_NO_FRAME_TIME = "Can't get frame time."; -const char *LLBVHLoader::ST_NO_POS = "Can't get position values."; -const char *LLBVHLoader::ST_NO_ROT = "Can't get rotation values."; -const char *LLBVHLoader::ST_NO_XLT_FILE = "Can't open translation file."; -const char *LLBVHLoader::ST_NO_XLT_HEADER = "Can't read translation header."; -const char *LLBVHLoader::ST_NO_XLT_NAME = "Can't read translation names."; -const char *LLBVHLoader::ST_NO_XLT_IGNORE = "Can't read translation ignore value."; -const char *LLBVHLoader::ST_NO_XLT_RELATIVE = "Can't read translation relative value."; -const char *LLBVHLoader::ST_NO_XLT_OUTNAME = "Can't read translation outname value."; -const char *LLBVHLoader::ST_NO_XLT_MATRIX = "Can't read translation matrix."; +const char *LLBVHLoader::ST_OK = "Ok"; +const char *LLBVHLoader::ST_EOF = "Premature end of file."; +const char *LLBVHLoader::ST_NO_CONSTRAINT = "Can't read constraint definition."; +const char *LLBVHLoader::ST_NO_FILE = "Can't open BVH file."; +const char *LLBVHLoader::ST_NO_HIER = "Invalid HIERARCHY header."; +const char *LLBVHLoader::ST_NO_JOINT = "Can't find ROOT or JOINT."; +const char *LLBVHLoader::ST_NO_NAME = "Can't get JOINT name."; +const char *LLBVHLoader::ST_NO_OFFSET = "Can't find OFFSET."; +const char *LLBVHLoader::ST_NO_CHANNELS = "Can't find CHANNELS."; +const char *LLBVHLoader::ST_NO_ROTATION = "Can't get rotation order."; +const char *LLBVHLoader::ST_NO_AXIS = "Can't get rotation axis."; +const char *LLBVHLoader::ST_NO_MOTION = "Can't find MOTION."; +const char *LLBVHLoader::ST_NO_FRAMES = "Can't get number of frames."; +const char *LLBVHLoader::ST_NO_FRAME_TIME = "Can't get frame time."; +const char *LLBVHLoader::ST_NO_POS = "Can't get position values."; +const char *LLBVHLoader::ST_NO_ROT = "Can't get rotation values."; +const char *LLBVHLoader::ST_NO_XLT_FILE = "Can't open translation file."; +const char *LLBVHLoader::ST_NO_XLT_HEADER = "Can't read translation header."; +const char *LLBVHLoader::ST_NO_XLT_NAME = "Can't read translation names."; +const char *LLBVHLoader::ST_NO_XLT_IGNORE = "Can't read translation ignore value."; +const char *LLBVHLoader::ST_NO_XLT_RELATIVE = "Can't read translation relative value."; +const char *LLBVHLoader::ST_NO_XLT_OUTNAME = "Can't read translation outname value."; +const char *LLBVHLoader::ST_NO_XLT_MATRIX = "Can't read translation matrix."; const char *LLBVHLoader::ST_NO_XLT_MERGECHILD = "Can't get mergechild name."; const char *LLBVHLoader::ST_NO_XLT_MERGEPARENT = "Can't get mergeparent name."; -const char *LLBVHLoader::ST_NO_XLT_PRIORITY = "Can't get priority value."; -const char *LLBVHLoader::ST_NO_XLT_LOOP = "Can't get loop value."; -const char *LLBVHLoader::ST_NO_XLT_EASEIN = "Can't get easeIn values."; -const char *LLBVHLoader::ST_NO_XLT_EASEOUT = "Can't get easeOut values."; -const char *LLBVHLoader::ST_NO_XLT_HAND = "Can't get hand morph value."; -const char *LLBVHLoader::ST_NO_XLT_EMOTE = "Can't read emote name."; +const char *LLBVHLoader::ST_NO_XLT_PRIORITY = "Can't get priority value."; +const char *LLBVHLoader::ST_NO_XLT_LOOP = "Can't get loop value."; +const char *LLBVHLoader::ST_NO_XLT_EASEIN = "Can't get easeIn values."; +const char *LLBVHLoader::ST_NO_XLT_EASEOUT = "Can't get easeOut values."; +const char *LLBVHLoader::ST_NO_XLT_HAND = "Can't get hand morph value."; +const char *LLBVHLoader::ST_NO_XLT_EMOTE = "Can't read emote name."; const char *LLBVHLoader::ST_BAD_ROOT = "Illegal ROOT joint."; */ @@ -103,9 +103,9 @@ const char *LLBVHLoader::ST_BAD_ROOT = "Illegal ROOT joint."; //------------------------------------------------------------------------ const char *find_next_whitespace(const char *p) { - while(*p && isspace(*p)) p++; - while(*p && !isspace(*p)) p++; - return p; + while(*p && isspace(*p)) p++; + while(*p && !isspace(*p)) p++; + return p; } @@ -118,13 +118,13 @@ const char *find_next_whitespace(const char *p) //------------------------------------------------------------------------ LLQuaternion::Order bvhStringToOrder( char *str ) { - char order[4]; /* Flawfinder: ignore */ - order[0] = str[2]; - order[1] = str[1]; - order[2] = str[0]; - order[3] = 0; - LLQuaternion::Order retVal = StringToOrder( order ); - return retVal; + char order[4]; /* Flawfinder: ignore */ + order[0] = str[2]; + order[1] = str[1]; + order[2] = str[0]; + order[3] = 0; + LLQuaternion::Order retVal = StringToOrder( order ); + return retVal; } //----------------------------------------------------------------------------- @@ -133,65 +133,65 @@ LLQuaternion::Order bvhStringToOrder( char *str ) LLBVHLoader::LLBVHLoader(const char* buffer, ELoadStatus &loadStatus, S32 &errorLine, std::map<std::string, std::string>& joint_alias_map ) { - reset(); - errorLine = 0; - mStatus = loadTranslationTable("anim.ini"); - loadStatus = mStatus; - LL_INFOS("BVH") << "Load Status 00 : " << loadStatus << LL_ENDL; - if (mStatus == E_ST_NO_XLT_FILE) - { - LL_WARNS("BVH") << "NOTE: No translation table found." << LL_ENDL; - loadStatus = mStatus; - return; - } - else - { - if (mStatus != E_ST_OK) - { - LL_WARNS("BVH") << "ERROR: [line: " << getLineNumber() << "] " << mStatus << LL_ENDL; - errorLine = getLineNumber(); - loadStatus = mStatus; - return; - } - } - + reset(); + errorLine = 0; + mStatus = loadTranslationTable("anim.ini"); + loadStatus = mStatus; + LL_INFOS("BVH") << "Load Status 00 : " << loadStatus << LL_ENDL; + if (mStatus == E_ST_NO_XLT_FILE) + { + LL_WARNS("BVH") << "NOTE: No translation table found." << LL_ENDL; + loadStatus = mStatus; + return; + } + else + { + if (mStatus != E_ST_OK) + { + LL_WARNS("BVH") << "ERROR: [line: " << getLineNumber() << "] " << mStatus << LL_ENDL; + errorLine = getLineNumber(); + loadStatus = mStatus; + return; + } + } + // Recognize all names we've been told are legal. for (std::map<std::string, std::string>::value_type& alias_pair : joint_alias_map) { makeTranslation( alias_pair.first , alias_pair.second ); } - - char error_text[128]; /* Flawfinder: ignore */ - S32 error_line; - mStatus = loadBVHFile(buffer, error_text, error_line); //Reads all joints in BVH file. - - LL_DEBUGS("BVH") << "============================================================" << LL_ENDL; - LL_DEBUGS("BVH") << "Raw data from file" << LL_ENDL; - dumpBVHInfo(); - - if (mStatus != E_ST_OK) - { - LL_WARNS("BVH") << "ERROR: [line: " << getLineNumber() << "] " << mStatus << LL_ENDL; - loadStatus = mStatus; - errorLine = getLineNumber(); - return; - } - - applyTranslations(); //Maps between joints found in file and the aliased names. - optimize(); - - LL_DEBUGS("BVH") << "============================================================" << LL_ENDL; - LL_DEBUGS("BVH") << "After translations and optimize" << LL_ENDL; - dumpBVHInfo(); - - mInitialized = TRUE; + + char error_text[128]; /* Flawfinder: ignore */ + S32 error_line; + mStatus = loadBVHFile(buffer, error_text, error_line); //Reads all joints in BVH file. + + LL_DEBUGS("BVH") << "============================================================" << LL_ENDL; + LL_DEBUGS("BVH") << "Raw data from file" << LL_ENDL; + dumpBVHInfo(); + + if (mStatus != E_ST_OK) + { + LL_WARNS("BVH") << "ERROR: [line: " << getLineNumber() << "] " << mStatus << LL_ENDL; + loadStatus = mStatus; + errorLine = getLineNumber(); + return; + } + + applyTranslations(); //Maps between joints found in file and the aliased names. + optimize(); + + LL_DEBUGS("BVH") << "============================================================" << LL_ENDL; + LL_DEBUGS("BVH") << "After translations and optimize" << LL_ENDL; + dumpBVHInfo(); + + mInitialized = TRUE; } LLBVHLoader::~LLBVHLoader() { - std::for_each(mJoints.begin(),mJoints.end(),DeletePointer()); - mJoints.clear(); + std::for_each(mJoints.begin(),mJoints.end(),DeletePointer()); + mJoints.clear(); } //------------------------------------------------------------------------ @@ -199,301 +199,301 @@ LLBVHLoader::~LLBVHLoader() //------------------------------------------------------------------------ ELoadStatus LLBVHLoader::loadTranslationTable(const char *fileName) { - //-------------------------------------------------------------------- - // open file - //-------------------------------------------------------------------- - std::string path = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS,fileName); - - LLAPRFile infile ; - infile.open(path, LL_APR_R); - apr_file_t *fp = infile.getFileHandle(); - if (!fp) - return E_ST_NO_XLT_FILE; - - LL_INFOS("BVH") << "NOTE: Loading translation table: " << fileName << LL_ENDL; - - //-------------------------------------------------------------------- - // register file to be closed on function exit - //-------------------------------------------------------------------- - - //-------------------------------------------------------------------- - // load header - //-------------------------------------------------------------------- - if ( ! getLine(fp) ) - return E_ST_EOF; - if ( strncmp(mLine, "Translations 1.0", 16) ) - return E_ST_NO_XLT_HEADER; - - //-------------------------------------------------------------------- - // load data one line at a time - //-------------------------------------------------------------------- - BOOL loadingGlobals = FALSE; - while ( getLine(fp) ) - { - //---------------------------------------------------------------- - // check the 1st token on the line to determine if it's empty or a comment - //---------------------------------------------------------------- - char token[128]; /* Flawfinder: ignore */ - if ( sscanf(mLine, " %127s", token) != 1 ) /* Flawfinder: ignore */ - continue; - - if (token[0] == '#') - continue; - - //---------------------------------------------------------------- - // check if a [jointName] or [GLOBALS] was specified. - //---------------------------------------------------------------- - if (token[0] == '[') - { - char name[128]; /* Flawfinder: ignore */ - if ( sscanf(mLine, " [%127[^]]", name) != 1 ) - return E_ST_NO_XLT_NAME; - - if (strcmp(name, "GLOBALS")==0) - { - loadingGlobals = TRUE; - continue; - } - } - - //---------------------------------------------------------------- - // check for optional emote - //---------------------------------------------------------------- - if (loadingGlobals && LLStringUtil::compareInsensitive(token, "emote")==0) - { - char emote_str[1024]; /* Flawfinder: ignore */ - if ( sscanf(mLine, " %*s = %1023s", emote_str) != 1 ) /* Flawfinder: ignore */ - return E_ST_NO_XLT_EMOTE; - - mEmoteName.assign( emote_str ); -// LL_INFOS() << "NOTE: Emote: " << mEmoteName.c_str() << LL_ENDL; - continue; - } - - - //---------------------------------------------------------------- - // check for global priority setting - //---------------------------------------------------------------- - if (loadingGlobals && LLStringUtil::compareInsensitive(token, "priority")==0) - { - S32 priority; - if ( sscanf(mLine, " %*s = %d", &priority) != 1 ) - return E_ST_NO_XLT_PRIORITY; - - mPriority = priority; -// LL_INFOS() << "NOTE: Priority: " << mPriority << LL_ENDL; - continue; - } - - //---------------------------------------------------------------- - // check for global loop setting - //---------------------------------------------------------------- - if (loadingGlobals && LLStringUtil::compareInsensitive(token, "loop")==0) - { - char trueFalse[128]; /* Flawfinder: ignore */ - trueFalse[0] = '\0'; - - F32 loop_in = 0.f; - F32 loop_out = 1.f; - - if ( sscanf(mLine, " %*s = %f %f", &loop_in, &loop_out) == 2 ) - { - mLoop = TRUE; - } - else if ( sscanf(mLine, " %*s = %127s", trueFalse) == 1 ) /* Flawfinder: ignore */ - { - mLoop = (LLStringUtil::compareInsensitive(trueFalse, "true")==0); - } - else - { - return E_ST_NO_XLT_LOOP; - } - - mLoopInPoint = loop_in * mDuration; - mLoopOutPoint = loop_out * mDuration; - - continue; - } - - //---------------------------------------------------------------- - // check for global easeIn setting - //---------------------------------------------------------------- - if (loadingGlobals && LLStringUtil::compareInsensitive(token, "easein")==0) - { - F32 duration; - char type[128]; /* Flawfinder: ignore */ - if ( sscanf(mLine, " %*s = %f %127s", &duration, type) != 2 ) /* Flawfinder: ignore */ - return E_ST_NO_XLT_EASEIN; - - mEaseIn = duration; - continue; - } - - //---------------------------------------------------------------- - // check for global easeOut setting - //---------------------------------------------------------------- - if (loadingGlobals && LLStringUtil::compareInsensitive(token, "easeout")==0) - { - F32 duration; - char type[128]; /* Flawfinder: ignore */ - if ( sscanf(mLine, " %*s = %f %127s", &duration, type) != 2 ) /* Flawfinder: ignore */ - return E_ST_NO_XLT_EASEOUT; - - mEaseOut = duration; - continue; - } - - //---------------------------------------------------------------- - // check for global handMorph setting - //---------------------------------------------------------------- - if (loadingGlobals && LLStringUtil::compareInsensitive(token, "hand")==0) - { - S32 handMorph; - if (sscanf(mLine, " %*s = %d", &handMorph) != 1) - return E_ST_NO_XLT_HAND; - - mHand = handMorph; - continue; - } - - if (loadingGlobals && LLStringUtil::compareInsensitive(token, "constraint")==0) - { - Constraint constraint; - - // try reading optional target direction - if(sscanf( /* Flawfinder: ignore */ - mLine, - " %*s = %d %f %f %f %f %15s %f %f %f %15s %f %f %f %f %f %f", - &constraint.mChainLength, - &constraint.mEaseInStart, - &constraint.mEaseInStop, - &constraint.mEaseOutStart, - &constraint.mEaseOutStop, - constraint.mSourceJointName, - &constraint.mSourceOffset.mV[VX], - &constraint.mSourceOffset.mV[VY], - &constraint.mSourceOffset.mV[VZ], - constraint.mTargetJointName, - &constraint.mTargetOffset.mV[VX], - &constraint.mTargetOffset.mV[VY], - &constraint.mTargetOffset.mV[VZ], - &constraint.mTargetDir.mV[VX], - &constraint.mTargetDir.mV[VY], - &constraint.mTargetDir.mV[VZ]) != 16) - { - if(sscanf( /* Flawfinder: ignore */ - mLine, - " %*s = %d %f %f %f %f %15s %f %f %f %15s %f %f %f", - &constraint.mChainLength, - &constraint.mEaseInStart, - &constraint.mEaseInStop, - &constraint.mEaseOutStart, - &constraint.mEaseOutStop, - constraint.mSourceJointName, - &constraint.mSourceOffset.mV[VX], - &constraint.mSourceOffset.mV[VY], - &constraint.mSourceOffset.mV[VZ], - constraint.mTargetJointName, - &constraint.mTargetOffset.mV[VX], - &constraint.mTargetOffset.mV[VY], - &constraint.mTargetOffset.mV[VZ]) != 13) - { - return E_ST_NO_CONSTRAINT; - } - } - else - { - // normalize direction - if (!constraint.mTargetDir.isExactlyZero()) - { - constraint.mTargetDir.normVec(); - } - - } - - constraint.mConstraintType = CONSTRAINT_TYPE_POINT; - mConstraints.push_back(constraint); - continue; - } - - if (loadingGlobals && LLStringUtil::compareInsensitive(token, "planar_constraint")==0) - { - Constraint constraint; - - // try reading optional target direction - if(sscanf( /* Flawfinder: ignore */ - mLine, - " %*s = %d %f %f %f %f %15s %f %f %f %15s %f %f %f %f %f %f", - &constraint.mChainLength, - &constraint.mEaseInStart, - &constraint.mEaseInStop, - &constraint.mEaseOutStart, - &constraint.mEaseOutStop, - constraint.mSourceJointName, - &constraint.mSourceOffset.mV[VX], - &constraint.mSourceOffset.mV[VY], - &constraint.mSourceOffset.mV[VZ], - constraint.mTargetJointName, - &constraint.mTargetOffset.mV[VX], - &constraint.mTargetOffset.mV[VY], - &constraint.mTargetOffset.mV[VZ], - &constraint.mTargetDir.mV[VX], - &constraint.mTargetDir.mV[VY], - &constraint.mTargetDir.mV[VZ]) != 16) - { - if(sscanf( /* Flawfinder: ignore */ - mLine, - " %*s = %d %f %f %f %f %15s %f %f %f %15s %f %f %f", - &constraint.mChainLength, - &constraint.mEaseInStart, - &constraint.mEaseInStop, - &constraint.mEaseOutStart, - &constraint.mEaseOutStop, - constraint.mSourceJointName, - &constraint.mSourceOffset.mV[VX], - &constraint.mSourceOffset.mV[VY], - &constraint.mSourceOffset.mV[VZ], - constraint.mTargetJointName, - &constraint.mTargetOffset.mV[VX], - &constraint.mTargetOffset.mV[VY], - &constraint.mTargetOffset.mV[VZ]) != 13) - { - return E_ST_NO_CONSTRAINT; - } - } - else - { - // normalize direction - if (!constraint.mTargetDir.isExactlyZero()) - { - constraint.mTargetDir.normVec(); - } - - } - - constraint.mConstraintType = CONSTRAINT_TYPE_PLANE; - mConstraints.push_back(constraint); - continue; - } - } - - infile.close() ; - return E_ST_OK; + //-------------------------------------------------------------------- + // open file + //-------------------------------------------------------------------- + std::string path = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS,fileName); + + LLAPRFile infile ; + infile.open(path, LL_APR_R); + apr_file_t *fp = infile.getFileHandle(); + if (!fp) + return E_ST_NO_XLT_FILE; + + LL_INFOS("BVH") << "NOTE: Loading translation table: " << fileName << LL_ENDL; + + //-------------------------------------------------------------------- + // register file to be closed on function exit + //-------------------------------------------------------------------- + + //-------------------------------------------------------------------- + // load header + //-------------------------------------------------------------------- + if ( ! getLine(fp) ) + return E_ST_EOF; + if ( strncmp(mLine, "Translations 1.0", 16) ) + return E_ST_NO_XLT_HEADER; + + //-------------------------------------------------------------------- + // load data one line at a time + //-------------------------------------------------------------------- + BOOL loadingGlobals = FALSE; + while ( getLine(fp) ) + { + //---------------------------------------------------------------- + // check the 1st token on the line to determine if it's empty or a comment + //---------------------------------------------------------------- + char token[128]; /* Flawfinder: ignore */ + if ( sscanf(mLine, " %127s", token) != 1 ) /* Flawfinder: ignore */ + continue; + + if (token[0] == '#') + continue; + + //---------------------------------------------------------------- + // check if a [jointName] or [GLOBALS] was specified. + //---------------------------------------------------------------- + if (token[0] == '[') + { + char name[128]; /* Flawfinder: ignore */ + if ( sscanf(mLine, " [%127[^]]", name) != 1 ) + return E_ST_NO_XLT_NAME; + + if (strcmp(name, "GLOBALS")==0) + { + loadingGlobals = TRUE; + continue; + } + } + + //---------------------------------------------------------------- + // check for optional emote + //---------------------------------------------------------------- + if (loadingGlobals && LLStringUtil::compareInsensitive(token, "emote")==0) + { + char emote_str[1024]; /* Flawfinder: ignore */ + if ( sscanf(mLine, " %*s = %1023s", emote_str) != 1 ) /* Flawfinder: ignore */ + return E_ST_NO_XLT_EMOTE; + + mEmoteName.assign( emote_str ); +// LL_INFOS() << "NOTE: Emote: " << mEmoteName.c_str() << LL_ENDL; + continue; + } + + + //---------------------------------------------------------------- + // check for global priority setting + //---------------------------------------------------------------- + if (loadingGlobals && LLStringUtil::compareInsensitive(token, "priority")==0) + { + S32 priority; + if ( sscanf(mLine, " %*s = %d", &priority) != 1 ) + return E_ST_NO_XLT_PRIORITY; + + mPriority = priority; +// LL_INFOS() << "NOTE: Priority: " << mPriority << LL_ENDL; + continue; + } + + //---------------------------------------------------------------- + // check for global loop setting + //---------------------------------------------------------------- + if (loadingGlobals && LLStringUtil::compareInsensitive(token, "loop")==0) + { + char trueFalse[128]; /* Flawfinder: ignore */ + trueFalse[0] = '\0'; + + F32 loop_in = 0.f; + F32 loop_out = 1.f; + + if ( sscanf(mLine, " %*s = %f %f", &loop_in, &loop_out) == 2 ) + { + mLoop = TRUE; + } + else if ( sscanf(mLine, " %*s = %127s", trueFalse) == 1 ) /* Flawfinder: ignore */ + { + mLoop = (LLStringUtil::compareInsensitive(trueFalse, "true")==0); + } + else + { + return E_ST_NO_XLT_LOOP; + } + + mLoopInPoint = loop_in * mDuration; + mLoopOutPoint = loop_out * mDuration; + + continue; + } + + //---------------------------------------------------------------- + // check for global easeIn setting + //---------------------------------------------------------------- + if (loadingGlobals && LLStringUtil::compareInsensitive(token, "easein")==0) + { + F32 duration; + char type[128]; /* Flawfinder: ignore */ + if ( sscanf(mLine, " %*s = %f %127s", &duration, type) != 2 ) /* Flawfinder: ignore */ + return E_ST_NO_XLT_EASEIN; + + mEaseIn = duration; + continue; + } + + //---------------------------------------------------------------- + // check for global easeOut setting + //---------------------------------------------------------------- + if (loadingGlobals && LLStringUtil::compareInsensitive(token, "easeout")==0) + { + F32 duration; + char type[128]; /* Flawfinder: ignore */ + if ( sscanf(mLine, " %*s = %f %127s", &duration, type) != 2 ) /* Flawfinder: ignore */ + return E_ST_NO_XLT_EASEOUT; + + mEaseOut = duration; + continue; + } + + //---------------------------------------------------------------- + // check for global handMorph setting + //---------------------------------------------------------------- + if (loadingGlobals && LLStringUtil::compareInsensitive(token, "hand")==0) + { + S32 handMorph; + if (sscanf(mLine, " %*s = %d", &handMorph) != 1) + return E_ST_NO_XLT_HAND; + + mHand = handMorph; + continue; + } + + if (loadingGlobals && LLStringUtil::compareInsensitive(token, "constraint")==0) + { + Constraint constraint; + + // try reading optional target direction + if(sscanf( /* Flawfinder: ignore */ + mLine, + " %*s = %d %f %f %f %f %15s %f %f %f %15s %f %f %f %f %f %f", + &constraint.mChainLength, + &constraint.mEaseInStart, + &constraint.mEaseInStop, + &constraint.mEaseOutStart, + &constraint.mEaseOutStop, + constraint.mSourceJointName, + &constraint.mSourceOffset.mV[VX], + &constraint.mSourceOffset.mV[VY], + &constraint.mSourceOffset.mV[VZ], + constraint.mTargetJointName, + &constraint.mTargetOffset.mV[VX], + &constraint.mTargetOffset.mV[VY], + &constraint.mTargetOffset.mV[VZ], + &constraint.mTargetDir.mV[VX], + &constraint.mTargetDir.mV[VY], + &constraint.mTargetDir.mV[VZ]) != 16) + { + if(sscanf( /* Flawfinder: ignore */ + mLine, + " %*s = %d %f %f %f %f %15s %f %f %f %15s %f %f %f", + &constraint.mChainLength, + &constraint.mEaseInStart, + &constraint.mEaseInStop, + &constraint.mEaseOutStart, + &constraint.mEaseOutStop, + constraint.mSourceJointName, + &constraint.mSourceOffset.mV[VX], + &constraint.mSourceOffset.mV[VY], + &constraint.mSourceOffset.mV[VZ], + constraint.mTargetJointName, + &constraint.mTargetOffset.mV[VX], + &constraint.mTargetOffset.mV[VY], + &constraint.mTargetOffset.mV[VZ]) != 13) + { + return E_ST_NO_CONSTRAINT; + } + } + else + { + // normalize direction + if (!constraint.mTargetDir.isExactlyZero()) + { + constraint.mTargetDir.normVec(); + } + + } + + constraint.mConstraintType = CONSTRAINT_TYPE_POINT; + mConstraints.push_back(constraint); + continue; + } + + if (loadingGlobals && LLStringUtil::compareInsensitive(token, "planar_constraint")==0) + { + Constraint constraint; + + // try reading optional target direction + if(sscanf( /* Flawfinder: ignore */ + mLine, + " %*s = %d %f %f %f %f %15s %f %f %f %15s %f %f %f %f %f %f", + &constraint.mChainLength, + &constraint.mEaseInStart, + &constraint.mEaseInStop, + &constraint.mEaseOutStart, + &constraint.mEaseOutStop, + constraint.mSourceJointName, + &constraint.mSourceOffset.mV[VX], + &constraint.mSourceOffset.mV[VY], + &constraint.mSourceOffset.mV[VZ], + constraint.mTargetJointName, + &constraint.mTargetOffset.mV[VX], + &constraint.mTargetOffset.mV[VY], + &constraint.mTargetOffset.mV[VZ], + &constraint.mTargetDir.mV[VX], + &constraint.mTargetDir.mV[VY], + &constraint.mTargetDir.mV[VZ]) != 16) + { + if(sscanf( /* Flawfinder: ignore */ + mLine, + " %*s = %d %f %f %f %f %15s %f %f %f %15s %f %f %f", + &constraint.mChainLength, + &constraint.mEaseInStart, + &constraint.mEaseInStop, + &constraint.mEaseOutStart, + &constraint.mEaseOutStop, + constraint.mSourceJointName, + &constraint.mSourceOffset.mV[VX], + &constraint.mSourceOffset.mV[VY], + &constraint.mSourceOffset.mV[VZ], + constraint.mTargetJointName, + &constraint.mTargetOffset.mV[VX], + &constraint.mTargetOffset.mV[VY], + &constraint.mTargetOffset.mV[VZ]) != 13) + { + return E_ST_NO_CONSTRAINT; + } + } + else + { + // normalize direction + if (!constraint.mTargetDir.isExactlyZero()) + { + constraint.mTargetDir.normVec(); + } + + } + + constraint.mConstraintType = CONSTRAINT_TYPE_PLANE; + mConstraints.push_back(constraint); + continue; + } + } + + infile.close() ; + return E_ST_OK; } void LLBVHLoader::makeTranslation(std::string alias_name, std::string joint_name) { //Translation &newTrans = (foomap.insert(value_type(alias_name, Translation()))).first(); Translation &newTrans = mTranslations[ alias_name ]; //Uses []'s implicit call to ctor. - + newTrans.mOutName = joint_name; LLMatrix3 fm; LLVector3 vect1(0, 1, 0); LLVector3 vect2(0, 0, 1); LLVector3 vect3(1, 0, 0); fm.setRows(vect1, vect2, vect3); - + newTrans.mFrameMatrix = fm; - + if (joint_name == "mPelvis") { newTrans.mRelativePositionKey = TRUE; @@ -505,12 +505,12 @@ if (joint_name == "mPelvis") ELoadStatus LLBVHLoader::loadAliases(const char * filename) { LLSD aliases_sd; - + std::string fullpath = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS,filename); - + llifstream input_stream; input_stream.open(fullpath.c_str(), std::ios::in | std::ios::binary); - + if(input_stream.is_open()) { if ( LLSDSerialize::fromXML(aliases_sd, input_stream) ) @@ -522,7 +522,7 @@ ELoadStatus LLBVHLoader::loadAliases(const char * filename) LLSD::String alias_name = alias_iter->first; LLSD::String joint_name = alias_iter->second; makeTranslation(alias_name, joint_name); - + } } else @@ -542,12 +542,12 @@ ELoadStatus LLBVHLoader::loadAliases(const char * filename) void LLBVHLoader::dumpBVHInfo() { - for (U32 j=0; j<mJoints.size(); j++) - { - Joint *joint = mJoints[j]; - LL_DEBUGS("BVH") << joint->mName << LL_ENDL; - for (S32 i=0; i<mNumFrames; i++) - { + for (U32 j=0; j<mJoints.size(); j++) + { + Joint *joint = mJoints[j]; + LL_DEBUGS("BVH") << joint->mName << LL_ENDL; + for (S32 i=0; i<mNumFrames; i++) + { if (i<joint->mKeys.size()) // Check this in case file load failed. { Key &prevkey = joint->mKeys[llmax(i-1,0)]; @@ -561,13 +561,13 @@ void LLBVHLoader::dumpBVHInfo() (key.mRot[2] != prevkey.mRot[2]) ) { - LL_DEBUGS("BVH") << "FRAME " << i + LL_DEBUGS("BVH") << "FRAME " << i << " POS " << key.mPos[0] << "," << key.mPos[1] << "," << key.mPos[2] << " ROT " << key.mRot[0] << "," << key.mRot[1] << "," << key.mRot[2] << LL_ENDL; } } - } - } + } + } } @@ -576,331 +576,331 @@ void LLBVHLoader::dumpBVHInfo() //------------------------------------------------------------------------ ELoadStatus LLBVHLoader::loadBVHFile(const char *buffer, char* error_text, S32 &err_line) { - std::string line; - - err_line = 0; - error_text[127] = '\0'; - - std::string str(buffer); - typedef boost::tokenizer<boost::char_separator<char> > tokenizer; - boost::char_separator<char> sep("\r\n"); - tokenizer tokens(str, sep); - tokenizer::iterator iter = tokens.begin(); - - mLineNumber = 0; - mJoints.clear(); - - std::vector<S32> parent_joints; - - //-------------------------------------------------------------------- - // consume hierarchy - //-------------------------------------------------------------------- - if (iter == tokens.end()) - return E_ST_EOF; - line = (*(iter++)); - err_line++; - - if ( !strstr(line.c_str(), "HIERARCHY") ) - { -// LL_INFOS() << line << LL_ENDL; - return E_ST_NO_HIER; - } - - //-------------------------------------------------------------------- - // consume joints - //-------------------------------------------------------------------- - while (TRUE) - { - //---------------------------------------------------------------- - // get next line - //---------------------------------------------------------------- - if (iter == tokens.end()) - return E_ST_EOF; - line = (*(iter++)); - err_line++; - - //---------------------------------------------------------------- - // consume } - //---------------------------------------------------------------- - if ( strstr(line.c_str(), "}") ) - { - if (parent_joints.size() > 0) - { - parent_joints.pop_back(); - } - continue; - } - - //---------------------------------------------------------------- - // if MOTION, break out - //---------------------------------------------------------------- - if ( strstr(line.c_str(), "MOTION") ) - break; - - //---------------------------------------------------------------- - // it must be either ROOT or JOINT or EndSite - //---------------------------------------------------------------- - if ( strstr(line.c_str(), "ROOT") ) - { - } - else if ( strstr(line.c_str(), "JOINT") ) - { - } - else if ( strstr(line.c_str(), "End Site") ) - { - iter++; // { - iter++; // OFFSET - iter++; // } - S32 depth = 0; - for (S32 j = (S32)parent_joints.size() - 1; j >= 0; j--) - { - Joint *joint = mJoints[parent_joints[j]]; - if (depth > joint->mChildTreeMaxDepth) - { - joint->mChildTreeMaxDepth = depth; - } - depth++; - } - continue; - } - else - { - strncpy(error_text, line.c_str(), 127); /* Flawfinder: ignore */ - return E_ST_NO_JOINT; - } - - //---------------------------------------------------------------- - // get the joint name - //---------------------------------------------------------------- - char jointName[80]; /* Flawfinder: ignore */ - if ( sscanf(line.c_str(), "%*s %79s", jointName) != 1 ) /* Flawfinder: ignore */ - { - strncpy(error_text, line.c_str(), 127); /* Flawfinder: ignore */ - return E_ST_NO_NAME; - } - - //--------------------------------------------------------------- - // we require the root joint be "hip" - DEV-26188 - //--------------------------------------------------------------- + std::string line; + + err_line = 0; + error_text[127] = '\0'; + + std::string str(buffer); + typedef boost::tokenizer<boost::char_separator<char> > tokenizer; + boost::char_separator<char> sep("\r\n"); + tokenizer tokens(str, sep); + tokenizer::iterator iter = tokens.begin(); + + mLineNumber = 0; + mJoints.clear(); + + std::vector<S32> parent_joints; + + //-------------------------------------------------------------------- + // consume hierarchy + //-------------------------------------------------------------------- + if (iter == tokens.end()) + return E_ST_EOF; + line = (*(iter++)); + err_line++; + + if ( !strstr(line.c_str(), "HIERARCHY") ) + { +// LL_INFOS() << line << LL_ENDL; + return E_ST_NO_HIER; + } + + //-------------------------------------------------------------------- + // consume joints + //-------------------------------------------------------------------- + while (TRUE) + { + //---------------------------------------------------------------- + // get next line + //---------------------------------------------------------------- + if (iter == tokens.end()) + return E_ST_EOF; + line = (*(iter++)); + err_line++; + + //---------------------------------------------------------------- + // consume } + //---------------------------------------------------------------- + if ( strstr(line.c_str(), "}") ) + { + if (parent_joints.size() > 0) + { + parent_joints.pop_back(); + } + continue; + } + + //---------------------------------------------------------------- + // if MOTION, break out + //---------------------------------------------------------------- + if ( strstr(line.c_str(), "MOTION") ) + break; + + //---------------------------------------------------------------- + // it must be either ROOT or JOINT or EndSite + //---------------------------------------------------------------- + if ( strstr(line.c_str(), "ROOT") ) + { + } + else if ( strstr(line.c_str(), "JOINT") ) + { + } + else if ( strstr(line.c_str(), "End Site") ) + { + iter++; // { + iter++; // OFFSET + iter++; // } + S32 depth = 0; + for (S32 j = (S32)parent_joints.size() - 1; j >= 0; j--) + { + Joint *joint = mJoints[parent_joints[j]]; + if (depth > joint->mChildTreeMaxDepth) + { + joint->mChildTreeMaxDepth = depth; + } + depth++; + } + continue; + } + else + { + strncpy(error_text, line.c_str(), 127); /* Flawfinder: ignore */ + return E_ST_NO_JOINT; + } + + //---------------------------------------------------------------- + // get the joint name + //---------------------------------------------------------------- + char jointName[80]; /* Flawfinder: ignore */ + if ( sscanf(line.c_str(), "%*s %79s", jointName) != 1 ) /* Flawfinder: ignore */ + { + strncpy(error_text, line.c_str(), 127); /* Flawfinder: ignore */ + return E_ST_NO_NAME; + } + + //--------------------------------------------------------------- + // we require the root joint be "hip" - DEV-26188 + //--------------------------------------------------------------- if (mJoints.size() == 0 ) { //The root joint of the BVH file must be hip (mPelvis) or an alias of mPelvis. const char* FORCED_ROOT_NAME = "hip"; - + TranslationMap::iterator hip_joint = mTranslations.find( FORCED_ROOT_NAME ); TranslationMap::iterator root_joint = mTranslations.find( jointName ); if ( hip_joint == mTranslations.end() || root_joint == mTranslations.end() || root_joint->second.mOutName != hip_joint->second.mOutName ) { - strncpy(error_text, line.c_str(), 127); /* Flawfinder: ignore */ + strncpy(error_text, line.c_str(), 127); /* Flawfinder: ignore */ return E_ST_BAD_ROOT; } } - - //---------------------------------------------------------------- - // add a set of keyframes for this joint - //---------------------------------------------------------------- - mJoints.push_back( new Joint( jointName ) ); - Joint *joint = mJoints.back(); - LL_DEBUGS("BVH") << "Created joint " << jointName << LL_ENDL; - LL_DEBUGS("BVH") << "- index " << mJoints.size()-1 << LL_ENDL; - - S32 depth = 1; - for (S32 j = (S32)parent_joints.size() - 1; j >= 0; j--) - { - Joint *pjoint = mJoints[parent_joints[j]]; - LL_DEBUGS("BVH") << "- ancestor " << pjoint->mName << LL_ENDL; - if (depth > pjoint->mChildTreeMaxDepth) - { - pjoint->mChildTreeMaxDepth = depth; - } - depth++; - } - - //---------------------------------------------------------------- - // get next line - //---------------------------------------------------------------- - if (iter == tokens.end()) - { - return E_ST_EOF; - } - line = (*(iter++)); - err_line++; - - //---------------------------------------------------------------- - // it must be { - //---------------------------------------------------------------- - if ( !strstr(line.c_str(), "{") ) - { - strncpy(error_text, line.c_str(), 127); /*Flawfinder: ignore*/ - return E_ST_NO_OFFSET; - } - else - { - parent_joints.push_back((S32)mJoints.size() - 1); - } - - //---------------------------------------------------------------- - // get next line - //---------------------------------------------------------------- - if (iter == tokens.end()) - { - return E_ST_EOF; - } - line = (*(iter++)); - err_line++; - - //---------------------------------------------------------------- - // it must be OFFSET - //---------------------------------------------------------------- - if ( !strstr(line.c_str(), "OFFSET") ) - { - strncpy(error_text, line.c_str(), 127); /*Flawfinder: ignore*/ - return E_ST_NO_OFFSET; - } - - //---------------------------------------------------------------- - // get next line - //---------------------------------------------------------------- - if (iter == tokens.end()) - { - return E_ST_EOF; - } - line = (*(iter++)); - err_line++; - - //---------------------------------------------------------------- - // it must be CHANNELS - //---------------------------------------------------------------- - if ( !strstr(line.c_str(), "CHANNELS") ) - { - strncpy(error_text, line.c_str(), 127); /*Flawfinder: ignore*/ - return E_ST_NO_CHANNELS; - } + + //---------------------------------------------------------------- + // add a set of keyframes for this joint + //---------------------------------------------------------------- + mJoints.push_back( new Joint( jointName ) ); + Joint *joint = mJoints.back(); + LL_DEBUGS("BVH") << "Created joint " << jointName << LL_ENDL; + LL_DEBUGS("BVH") << "- index " << mJoints.size()-1 << LL_ENDL; + + S32 depth = 1; + for (S32 j = (S32)parent_joints.size() - 1; j >= 0; j--) + { + Joint *pjoint = mJoints[parent_joints[j]]; + LL_DEBUGS("BVH") << "- ancestor " << pjoint->mName << LL_ENDL; + if (depth > pjoint->mChildTreeMaxDepth) + { + pjoint->mChildTreeMaxDepth = depth; + } + depth++; + } + + //---------------------------------------------------------------- + // get next line + //---------------------------------------------------------------- + if (iter == tokens.end()) + { + return E_ST_EOF; + } + line = (*(iter++)); + err_line++; + + //---------------------------------------------------------------- + // it must be { + //---------------------------------------------------------------- + if ( !strstr(line.c_str(), "{") ) + { + strncpy(error_text, line.c_str(), 127); /*Flawfinder: ignore*/ + return E_ST_NO_OFFSET; + } + else + { + parent_joints.push_back((S32)mJoints.size() - 1); + } + + //---------------------------------------------------------------- + // get next line + //---------------------------------------------------------------- + if (iter == tokens.end()) + { + return E_ST_EOF; + } + line = (*(iter++)); + err_line++; + + //---------------------------------------------------------------- + // it must be OFFSET + //---------------------------------------------------------------- + if ( !strstr(line.c_str(), "OFFSET") ) + { + strncpy(error_text, line.c_str(), 127); /*Flawfinder: ignore*/ + return E_ST_NO_OFFSET; + } + + //---------------------------------------------------------------- + // get next line + //---------------------------------------------------------------- + if (iter == tokens.end()) + { + return E_ST_EOF; + } + line = (*(iter++)); + err_line++; + + //---------------------------------------------------------------- + // it must be CHANNELS + //---------------------------------------------------------------- + if ( !strstr(line.c_str(), "CHANNELS") ) + { + strncpy(error_text, line.c_str(), 127); /*Flawfinder: ignore*/ + return E_ST_NO_CHANNELS; + } // Animating position (via mNumChannels = 6) is only supported for mPelvis. - int res = sscanf(line.c_str(), " CHANNELS %d", &joint->mNumChannels); - if ( res != 1 ) - { - // Assume default if not otherwise specified. - if (mJoints.size()==1) - { - joint->mNumChannels = 6; - } - else - { - joint->mNumChannels = 3; - } - } - - //---------------------------------------------------------------- - // get rotation order - //---------------------------------------------------------------- - const char *p = line.c_str(); - for (S32 i=0; i<3; i++) - { - p = strstr(p, "rotation"); - if (!p) - { - strncpy(error_text, line.c_str(), 127); /*Flawfinder: ignore*/ - return E_ST_NO_ROTATION; - } - - const char axis = *(p - 1); - if ((axis != 'X') && (axis != 'Y') && (axis != 'Z')) - { - strncpy(error_text, line.c_str(), 127); /*Flawfinder: ignore*/ - return E_ST_NO_AXIS; - } - - joint->mOrder[i] = axis; - - p++; - } - } - - //-------------------------------------------------------------------- - // consume motion - //-------------------------------------------------------------------- - if ( !strstr(line.c_str(), "MOTION") ) - { - strncpy(error_text, line.c_str(), 127); /*Flawfinder: ignore*/ - return E_ST_NO_MOTION; - } - - //-------------------------------------------------------------------- - // get number of frames - //-------------------------------------------------------------------- - if (iter == tokens.end()) - { - return E_ST_EOF; - } - line = (*(iter++)); - err_line++; - - if ( !strstr(line.c_str(), "Frames:") ) - { - strncpy(error_text, line.c_str(), 127); /*Flawfinder: ignore*/ - return E_ST_NO_FRAMES; - } - - if ( sscanf(line.c_str(), "Frames: %d", &mNumFrames) != 1 ) - { - strncpy(error_text, line.c_str(), 127); /*Flawfinder: ignore*/ - return E_ST_NO_FRAMES; - } - - //-------------------------------------------------------------------- - // get frame time - //-------------------------------------------------------------------- - if (iter == tokens.end()) - { - return E_ST_EOF; - } - line = (*(iter++)); - err_line++; - - if ( !strstr(line.c_str(), "Frame Time:") ) - { - strncpy(error_text, line.c_str(), 127); /*Flawfinder: ignore*/ - return E_ST_NO_FRAME_TIME; - } - - if ( sscanf(line.c_str(), "Frame Time: %f", &mFrameTime) != 1 ) - { - strncpy(error_text, line.c_str(), 127); /*Flawfinder: ignore*/ - return E_ST_NO_FRAME_TIME; - } - - // If the user only supplies one animation frame (after the ignored reference frame 0), hold for mFrameTime. - // If the user supples exactly one total frame, it isn't clear if that is a pose or reference frame, and the - // behavior is not defined. In this case, retain historical undefined behavior. - mDuration = llmax((F32)(mNumFrames - NUMBER_OF_UNPLAYED_FRAMES), 1.0f) * mFrameTime; - if (!mLoop) - { - mLoopOutPoint = mDuration; - } - - //-------------------------------------------------------------------- - // load frames - //-------------------------------------------------------------------- - for (S32 i=0; i<mNumFrames; i++) - { - // get next line - if (iter == tokens.end()) - { - return E_ST_EOF; - } - line = (*(iter++)); - err_line++; - - // Split line into a collection of floats. - std::deque<F32> floats; - boost::char_separator<char> whitespace_sep("\t "); - tokenizer float_tokens(line, whitespace_sep); - tokenizer::iterator float_token_iter = float_tokens.begin(); - while (float_token_iter != float_tokens.end()) - { + int res = sscanf(line.c_str(), " CHANNELS %d", &joint->mNumChannels); + if ( res != 1 ) + { + // Assume default if not otherwise specified. + if (mJoints.size()==1) + { + joint->mNumChannels = 6; + } + else + { + joint->mNumChannels = 3; + } + } + + //---------------------------------------------------------------- + // get rotation order + //---------------------------------------------------------------- + const char *p = line.c_str(); + for (S32 i=0; i<3; i++) + { + p = strstr(p, "rotation"); + if (!p) + { + strncpy(error_text, line.c_str(), 127); /*Flawfinder: ignore*/ + return E_ST_NO_ROTATION; + } + + const char axis = *(p - 1); + if ((axis != 'X') && (axis != 'Y') && (axis != 'Z')) + { + strncpy(error_text, line.c_str(), 127); /*Flawfinder: ignore*/ + return E_ST_NO_AXIS; + } + + joint->mOrder[i] = axis; + + p++; + } + } + + //-------------------------------------------------------------------- + // consume motion + //-------------------------------------------------------------------- + if ( !strstr(line.c_str(), "MOTION") ) + { + strncpy(error_text, line.c_str(), 127); /*Flawfinder: ignore*/ + return E_ST_NO_MOTION; + } + + //-------------------------------------------------------------------- + // get number of frames + //-------------------------------------------------------------------- + if (iter == tokens.end()) + { + return E_ST_EOF; + } + line = (*(iter++)); + err_line++; + + if ( !strstr(line.c_str(), "Frames:") ) + { + strncpy(error_text, line.c_str(), 127); /*Flawfinder: ignore*/ + return E_ST_NO_FRAMES; + } + + if ( sscanf(line.c_str(), "Frames: %d", &mNumFrames) != 1 ) + { + strncpy(error_text, line.c_str(), 127); /*Flawfinder: ignore*/ + return E_ST_NO_FRAMES; + } + + //-------------------------------------------------------------------- + // get frame time + //-------------------------------------------------------------------- + if (iter == tokens.end()) + { + return E_ST_EOF; + } + line = (*(iter++)); + err_line++; + + if ( !strstr(line.c_str(), "Frame Time:") ) + { + strncpy(error_text, line.c_str(), 127); /*Flawfinder: ignore*/ + return E_ST_NO_FRAME_TIME; + } + + if ( sscanf(line.c_str(), "Frame Time: %f", &mFrameTime) != 1 ) + { + strncpy(error_text, line.c_str(), 127); /*Flawfinder: ignore*/ + return E_ST_NO_FRAME_TIME; + } + + // If the user only supplies one animation frame (after the ignored reference frame 0), hold for mFrameTime. + // If the user supples exactly one total frame, it isn't clear if that is a pose or reference frame, and the + // behavior is not defined. In this case, retain historical undefined behavior. + mDuration = llmax((F32)(mNumFrames - NUMBER_OF_UNPLAYED_FRAMES), 1.0f) * mFrameTime; + if (!mLoop) + { + mLoopOutPoint = mDuration; + } + + //-------------------------------------------------------------------- + // load frames + //-------------------------------------------------------------------- + for (S32 i=0; i<mNumFrames; i++) + { + // get next line + if (iter == tokens.end()) + { + return E_ST_EOF; + } + line = (*(iter++)); + err_line++; + + // Split line into a collection of floats. + std::deque<F32> floats; + boost::char_separator<char> whitespace_sep("\t "); + tokenizer float_tokens(line, whitespace_sep); + tokenizer::iterator float_token_iter = float_tokens.begin(); + while (float_token_iter != float_tokens.end()) + { try { F32 val = boost::lexical_cast<float>(*float_token_iter); @@ -908,39 +908,39 @@ ELoadStatus LLBVHLoader::loadBVHFile(const char *buffer, char* error_text, S32 & } catch (const boost::bad_lexical_cast&) { - strncpy(error_text, line.c_str(), 127); /*Flawfinder: ignore*/ - return E_ST_NO_POS; + strncpy(error_text, line.c_str(), 127); /*Flawfinder: ignore*/ + return E_ST_NO_POS; } float_token_iter++; - } - LL_DEBUGS("BVH") << "Got " << floats.size() << " floats " << LL_ENDL; - for (U32 j=0; j<mJoints.size(); j++) - { - Joint *joint = mJoints[j]; - joint->mKeys.push_back( Key() ); - Key &key = joint->mKeys.back(); - - if (floats.size() < joint->mNumChannels) - { - strncpy(error_text, line.c_str(), 127); /*Flawfinder: ignore*/ - return E_ST_NO_POS; - } - - // assume either numChannels == 6, in which case we have pos + rot, - // or numChannels == 3, in which case we have only rot. - if (joint->mNumChannels == 6) - { - key.mPos[0] = floats.front(); floats.pop_front(); - key.mPos[1] = floats.front(); floats.pop_front(); - key.mPos[2] = floats.front(); floats.pop_front(); - } - key.mRot[ joint->mOrder[0]-'X' ] = floats.front(); floats.pop_front(); - key.mRot[ joint->mOrder[1]-'X' ] = floats.front(); floats.pop_front(); - key.mRot[ joint->mOrder[2]-'X' ] = floats.front(); floats.pop_front(); - } - } - - return E_ST_OK; + } + LL_DEBUGS("BVH") << "Got " << floats.size() << " floats " << LL_ENDL; + for (U32 j=0; j<mJoints.size(); j++) + { + Joint *joint = mJoints[j]; + joint->mKeys.push_back( Key() ); + Key &key = joint->mKeys.back(); + + if (floats.size() < joint->mNumChannels) + { + strncpy(error_text, line.c_str(), 127); /*Flawfinder: ignore*/ + return E_ST_NO_POS; + } + + // assume either numChannels == 6, in which case we have pos + rot, + // or numChannels == 3, in which case we have only rot. + if (joint->mNumChannels == 6) + { + key.mPos[0] = floats.front(); floats.pop_front(); + key.mPos[1] = floats.front(); floats.pop_front(); + key.mPos[2] = floats.front(); floats.pop_front(); + } + key.mRot[ joint->mOrder[0]-'X' ] = floats.front(); floats.pop_front(); + key.mRot[ joint->mOrder[1]-'X' ] = floats.front(); floats.pop_front(); + key.mRot[ joint->mOrder[2]-'X' ] = floats.front(); floats.pop_front(); + } + } + + return E_ST_OK; } @@ -949,38 +949,38 @@ ELoadStatus LLBVHLoader::loadBVHFile(const char *buffer, char* error_text, S32 & //------------------------------------------------------------------------ void LLBVHLoader::applyTranslations() { - for (Joint* joint : mJoints) - { - //---------------------------------------------------------------- - // Look for a translation for this joint. - // If none, skip to next joint - //---------------------------------------------------------------- - TranslationMap::iterator ti = mTranslations.find( joint->mName ); - if ( ti == mTranslations.end() ) - { - continue; - } - - Translation &trans = ti->second; - - //---------------------------------------------------------------- - // Set the ignore flag if necessary - //---------------------------------------------------------------- - if ( trans.mIgnore ) - { + for (Joint* joint : mJoints) + { + //---------------------------------------------------------------- + // Look for a translation for this joint. + // If none, skip to next joint + //---------------------------------------------------------------- + TranslationMap::iterator ti = mTranslations.find( joint->mName ); + if ( ti == mTranslations.end() ) + { + continue; + } + + Translation &trans = ti->second; + + //---------------------------------------------------------------- + // Set the ignore flag if necessary + //---------------------------------------------------------------- + if ( trans.mIgnore ) + { //LL_INFOS() << "NOTE: Ignoring " << joint->mName.c_str() << LL_ENDL; - joint->mIgnore = TRUE; - continue; - } - - //---------------------------------------------------------------- - // Set the output name - //---------------------------------------------------------------- - if ( ! trans.mOutName.empty() ) - { - //LL_INFOS() << "NOTE: Changing " << joint->mName.c_str() << " to " << trans.mOutName.c_str() << LL_ENDL; - joint->mOutName = trans.mOutName; - } + joint->mIgnore = TRUE; + continue; + } + + //---------------------------------------------------------------- + // Set the output name + //---------------------------------------------------------------- + if ( ! trans.mOutName.empty() ) + { + //LL_INFOS() << "NOTE: Changing " << joint->mName.c_str() << " to " << trans.mOutName.c_str() << LL_ENDL; + joint->mOutName = trans.mOutName; + } //Allow joint position changes as of SL-318 joint->mIgnorePositions = FALSE; @@ -989,65 +989,65 @@ void LLBVHLoader::applyTranslations() joint->mIgnorePositions = TRUE; } - //---------------------------------------------------------------- - // Set the relativepos flags if necessary - //---------------------------------------------------------------- - if ( trans.mRelativePositionKey ) - { -// LL_INFOS() << "NOTE: Removing 1st position offset from all keys for " << joint->mOutName.c_str() << LL_ENDL; - joint->mRelativePositionKey = TRUE; - } - - if ( trans.mRelativeRotationKey ) - { -// LL_INFOS() << "NOTE: Removing 1st rotation from all keys for " << joint->mOutName.c_str() << LL_ENDL; - joint->mRelativeRotationKey = TRUE; - } - - if ( trans.mRelativePosition.magVec() > 0.0f ) - { - joint->mRelativePosition = trans.mRelativePosition; -// LL_INFOS() << "NOTE: Removing " << -// joint->mRelativePosition.mV[0] << " " << -// joint->mRelativePosition.mV[1] << " " << -// joint->mRelativePosition.mV[2] << -// " from all position keys in " << -// joint->mOutName.c_str() << LL_ENDL; - } - - //---------------------------------------------------------------- - // Set change of coordinate frame - //---------------------------------------------------------------- - joint->mFrameMatrix = trans.mFrameMatrix; - joint->mOffsetMatrix = trans.mOffsetMatrix; - - //---------------------------------------------------------------- - // Set mergeparent name - //---------------------------------------------------------------- - if ( ! trans.mMergeParentName.empty() ) - { -// LL_INFOS() << "NOTE: Merging " << joint->mOutName.c_str() << -// " with parent " << -// trans.mMergeParentName.c_str() << LL_ENDL; - joint->mMergeParentName = trans.mMergeParentName; - } - - //---------------------------------------------------------------- - // Set mergechild name - //---------------------------------------------------------------- - if ( ! trans.mMergeChildName.empty() ) - { -// LL_INFOS() << "NOTE: Merging " << joint->mName.c_str() << -// " with child " << trans.mMergeChildName.c_str() << LL_ENDL; - joint->mMergeChildName = trans.mMergeChildName; - } - - //---------------------------------------------------------------- - // Set joint priority - //---------------------------------------------------------------- - joint->mPriority = mPriority + trans.mPriorityModifier; - - } + //---------------------------------------------------------------- + // Set the relativepos flags if necessary + //---------------------------------------------------------------- + if ( trans.mRelativePositionKey ) + { +// LL_INFOS() << "NOTE: Removing 1st position offset from all keys for " << joint->mOutName.c_str() << LL_ENDL; + joint->mRelativePositionKey = TRUE; + } + + if ( trans.mRelativeRotationKey ) + { +// LL_INFOS() << "NOTE: Removing 1st rotation from all keys for " << joint->mOutName.c_str() << LL_ENDL; + joint->mRelativeRotationKey = TRUE; + } + + if ( trans.mRelativePosition.magVec() > 0.0f ) + { + joint->mRelativePosition = trans.mRelativePosition; +// LL_INFOS() << "NOTE: Removing " << +// joint->mRelativePosition.mV[0] << " " << +// joint->mRelativePosition.mV[1] << " " << +// joint->mRelativePosition.mV[2] << +// " from all position keys in " << +// joint->mOutName.c_str() << LL_ENDL; + } + + //---------------------------------------------------------------- + // Set change of coordinate frame + //---------------------------------------------------------------- + joint->mFrameMatrix = trans.mFrameMatrix; + joint->mOffsetMatrix = trans.mOffsetMatrix; + + //---------------------------------------------------------------- + // Set mergeparent name + //---------------------------------------------------------------- + if ( ! trans.mMergeParentName.empty() ) + { +// LL_INFOS() << "NOTE: Merging " << joint->mOutName.c_str() << +// " with parent " << +// trans.mMergeParentName.c_str() << LL_ENDL; + joint->mMergeParentName = trans.mMergeParentName; + } + + //---------------------------------------------------------------- + // Set mergechild name + //---------------------------------------------------------------- + if ( ! trans.mMergeChildName.empty() ) + { +// LL_INFOS() << "NOTE: Merging " << joint->mName.c_str() << +// " with child " << trans.mMergeChildName.c_str() << LL_ENDL; + joint->mMergeChildName = trans.mMergeChildName; + } + + //---------------------------------------------------------------- + // Set joint priority + //---------------------------------------------------------------- + joint->mPriority = mPriority + trans.mPriorityModifier; + + } } //----------------------------------------------------------------------------- @@ -1055,208 +1055,208 @@ void LLBVHLoader::applyTranslations() //----------------------------------------------------------------------------- void LLBVHLoader::optimize() { - //RN: assumes motion blend, which is the default now - if (!mLoop && mEaseIn + mEaseOut > mDuration && mDuration != 0.f) - { - F32 factor = mDuration / (mEaseIn + mEaseOut); - mEaseIn *= factor; - mEaseOut *= factor; - } - - for (Joint* joint : mJoints) - { - BOOL pos_changed = FALSE; - BOOL rot_changed = FALSE; - - if ( ! joint->mIgnore ) - { - joint->mNumPosKeys = 0; - joint->mNumRotKeys = 0; - LLQuaternion::Order order = bvhStringToOrder( joint->mOrder ); - - KeyVector::iterator first_key = joint->mKeys.begin(); - - // no keys? - if (first_key == joint->mKeys.end()) - { - joint->mIgnore = TRUE; - continue; - } - - LLVector3 first_frame_pos(first_key->mPos); - LLQuaternion first_frame_rot = mayaQ( first_key->mRot[0], first_key->mRot[1], first_key->mRot[2], order); - - // skip first key - KeyVector::iterator ki = joint->mKeys.begin(); - if (joint->mKeys.size() == 1) - { - // *FIX: use single frame to move pelvis - // if only one keyframe force output for this joint - rot_changed = TRUE; - } - else - { - // if more than one keyframe, use first frame as reference and skip to second - first_key->mIgnorePos = TRUE; - first_key->mIgnoreRot = TRUE; - ++ki; - } - - KeyVector::iterator ki_prev = ki; - KeyVector::iterator ki_last_good_pos = ki; - KeyVector::iterator ki_last_good_rot = ki; - S32 numPosFramesConsidered = 2; - S32 numRotFramesConsidered = 2; - - F32 rot_threshold = ROTATION_KEYFRAME_THRESHOLD / llmax((F32)joint->mChildTreeMaxDepth * 0.33f, 1.f); - - double diff_max = 0; - KeyVector::iterator ki_max = ki; - for (; ki != joint->mKeys.end(); ++ki) - { - if (ki_prev == ki_last_good_pos) - { - joint->mNumPosKeys++; - if (dist_vec_squared(LLVector3(ki_prev->mPos), first_frame_pos) > POSITION_MOTION_THRESHOLD_SQUARED) - { - pos_changed = TRUE; - } - } - else - { - //check position for noticeable effect - LLVector3 test_pos(ki_prev->mPos); - LLVector3 last_good_pos(ki_last_good_pos->mPos); - LLVector3 current_pos(ki->mPos); - LLVector3 interp_pos = lerp(current_pos, last_good_pos, 1.f / (F32)numPosFramesConsidered); - - if (dist_vec_squared(current_pos, first_frame_pos) > POSITION_MOTION_THRESHOLD_SQUARED) - { - pos_changed = TRUE; - } - - if (dist_vec_squared(interp_pos, test_pos) < POSITION_KEYFRAME_THRESHOLD_SQUARED) - { - ki_prev->mIgnorePos = TRUE; - numPosFramesConsidered++; - } - else - { - numPosFramesConsidered = 2; - ki_last_good_pos = ki_prev; - joint->mNumPosKeys++; - } - } - - if (ki_prev == ki_last_good_rot) - { - joint->mNumRotKeys++; - LLQuaternion test_rot = mayaQ( ki_prev->mRot[0], ki_prev->mRot[1], ki_prev->mRot[2], order); - F32 x_delta = dist_vec(LLVector3::x_axis * first_frame_rot, LLVector3::x_axis * test_rot); - F32 y_delta = dist_vec(LLVector3::y_axis * first_frame_rot, LLVector3::y_axis * test_rot); - F32 rot_test = x_delta + y_delta; - - if (rot_test > ROTATION_MOTION_THRESHOLD) - { - rot_changed = TRUE; - } - } - else - { - //check rotation for noticeable effect - LLQuaternion test_rot = mayaQ( ki_prev->mRot[0], ki_prev->mRot[1], ki_prev->mRot[2], order); - LLQuaternion last_good_rot = mayaQ( ki_last_good_rot->mRot[0], ki_last_good_rot->mRot[1], ki_last_good_rot->mRot[2], order); - LLQuaternion current_rot = mayaQ( ki->mRot[0], ki->mRot[1], ki->mRot[2], order); - LLQuaternion interp_rot = lerp(1.f / (F32)numRotFramesConsidered, current_rot, last_good_rot); - - F32 x_delta; - F32 y_delta; - F32 rot_test; - - // Test if the rotation has changed significantly since the very first frame. If false - // for all frames, then we'll just throw out this joint's rotation entirely. - x_delta = dist_vec(LLVector3::x_axis * first_frame_rot, LLVector3::x_axis * test_rot); - y_delta = dist_vec(LLVector3::y_axis * first_frame_rot, LLVector3::y_axis * test_rot); - rot_test = x_delta + y_delta; - if (rot_test > ROTATION_MOTION_THRESHOLD) - { - rot_changed = TRUE; - } - x_delta = dist_vec(LLVector3::x_axis * interp_rot, LLVector3::x_axis * test_rot); - y_delta = dist_vec(LLVector3::y_axis * interp_rot, LLVector3::y_axis * test_rot); - rot_test = x_delta + y_delta; - - // Draw a line between the last good keyframe and current. Test the distance between the last frame (current-1, i.e. ki_prev) - // and the line. If it's greater than some threshold, then it represents a significant frame and we want to include it. - if (rot_test >= rot_threshold || - (ki+1 == joint->mKeys.end() && numRotFramesConsidered > 2)) - { - // Add the current test keyframe (which is technically the previous key, i.e. ki_prev). - numRotFramesConsidered = 2; - ki_last_good_rot = ki_prev; - joint->mNumRotKeys++; - - // Add another keyframe between the last good keyframe and current, at whatever point was the most "significant" (i.e. - // had the largest deviation from the earlier tests). Note that a more robust approach would be test all intermediate - // keyframes against the line between the last good keyframe and current, but we're settling for this other method - // because it's significantly faster. - if (diff_max > 0) - { - if (ki_max->mIgnoreRot == TRUE) - { - ki_max->mIgnoreRot = FALSE; - joint->mNumRotKeys++; - } - diff_max = 0; - } - } - else - { - // This keyframe isn't significant enough, throw it away. - ki_prev->mIgnoreRot = TRUE; - numRotFramesConsidered++; - // Store away the keyframe that has the largest deviation from the interpolated line, for insertion later. - if (rot_test > diff_max) - { - diff_max = rot_test; - ki_max = ki; - } - } - } - - ki_prev = ki; - } - } - - // don't output joints with no motion - if (!(pos_changed || rot_changed)) - { - //LL_INFOS() << "Ignoring joint " << joint->mName << LL_ENDL; - joint->mIgnore = TRUE; - } - } + //RN: assumes motion blend, which is the default now + if (!mLoop && mEaseIn + mEaseOut > mDuration && mDuration != 0.f) + { + F32 factor = mDuration / (mEaseIn + mEaseOut); + mEaseIn *= factor; + mEaseOut *= factor; + } + + for (Joint* joint : mJoints) + { + BOOL pos_changed = FALSE; + BOOL rot_changed = FALSE; + + if ( ! joint->mIgnore ) + { + joint->mNumPosKeys = 0; + joint->mNumRotKeys = 0; + LLQuaternion::Order order = bvhStringToOrder( joint->mOrder ); + + KeyVector::iterator first_key = joint->mKeys.begin(); + + // no keys? + if (first_key == joint->mKeys.end()) + { + joint->mIgnore = TRUE; + continue; + } + + LLVector3 first_frame_pos(first_key->mPos); + LLQuaternion first_frame_rot = mayaQ( first_key->mRot[0], first_key->mRot[1], first_key->mRot[2], order); + + // skip first key + KeyVector::iterator ki = joint->mKeys.begin(); + if (joint->mKeys.size() == 1) + { + // *FIX: use single frame to move pelvis + // if only one keyframe force output for this joint + rot_changed = TRUE; + } + else + { + // if more than one keyframe, use first frame as reference and skip to second + first_key->mIgnorePos = TRUE; + first_key->mIgnoreRot = TRUE; + ++ki; + } + + KeyVector::iterator ki_prev = ki; + KeyVector::iterator ki_last_good_pos = ki; + KeyVector::iterator ki_last_good_rot = ki; + S32 numPosFramesConsidered = 2; + S32 numRotFramesConsidered = 2; + + F32 rot_threshold = ROTATION_KEYFRAME_THRESHOLD / llmax((F32)joint->mChildTreeMaxDepth * 0.33f, 1.f); + + double diff_max = 0; + KeyVector::iterator ki_max = ki; + for (; ki != joint->mKeys.end(); ++ki) + { + if (ki_prev == ki_last_good_pos) + { + joint->mNumPosKeys++; + if (dist_vec_squared(LLVector3(ki_prev->mPos), first_frame_pos) > POSITION_MOTION_THRESHOLD_SQUARED) + { + pos_changed = TRUE; + } + } + else + { + //check position for noticeable effect + LLVector3 test_pos(ki_prev->mPos); + LLVector3 last_good_pos(ki_last_good_pos->mPos); + LLVector3 current_pos(ki->mPos); + LLVector3 interp_pos = lerp(current_pos, last_good_pos, 1.f / (F32)numPosFramesConsidered); + + if (dist_vec_squared(current_pos, first_frame_pos) > POSITION_MOTION_THRESHOLD_SQUARED) + { + pos_changed = TRUE; + } + + if (dist_vec_squared(interp_pos, test_pos) < POSITION_KEYFRAME_THRESHOLD_SQUARED) + { + ki_prev->mIgnorePos = TRUE; + numPosFramesConsidered++; + } + else + { + numPosFramesConsidered = 2; + ki_last_good_pos = ki_prev; + joint->mNumPosKeys++; + } + } + + if (ki_prev == ki_last_good_rot) + { + joint->mNumRotKeys++; + LLQuaternion test_rot = mayaQ( ki_prev->mRot[0], ki_prev->mRot[1], ki_prev->mRot[2], order); + F32 x_delta = dist_vec(LLVector3::x_axis * first_frame_rot, LLVector3::x_axis * test_rot); + F32 y_delta = dist_vec(LLVector3::y_axis * first_frame_rot, LLVector3::y_axis * test_rot); + F32 rot_test = x_delta + y_delta; + + if (rot_test > ROTATION_MOTION_THRESHOLD) + { + rot_changed = TRUE; + } + } + else + { + //check rotation for noticeable effect + LLQuaternion test_rot = mayaQ( ki_prev->mRot[0], ki_prev->mRot[1], ki_prev->mRot[2], order); + LLQuaternion last_good_rot = mayaQ( ki_last_good_rot->mRot[0], ki_last_good_rot->mRot[1], ki_last_good_rot->mRot[2], order); + LLQuaternion current_rot = mayaQ( ki->mRot[0], ki->mRot[1], ki->mRot[2], order); + LLQuaternion interp_rot = lerp(1.f / (F32)numRotFramesConsidered, current_rot, last_good_rot); + + F32 x_delta; + F32 y_delta; + F32 rot_test; + + // Test if the rotation has changed significantly since the very first frame. If false + // for all frames, then we'll just throw out this joint's rotation entirely. + x_delta = dist_vec(LLVector3::x_axis * first_frame_rot, LLVector3::x_axis * test_rot); + y_delta = dist_vec(LLVector3::y_axis * first_frame_rot, LLVector3::y_axis * test_rot); + rot_test = x_delta + y_delta; + if (rot_test > ROTATION_MOTION_THRESHOLD) + { + rot_changed = TRUE; + } + x_delta = dist_vec(LLVector3::x_axis * interp_rot, LLVector3::x_axis * test_rot); + y_delta = dist_vec(LLVector3::y_axis * interp_rot, LLVector3::y_axis * test_rot); + rot_test = x_delta + y_delta; + + // Draw a line between the last good keyframe and current. Test the distance between the last frame (current-1, i.e. ki_prev) + // and the line. If it's greater than some threshold, then it represents a significant frame and we want to include it. + if (rot_test >= rot_threshold || + (ki+1 == joint->mKeys.end() && numRotFramesConsidered > 2)) + { + // Add the current test keyframe (which is technically the previous key, i.e. ki_prev). + numRotFramesConsidered = 2; + ki_last_good_rot = ki_prev; + joint->mNumRotKeys++; + + // Add another keyframe between the last good keyframe and current, at whatever point was the most "significant" (i.e. + // had the largest deviation from the earlier tests). Note that a more robust approach would be test all intermediate + // keyframes against the line between the last good keyframe and current, but we're settling for this other method + // because it's significantly faster. + if (diff_max > 0) + { + if (ki_max->mIgnoreRot == TRUE) + { + ki_max->mIgnoreRot = FALSE; + joint->mNumRotKeys++; + } + diff_max = 0; + } + } + else + { + // This keyframe isn't significant enough, throw it away. + ki_prev->mIgnoreRot = TRUE; + numRotFramesConsidered++; + // Store away the keyframe that has the largest deviation from the interpolated line, for insertion later. + if (rot_test > diff_max) + { + diff_max = rot_test; + ki_max = ki; + } + } + } + + ki_prev = ki; + } + } + + // don't output joints with no motion + if (!(pos_changed || rot_changed)) + { + //LL_INFOS() << "Ignoring joint " << joint->mName << LL_ENDL; + joint->mIgnore = TRUE; + } + } } void LLBVHLoader::reset() { - mLineNumber = 0; - mNumFrames = 0; - mFrameTime = 0.0f; - mDuration = 0.0f; - - mPriority = 2; - mLoop = FALSE; - mLoopInPoint = 0.f; - mLoopOutPoint = 0.f; - mEaseIn = 0.3f; - mEaseOut = 0.3f; - mHand = 1; - mInitialized = FALSE; - - mEmoteName = ""; - mLineNumber = 0; - mTranslations.clear(); - mConstraints.clear(); + mLineNumber = 0; + mNumFrames = 0; + mFrameTime = 0.0f; + mDuration = 0.0f; + + mPriority = 2; + mLoop = FALSE; + mLoopInPoint = 0.f; + mLoopOutPoint = 0.f; + mEaseIn = 0.3f; + mEaseOut = 0.3f; + mHand = 1; + mInitialized = FALSE; + + mEmoteName = ""; + mLineNumber = 0; + mTranslations.clear(); + mConstraints.clear(); } //------------------------------------------------------------------------ @@ -1264,237 +1264,237 @@ void LLBVHLoader::reset() //------------------------------------------------------------------------ BOOL LLBVHLoader::getLine(apr_file_t* fp) { - if (apr_file_eof(fp) == APR_EOF) - { - return FALSE; - } - if ( apr_file_gets(mLine, BVH_PARSER_LINE_SIZE, fp) == APR_SUCCESS) - { - mLineNumber++; - return TRUE; - } - - return FALSE; + if (apr_file_eof(fp) == APR_EOF) + { + return FALSE; + } + if ( apr_file_gets(mLine, BVH_PARSER_LINE_SIZE, fp) == APR_SUCCESS) + { + mLineNumber++; + return TRUE; + } + + return FALSE; } // returns required size of output buffer U32 LLBVHLoader::getOutputSize() { - LLDataPackerBinaryBuffer dp; - serialize(dp); + LLDataPackerBinaryBuffer dp; + serialize(dp); - return dp.getCurrentSize(); + return dp.getCurrentSize(); } // writes contents to datapacker BOOL LLBVHLoader::serialize(LLDataPacker& dp) { - F32 time; - - // count number of non-ignored joints - S32 numJoints = 0; - for (Joint* joint : mJoints) - { - if ( ! joint->mIgnore ) - numJoints++; - } - - // print header - dp.packU16(KEYFRAME_MOTION_VERSION, "version"); - dp.packU16(KEYFRAME_MOTION_SUBVERSION, "sub_version"); - dp.packS32(mPriority, "base_priority"); - dp.packF32(mDuration, "duration"); - dp.packString(mEmoteName, "emote_name"); - dp.packF32(mLoopInPoint, "loop_in_point"); - dp.packF32(mLoopOutPoint, "loop_out_point"); - dp.packS32(mLoop, "loop"); - dp.packF32(mEaseIn, "ease_in_duration"); - dp.packF32(mEaseOut, "ease_out_duration"); - dp.packU32(mHand, "hand_pose"); - dp.packU32(numJoints, "num_joints"); - - for (Joint* joint : mJoints) - { - // if ignored, skip it - if ( joint->mIgnore ) - continue; - - LLQuaternion first_frame_rot; - LLQuaternion fixup_rot; - - dp.packString(joint->mOutName, "joint_name"); - dp.packS32(joint->mPriority, "joint_priority"); - - // compute coordinate frame rotation - LLQuaternion frameRot( joint->mFrameMatrix ); - LLQuaternion frameRotInv = ~frameRot; - - LLQuaternion offsetRot( joint->mOffsetMatrix ); - - // find mergechild and mergeparent joints, if specified - LLQuaternion mergeParentRot; - LLQuaternion mergeChildRot; - Joint *mergeParent = NULL; - Joint *mergeChild = NULL; - - for (Joint* mjoint : mJoints) - { - if ( !joint->mMergeParentName.empty() && (mjoint->mName == joint->mMergeParentName) ) - { - mergeParent = mjoint; - } - if ( !joint->mMergeChildName.empty() && (mjoint->mName == joint->mMergeChildName) ) - { - mergeChild = mjoint; - } - } - - dp.packS32(joint->mNumRotKeys, "num_rot_keys"); - - LLQuaternion::Order order = bvhStringToOrder( joint->mOrder ); - S32 frame = 0; - for (Key& key : joint->mKeys) - { - - if ((frame == 0) && joint->mRelativeRotationKey) - { - first_frame_rot = mayaQ( key.mRot[0], key.mRot[1], key.mRot[2], order); - - fixup_rot.shortestArc(LLVector3::z_axis * first_frame_rot * frameRot, LLVector3::z_axis); - } - - if (key.mIgnoreRot) - { - frame++; - continue; - } - - time = llmax((F32)(frame - NUMBER_OF_IGNORED_FRAMES_AT_START), 0.0f) * mFrameTime; // Time elapsed before this frame starts. - - if (mergeParent) - { - mergeParentRot = mayaQ( mergeParent->mKeys[frame-1].mRot[0], - mergeParent->mKeys[frame-1].mRot[1], - mergeParent->mKeys[frame-1].mRot[2], - bvhStringToOrder(mergeParent->mOrder) ); - LLQuaternion parentFrameRot( mergeParent->mFrameMatrix ); - LLQuaternion parentOffsetRot( mergeParent->mOffsetMatrix ); - mergeParentRot = ~parentFrameRot * mergeParentRot * parentFrameRot * parentOffsetRot; - } - else - { - mergeParentRot.loadIdentity(); - } - - if (mergeChild) - { - mergeChildRot = mayaQ( mergeChild->mKeys[frame-1].mRot[0], - mergeChild->mKeys[frame-1].mRot[1], - mergeChild->mKeys[frame-1].mRot[2], - bvhStringToOrder(mergeChild->mOrder) ); - LLQuaternion childFrameRot( mergeChild->mFrameMatrix ); - LLQuaternion childOffsetRot( mergeChild->mOffsetMatrix ); - mergeChildRot = ~childFrameRot * mergeChildRot * childFrameRot * childOffsetRot; - - } - else - { - mergeChildRot.loadIdentity(); - } - - LLQuaternion inRot = mayaQ( key.mRot[0], key.mRot[1], key.mRot[2], order); - - LLQuaternion outRot = frameRotInv* mergeChildRot * inRot * mergeParentRot * ~first_frame_rot * frameRot * offsetRot; - - U16 time_short = F32_to_U16(time, 0.f, mDuration); - dp.packU16(time_short, "time"); - U16 x, y, z; - LLVector3 rot_vec = outRot.packToVector3(); - rot_vec.quantize16(-1.f, 1.f, -1.f, 1.f); - x = F32_to_U16(rot_vec.mV[VX], -1.f, 1.f); - y = F32_to_U16(rot_vec.mV[VY], -1.f, 1.f); - z = F32_to_U16(rot_vec.mV[VZ], -1.f, 1.f); - dp.packU16(x, "rot_angle_x"); - dp.packU16(y, "rot_angle_y"); - dp.packU16(z, "rot_angle_z"); - frame++; - } - - // output position keys if joint has motion. + F32 time; + + // count number of non-ignored joints + S32 numJoints = 0; + for (Joint* joint : mJoints) + { + if ( ! joint->mIgnore ) + numJoints++; + } + + // print header + dp.packU16(KEYFRAME_MOTION_VERSION, "version"); + dp.packU16(KEYFRAME_MOTION_SUBVERSION, "sub_version"); + dp.packS32(mPriority, "base_priority"); + dp.packF32(mDuration, "duration"); + dp.packString(mEmoteName, "emote_name"); + dp.packF32(mLoopInPoint, "loop_in_point"); + dp.packF32(mLoopOutPoint, "loop_out_point"); + dp.packS32(mLoop, "loop"); + dp.packF32(mEaseIn, "ease_in_duration"); + dp.packF32(mEaseOut, "ease_out_duration"); + dp.packU32(mHand, "hand_pose"); + dp.packU32(numJoints, "num_joints"); + + for (Joint* joint : mJoints) + { + // if ignored, skip it + if ( joint->mIgnore ) + continue; + + LLQuaternion first_frame_rot; + LLQuaternion fixup_rot; + + dp.packString(joint->mOutName, "joint_name"); + dp.packS32(joint->mPriority, "joint_priority"); + + // compute coordinate frame rotation + LLQuaternion frameRot( joint->mFrameMatrix ); + LLQuaternion frameRotInv = ~frameRot; + + LLQuaternion offsetRot( joint->mOffsetMatrix ); + + // find mergechild and mergeparent joints, if specified + LLQuaternion mergeParentRot; + LLQuaternion mergeChildRot; + Joint *mergeParent = NULL; + Joint *mergeChild = NULL; + + for (Joint* mjoint : mJoints) + { + if ( !joint->mMergeParentName.empty() && (mjoint->mName == joint->mMergeParentName) ) + { + mergeParent = mjoint; + } + if ( !joint->mMergeChildName.empty() && (mjoint->mName == joint->mMergeChildName) ) + { + mergeChild = mjoint; + } + } + + dp.packS32(joint->mNumRotKeys, "num_rot_keys"); + + LLQuaternion::Order order = bvhStringToOrder( joint->mOrder ); + S32 frame = 0; + for (Key& key : joint->mKeys) + { + + if ((frame == 0) && joint->mRelativeRotationKey) + { + first_frame_rot = mayaQ( key.mRot[0], key.mRot[1], key.mRot[2], order); + + fixup_rot.shortestArc(LLVector3::z_axis * first_frame_rot * frameRot, LLVector3::z_axis); + } + + if (key.mIgnoreRot) + { + frame++; + continue; + } + + time = llmax((F32)(frame - NUMBER_OF_IGNORED_FRAMES_AT_START), 0.0f) * mFrameTime; // Time elapsed before this frame starts. + + if (mergeParent) + { + mergeParentRot = mayaQ( mergeParent->mKeys[frame-1].mRot[0], + mergeParent->mKeys[frame-1].mRot[1], + mergeParent->mKeys[frame-1].mRot[2], + bvhStringToOrder(mergeParent->mOrder) ); + LLQuaternion parentFrameRot( mergeParent->mFrameMatrix ); + LLQuaternion parentOffsetRot( mergeParent->mOffsetMatrix ); + mergeParentRot = ~parentFrameRot * mergeParentRot * parentFrameRot * parentOffsetRot; + } + else + { + mergeParentRot.loadIdentity(); + } + + if (mergeChild) + { + mergeChildRot = mayaQ( mergeChild->mKeys[frame-1].mRot[0], + mergeChild->mKeys[frame-1].mRot[1], + mergeChild->mKeys[frame-1].mRot[2], + bvhStringToOrder(mergeChild->mOrder) ); + LLQuaternion childFrameRot( mergeChild->mFrameMatrix ); + LLQuaternion childOffsetRot( mergeChild->mOffsetMatrix ); + mergeChildRot = ~childFrameRot * mergeChildRot * childFrameRot * childOffsetRot; + + } + else + { + mergeChildRot.loadIdentity(); + } + + LLQuaternion inRot = mayaQ( key.mRot[0], key.mRot[1], key.mRot[2], order); + + LLQuaternion outRot = frameRotInv* mergeChildRot * inRot * mergeParentRot * ~first_frame_rot * frameRot * offsetRot; + + U16 time_short = F32_to_U16(time, 0.f, mDuration); + dp.packU16(time_short, "time"); + U16 x, y, z; + LLVector3 rot_vec = outRot.packToVector3(); + rot_vec.quantize16(-1.f, 1.f, -1.f, 1.f); + x = F32_to_U16(rot_vec.mV[VX], -1.f, 1.f); + y = F32_to_U16(rot_vec.mV[VY], -1.f, 1.f); + z = F32_to_U16(rot_vec.mV[VZ], -1.f, 1.f); + dp.packU16(x, "rot_angle_x"); + dp.packU16(y, "rot_angle_y"); + dp.packU16(z, "rot_angle_z"); + frame++; + } + + // output position keys if joint has motion. if ( !joint->mIgnorePositions ) - { - dp.packS32(joint->mNumPosKeys, "num_pos_keys"); + { + dp.packS32(joint->mNumPosKeys, "num_pos_keys"); - LLVector3 relPos = joint->mRelativePosition; - LLVector3 relKey; + LLVector3 relPos = joint->mRelativePosition; + LLVector3 relKey; - frame = 0; - for (Key& key : joint->mKeys) - { - if ((frame == 0) && joint->mRelativePositionKey) - { - relKey.setVec(key.mPos); - } + frame = 0; + for (Key& key : joint->mKeys) + { + if ((frame == 0) && joint->mRelativePositionKey) + { + relKey.setVec(key.mPos); + } - if (key.mIgnorePos) - { - frame++; - continue; - } + if (key.mIgnorePos) + { + frame++; + continue; + } - time = llmax((F32)(frame - NUMBER_OF_IGNORED_FRAMES_AT_START), 0.0f) * mFrameTime; // Time elapsed before this frame starts. + time = llmax((F32)(frame - NUMBER_OF_IGNORED_FRAMES_AT_START), 0.0f) * mFrameTime; // Time elapsed before this frame starts. - LLVector3 inPos = (LLVector3(key.mPos) - relKey) * ~first_frame_rot;// * fixup_rot; - LLVector3 outPos = inPos * frameRot * offsetRot; + LLVector3 inPos = (LLVector3(key.mPos) - relKey) * ~first_frame_rot;// * fixup_rot; + LLVector3 outPos = inPos * frameRot * offsetRot; - outPos *= INCHES_TO_METERS; + outPos *= INCHES_TO_METERS; //SL-318 Pelvis position can only move 5m. Limiting all joint position offsets to this dist. - outPos -= relPos; - outPos.clamp(-LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET); - - U16 time_short = F32_to_U16(time, 0.f, mDuration); - dp.packU16(time_short, "time"); - - U16 x, y, z; - outPos.quantize16(-LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET, -LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET); - x = F32_to_U16(outPos.mV[VX], -LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET); - y = F32_to_U16(outPos.mV[VY], -LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET); - z = F32_to_U16(outPos.mV[VZ], -LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET); - dp.packU16(x, "pos_x"); - dp.packU16(y, "pos_y"); - dp.packU16(z, "pos_z"); - - frame++; - } - } - else - { - dp.packS32(0, "num_pos_keys"); - } - } - - S32 num_constraints = (S32)mConstraints.size(); - dp.packS32(num_constraints, "num_constraints"); - - for (Constraint& constraint : mConstraints) - { - U8 byte = constraint.mChainLength; - dp.packU8(byte, "chain_length"); - - byte = constraint.mConstraintType; - dp.packU8(byte, "constraint_type"); - dp.packBinaryDataFixed((U8*)constraint.mSourceJointName, 16, "source_volume"); - dp.packVector3(constraint.mSourceOffset, "source_offset"); - dp.packBinaryDataFixed((U8*)constraint.mTargetJointName, 16, "target_volume"); - dp.packVector3(constraint.mTargetOffset, "target_offset"); - dp.packVector3(constraint.mTargetDir, "target_dir"); - dp.packF32(constraint.mEaseInStart, "ease_in_start"); - dp.packF32(constraint.mEaseInStop, "ease_in_stop"); - dp.packF32(constraint.mEaseOutStart, "ease_out_start"); - dp.packF32(constraint.mEaseOutStop, "ease_out_stop"); - } - - - return TRUE; + outPos -= relPos; + outPos.clamp(-LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET); + + U16 time_short = F32_to_U16(time, 0.f, mDuration); + dp.packU16(time_short, "time"); + + U16 x, y, z; + outPos.quantize16(-LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET, -LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET); + x = F32_to_U16(outPos.mV[VX], -LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET); + y = F32_to_U16(outPos.mV[VY], -LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET); + z = F32_to_U16(outPos.mV[VZ], -LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET); + dp.packU16(x, "pos_x"); + dp.packU16(y, "pos_y"); + dp.packU16(z, "pos_z"); + + frame++; + } + } + else + { + dp.packS32(0, "num_pos_keys"); + } + } + + S32 num_constraints = (S32)mConstraints.size(); + dp.packS32(num_constraints, "num_constraints"); + + for (Constraint& constraint : mConstraints) + { + U8 byte = constraint.mChainLength; + dp.packU8(byte, "chain_length"); + + byte = constraint.mConstraintType; + dp.packU8(byte, "constraint_type"); + dp.packBinaryDataFixed((U8*)constraint.mSourceJointName, 16, "source_volume"); + dp.packVector3(constraint.mSourceOffset, "source_offset"); + dp.packBinaryDataFixed((U8*)constraint.mTargetJointName, 16, "target_volume"); + dp.packVector3(constraint.mTargetOffset, "target_offset"); + dp.packVector3(constraint.mTargetDir, "target_dir"); + dp.packF32(constraint.mEaseInStart, "ease_in_start"); + dp.packF32(constraint.mEaseInStop, "ease_in_stop"); + dp.packF32(constraint.mEaseOutStart, "ease_out_start"); + dp.packF32(constraint.mEaseOutStop, "ease_out_stop"); + } + + + return TRUE; } diff --git a/indra/llcharacter/llbvhloader.h b/indra/llcharacter/llbvhloader.h index 47fe409047..7923666d5c 100644 --- a/indra/llcharacter/llbvhloader.h +++ b/indra/llcharacter/llbvhloader.h @@ -1,25 +1,25 @@ -/** +/** * @file llbvhloader.h * @brief Translates a BVH files to LindenLabAnimation format. * * $LicenseInfo:firstyear=2004&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -42,17 +42,17 @@ class LLDataPacker; class FileCloser { public: - FileCloser( apr_file_t *file ) - { - mFile = file; - } - - ~FileCloser() - { - apr_file_close(mFile); - } + FileCloser( apr_file_t *file ) + { + mFile = file; + } + + ~FileCloser() + { + apr_file_close(mFile); + } protected: - apr_file_t* mFile; + apr_file_t* mFile; }; @@ -61,18 +61,18 @@ protected: //------------------------------------------------------------------------ struct Key { - Key() - { - mPos[0] = mPos[1] = mPos[2] = 0.0f; - mRot[0] = mRot[1] = mRot[2] = 0.0f; - mIgnorePos = false; - mIgnoreRot = false; - } - - F32 mPos[3]; - F32 mRot[3]; - BOOL mIgnorePos; - BOOL mIgnoreRot; + Key() + { + mPos[0] = mPos[1] = mPos[2] = 0.0f; + mRot[0] = mRot[1] = mRot[2] = 0.0f; + mIgnorePos = false; + mIgnoreRot = false; + } + + F32 mPos[3]; + F32 mRot[3]; + BOOL mIgnorePos; + BOOL mIgnoreRot; }; @@ -86,61 +86,61 @@ typedef std::vector<Key> KeyVector; //------------------------------------------------------------------------ struct Joint { - Joint(const char *name) - { - mName = name; - mIgnore = FALSE; - mIgnorePositions = FALSE; - mRelativePositionKey = FALSE; - mRelativeRotationKey = FALSE; - mOutName = name; - mOrder[0] = 'X'; - mOrder[1] = 'Y'; - mOrder[2] = 'Z'; - mOrder[3] = 0; - mNumPosKeys = 0; - mNumRotKeys = 0; - mChildTreeMaxDepth = 0; - mPriority = 0; - mNumChannels = 3; - } - - // Include aligned members first - LLMatrix3 mFrameMatrix; - LLMatrix3 mOffsetMatrix; - LLVector3 mRelativePosition; - // - std::string mName; - BOOL mIgnore; - BOOL mIgnorePositions; - BOOL mRelativePositionKey; - BOOL mRelativeRotationKey; - std::string mOutName; - std::string mMergeParentName; - std::string mMergeChildName; - char mOrder[4]; /* Flawfinder: ignore */ - KeyVector mKeys; - S32 mNumPosKeys; - S32 mNumRotKeys; - S32 mChildTreeMaxDepth; - S32 mPriority; - S32 mNumChannels; + Joint(const char *name) + { + mName = name; + mIgnore = FALSE; + mIgnorePositions = FALSE; + mRelativePositionKey = FALSE; + mRelativeRotationKey = FALSE; + mOutName = name; + mOrder[0] = 'X'; + mOrder[1] = 'Y'; + mOrder[2] = 'Z'; + mOrder[3] = 0; + mNumPosKeys = 0; + mNumRotKeys = 0; + mChildTreeMaxDepth = 0; + mPriority = 0; + mNumChannels = 3; + } + + // Include aligned members first + LLMatrix3 mFrameMatrix; + LLMatrix3 mOffsetMatrix; + LLVector3 mRelativePosition; + // + std::string mName; + BOOL mIgnore; + BOOL mIgnorePositions; + BOOL mRelativePositionKey; + BOOL mRelativeRotationKey; + std::string mOutName; + std::string mMergeParentName; + std::string mMergeChildName; + char mOrder[4]; /* Flawfinder: ignore */ + KeyVector mKeys; + S32 mNumPosKeys; + S32 mNumRotKeys; + S32 mChildTreeMaxDepth; + S32 mPriority; + S32 mNumChannels; }; struct Constraint { - char mSourceJointName[16]; /* Flawfinder: ignore */ - char mTargetJointName[16]; /* Flawfinder: ignore */ - S32 mChainLength; - LLVector3 mSourceOffset; - LLVector3 mTargetOffset; - LLVector3 mTargetDir; - F32 mEaseInStart; - F32 mEaseInStop; - F32 mEaseOutStart; - F32 mEaseOutStop; - EConstraintType mConstraintType; + char mSourceJointName[16]; /* Flawfinder: ignore */ + char mTargetJointName[16]; /* Flawfinder: ignore */ + S32 mChainLength; + LLVector3 mSourceOffset; + LLVector3 mTargetOffset; + LLVector3 mTargetDir; + F32 mEaseInStart; + F32 mEaseInStop; + F32 mEaseOutStart; + F32 mEaseOutStop; + EConstraintType mConstraintType; }; //------------------------------------------------------------------------ @@ -159,63 +159,63 @@ typedef std::vector<Constraint> ConstraintVector; class Translation { public: - Translation() - { - mIgnore = FALSE; - mIgnorePositions = FALSE; - mRelativePositionKey = FALSE; - mRelativeRotationKey = FALSE; - mPriorityModifier = 0; - } - - std::string mOutName; - BOOL mIgnore; - BOOL mIgnorePositions; - BOOL mRelativePositionKey; - BOOL mRelativeRotationKey; - LLMatrix3 mFrameMatrix; - LLMatrix3 mOffsetMatrix; - LLVector3 mRelativePosition; - std::string mMergeParentName; - std::string mMergeChildName; - S32 mPriorityModifier; + Translation() + { + mIgnore = FALSE; + mIgnorePositions = FALSE; + mRelativePositionKey = FALSE; + mRelativeRotationKey = FALSE; + mPriorityModifier = 0; + } + + std::string mOutName; + BOOL mIgnore; + BOOL mIgnorePositions; + BOOL mRelativePositionKey; + BOOL mRelativeRotationKey; + LLMatrix3 mFrameMatrix; + LLMatrix3 mOffsetMatrix; + LLVector3 mRelativePosition; + std::string mMergeParentName; + std::string mMergeChildName; + S32 mPriorityModifier; }; typedef enum e_load_status - { - E_ST_OK, - E_ST_EOF, - E_ST_NO_CONSTRAINT, - E_ST_NO_FILE, - E_ST_NO_HIER, - E_ST_NO_JOINT, - E_ST_NO_NAME, - E_ST_NO_OFFSET, - E_ST_NO_CHANNELS, - E_ST_NO_ROTATION, - E_ST_NO_AXIS, - E_ST_NO_MOTION, - E_ST_NO_FRAMES, - E_ST_NO_FRAME_TIME, - E_ST_NO_POS, - E_ST_NO_ROT, - E_ST_NO_XLT_FILE, - E_ST_NO_XLT_HEADER, - E_ST_NO_XLT_NAME, - E_ST_NO_XLT_IGNORE, - E_ST_NO_XLT_RELATIVE, - E_ST_NO_XLT_OUTNAME, - E_ST_NO_XLT_MATRIX, - E_ST_NO_XLT_MERGECHILD, - E_ST_NO_XLT_MERGEPARENT, - E_ST_NO_XLT_PRIORITY, - E_ST_NO_XLT_LOOP, - E_ST_NO_XLT_EASEIN, - E_ST_NO_XLT_EASEOUT, - E_ST_NO_XLT_HAND, - E_ST_NO_XLT_EMOTE, - E_ST_BAD_ROOT - } ELoadStatus; + { + E_ST_OK, + E_ST_EOF, + E_ST_NO_CONSTRAINT, + E_ST_NO_FILE, + E_ST_NO_HIER, + E_ST_NO_JOINT, + E_ST_NO_NAME, + E_ST_NO_OFFSET, + E_ST_NO_CHANNELS, + E_ST_NO_ROTATION, + E_ST_NO_AXIS, + E_ST_NO_MOTION, + E_ST_NO_FRAMES, + E_ST_NO_FRAME_TIME, + E_ST_NO_POS, + E_ST_NO_ROT, + E_ST_NO_XLT_FILE, + E_ST_NO_XLT_HEADER, + E_ST_NO_XLT_NAME, + E_ST_NO_XLT_IGNORE, + E_ST_NO_XLT_RELATIVE, + E_ST_NO_XLT_OUTNAME, + E_ST_NO_XLT_MATRIX, + E_ST_NO_XLT_MERGECHILD, + E_ST_NO_XLT_MERGEPARENT, + E_ST_NO_XLT_PRIORITY, + E_ST_NO_XLT_LOOP, + E_ST_NO_XLT_EASEIN, + E_ST_NO_XLT_EASEOUT, + E_ST_NO_XLT_HAND, + E_ST_NO_XLT_EMOTE, + E_ST_BAD_ROOT + } ELoadStatus; //------------------------------------------------------------------------ // TranslationMap @@ -224,117 +224,117 @@ typedef std::map<std::string, Translation> TranslationMap; class LLBVHLoader { - friend class LLKeyframeMotion; + friend class LLKeyframeMotion; public: - // Constructor + // Constructor LLBVHLoader(const char* buffer, ELoadStatus &loadStatus, S32 &errorLine, std::map<std::string, std::string>& joint_alias_map ); - ~LLBVHLoader(); - -/* - // Status Codes - typedef const char *status_t; - static const char *ST_OK; - static const char *ST_EOF; - static const char *ST_NO_CONSTRAINT; - static const char *ST_NO_FILE; - static const char *ST_NO_HIER; - static const char *ST_NO_JOINT; - static const char *ST_NO_NAME; - static const char *ST_NO_OFFSET; - static const char *ST_NO_CHANNELS; - static const char *ST_NO_ROTATION; - static const char *ST_NO_AXIS; - static const char *ST_NO_MOTION; - static const char *ST_NO_FRAMES; - static const char *ST_NO_FRAME_TIME; - static const char *ST_NO_POS; - static const char *ST_NO_ROT; - static const char *ST_NO_XLT_FILE; - static const char *ST_NO_XLT_HEADER; - static const char *ST_NO_XLT_NAME; - static const char *ST_NO_XLT_IGNORE; - static const char *ST_NO_XLT_RELATIVE; - static const char *ST_NO_XLT_OUTNAME; - static const char *ST_NO_XLT_MATRIX; - static const char *ST_NO_XLT_MERGECHILD; - static const char *ST_NO_XLT_MERGEPARENT; - static const char *ST_NO_XLT_PRIORITY; - static const char *ST_NO_XLT_LOOP; - static const char *ST_NO_XLT_EASEIN; - static const char *ST_NO_XLT_EASEOUT; - static const char *ST_NO_XLT_HAND; - static const char *ST_NO_XLT_EMOTE; - static const char *ST_BAD_ROOT; + ~LLBVHLoader(); + +/* + // Status Codes + typedef const char *status_t; + static const char *ST_OK; + static const char *ST_EOF; + static const char *ST_NO_CONSTRAINT; + static const char *ST_NO_FILE; + static const char *ST_NO_HIER; + static const char *ST_NO_JOINT; + static const char *ST_NO_NAME; + static const char *ST_NO_OFFSET; + static const char *ST_NO_CHANNELS; + static const char *ST_NO_ROTATION; + static const char *ST_NO_AXIS; + static const char *ST_NO_MOTION; + static const char *ST_NO_FRAMES; + static const char *ST_NO_FRAME_TIME; + static const char *ST_NO_POS; + static const char *ST_NO_ROT; + static const char *ST_NO_XLT_FILE; + static const char *ST_NO_XLT_HEADER; + static const char *ST_NO_XLT_NAME; + static const char *ST_NO_XLT_IGNORE; + static const char *ST_NO_XLT_RELATIVE; + static const char *ST_NO_XLT_OUTNAME; + static const char *ST_NO_XLT_MATRIX; + static const char *ST_NO_XLT_MERGECHILD; + static const char *ST_NO_XLT_MERGEPARENT; + static const char *ST_NO_XLT_PRIORITY; + static const char *ST_NO_XLT_LOOP; + static const char *ST_NO_XLT_EASEIN; + static const char *ST_NO_XLT_EASEOUT; + static const char *ST_NO_XLT_HAND; + static const char *ST_NO_XLT_EMOTE; + static const char *ST_BAD_ROOT; */ - // Loads the specified translation table. - ELoadStatus loadTranslationTable(const char *fileName); + // Loads the specified translation table. + ELoadStatus loadTranslationTable(const char *fileName); //Create a new joint alias void makeTranslation(std::string key, std::string value); - + // Loads joint aliases from XML file. ELoadStatus loadAliases(const char * filename); - // Load the specified BVH file. - // Returns status code. - ELoadStatus loadBVHFile(const char *buffer, char *error_text, S32 &error_line); + // Load the specified BVH file. + // Returns status code. + ELoadStatus loadBVHFile(const char *buffer, char *error_text, S32 &error_line); - void dumpBVHInfo(); + void dumpBVHInfo(); - // Applies translations to BVH data loaded. - void applyTranslations(); + // Applies translations to BVH data loaded. + void applyTranslations(); - // Returns the number of lines scanned. - // Useful for error reporting. - S32 getLineNumber() { return mLineNumber; } + // Returns the number of lines scanned. + // Useful for error reporting. + S32 getLineNumber() { return mLineNumber; } - // returns required size of output buffer - U32 getOutputSize(); + // returns required size of output buffer + U32 getOutputSize(); - // writes contents to datapacker - BOOL serialize(LLDataPacker& dp); + // writes contents to datapacker + BOOL serialize(LLDataPacker& dp); - // flags redundant keyframe data - void optimize(); + // flags redundant keyframe data + void optimize(); - void reset(); + void reset(); - F32 getDuration() { return mDuration; } + F32 getDuration() { return mDuration; } - BOOL isInitialized() { return mInitialized; } + BOOL isInitialized() { return mInitialized; } - ELoadStatus getStatus() { return mStatus; } + ELoadStatus getStatus() { return mStatus; } protected: - // Consumes one line of input from file. - BOOL getLine(apr_file_t *fp); - - // parser state - char mLine[BVH_PARSER_LINE_SIZE]; /* Flawfinder: ignore */ - S32 mLineNumber; - - // parsed values - S32 mNumFrames; - F32 mFrameTime; - JointVector mJoints; - ConstraintVector mConstraints; - TranslationMap mTranslations; - - S32 mPriority; - BOOL mLoop; - F32 mLoopInPoint; - F32 mLoopOutPoint; - F32 mEaseIn; - F32 mEaseOut; - S32 mHand; - std::string mEmoteName; - - BOOL mInitialized; - ELoadStatus mStatus; - - // computed values - F32 mDuration; + // Consumes one line of input from file. + BOOL getLine(apr_file_t *fp); + + // parser state + char mLine[BVH_PARSER_LINE_SIZE]; /* Flawfinder: ignore */ + S32 mLineNumber; + + // parsed values + S32 mNumFrames; + F32 mFrameTime; + JointVector mJoints; + ConstraintVector mConstraints; + TranslationMap mTranslations; + + S32 mPriority; + BOOL mLoop; + F32 mLoopInPoint; + F32 mLoopOutPoint; + F32 mEaseIn; + F32 mEaseOut; + S32 mHand; + std::string mEmoteName; + + BOOL mInitialized; + ELoadStatus mStatus; + + // computed values + F32 mDuration; }; #endif // LL_LLBVHLOADER_H diff --git a/indra/llcharacter/llcharacter.cpp b/indra/llcharacter/llcharacter.cpp index cf6be8daf0..f2aa55a32c 100644 --- a/indra/llcharacter/llcharacter.cpp +++ b/indra/llcharacter/llcharacter.cpp @@ -1,25 +1,25 @@ -/** +/** * @file llcharacter.cpp * @brief Implementation of LLCharacter class. * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -46,17 +46,17 @@ BOOL LLCharacter::sAllowInstancesChange = TRUE ; // Class Constructor //----------------------------------------------------------------------------- LLCharacter::LLCharacter() - : - mPreferredPelvisHeight( 0.f ), - mSex( SEX_FEMALE ), - mAppearanceSerialNum( 0 ), - mSkeletonSerialNum( 0 ) + : + mPreferredPelvisHeight( 0.f ), + mSex( SEX_FEMALE ), + mAppearanceSerialNum( 0 ), + mSkeletonSerialNum( 0 ) { - llassert_always(sAllowInstancesChange) ; - sInstances.push_back(this); + llassert_always(sAllowInstancesChange) ; + sInstances.push_back(this); - mMotionController.setCharacter( this ); - mPauseRequest = new LLPauseRequestHandle(); + mMotionController.setCharacter( this ); + mPauseRequest = new LLPauseRequestHandle(); } @@ -65,29 +65,29 @@ LLCharacter::LLCharacter() // Class Destructor //----------------------------------------------------------------------------- LLCharacter::~LLCharacter() -{ - for (LLVisualParam *param = getFirstVisualParam(); - param; - param = getNextVisualParam()) - { - delete param; - } - - U32 i ; - U32 size = sInstances.size() ; - for(i = 0 ; i < size ; i++) - { - if(sInstances[i] == this) - { - break ; - } - } - - llassert_always(i < size) ; - - llassert_always(sAllowInstancesChange) ; - sInstances[i] = sInstances[size - 1] ; - sInstances.pop_back() ; +{ + for (LLVisualParam *param = getFirstVisualParam(); + param; + param = getNextVisualParam()) + { + delete param; + } + + U32 i ; + U32 size = sInstances.size() ; + for(i = 0 ; i < size ; i++) + { + if(sInstances[i] == this) + { + break ; + } + } + + llassert_always(i < size) ; + + llassert_always(sAllowInstancesChange) ; + sInstances[i] = sInstances[size - 1] ; + sInstances.pop_back() ; } @@ -96,19 +96,19 @@ LLCharacter::~LLCharacter() //----------------------------------------------------------------------------- LLJoint *LLCharacter::getJoint( const std::string &name ) { - LLJoint* joint = NULL; - - LLJoint *root = getRootJoint(); - if (root) - { - joint = root->findJoint(name); - } - - if (!joint) - { - LL_WARNS() << "Failed to find joint." << LL_ENDL; - } - return joint; + LLJoint* joint = NULL; + + LLJoint *root = getRootJoint(); + if (root) + { + joint = root->findJoint(name); + } + + if (!joint) + { + LL_WARNS() << "Failed to find joint." << LL_ENDL; + } + return joint; } //----------------------------------------------------------------------------- @@ -116,7 +116,7 @@ LLJoint *LLCharacter::getJoint( const std::string &name ) //----------------------------------------------------------------------------- BOOL LLCharacter::registerMotion( const LLUUID& id, LLMotionConstructor create ) { - return mMotionController.registerMotion(id, create); + return mMotionController.registerMotion(id, create); } //----------------------------------------------------------------------------- @@ -124,7 +124,7 @@ BOOL LLCharacter::registerMotion( const LLUUID& id, LLMotionConstructor create ) //----------------------------------------------------------------------------- void LLCharacter::removeMotion( const LLUUID& id ) { - mMotionController.removeMotion(id); + mMotionController.removeMotion(id); } //----------------------------------------------------------------------------- @@ -132,7 +132,7 @@ void LLCharacter::removeMotion( const LLUUID& id ) //----------------------------------------------------------------------------- LLMotion* LLCharacter::findMotion( const LLUUID &id ) { - return mMotionController.findMotion( id ); + return mMotionController.findMotion( id ); } //----------------------------------------------------------------------------- @@ -141,7 +141,7 @@ LLMotion* LLCharacter::findMotion( const LLUUID &id ) //----------------------------------------------------------------------------- LLMotion* LLCharacter::createMotion( const LLUUID &id ) { - return mMotionController.createMotion( id ); + return mMotionController.createMotion( id ); } //----------------------------------------------------------------------------- @@ -149,7 +149,7 @@ LLMotion* LLCharacter::createMotion( const LLUUID &id ) //----------------------------------------------------------------------------- BOOL LLCharacter::startMotion(const LLUUID &id, F32 start_offset) { - return mMotionController.startMotion(id, start_offset); + return mMotionController.startMotion(id, start_offset); } @@ -158,7 +158,7 @@ BOOL LLCharacter::startMotion(const LLUUID &id, F32 start_offset) //----------------------------------------------------------------------------- BOOL LLCharacter::stopMotion(const LLUUID& id, BOOL stop_immediate) { - return mMotionController.stopMotionLocally(id, stop_immediate); + return mMotionController.stopMotionLocally(id, stop_immediate); } //----------------------------------------------------------------------------- @@ -166,13 +166,13 @@ BOOL LLCharacter::stopMotion(const LLUUID& id, BOOL stop_immediate) //----------------------------------------------------------------------------- BOOL LLCharacter::isMotionActive(const LLUUID& id) { - LLMotion *motionp = mMotionController.findMotion(id); - if (motionp) - { - return mMotionController.isMotionActive(motionp); - } + LLMotion *motionp = mMotionController.findMotion(id); + if (motionp) + { + return mMotionController.isMotionActive(motionp); + } - return FALSE; + return FALSE; } @@ -181,7 +181,7 @@ BOOL LLCharacter::isMotionActive(const LLUUID& id) //----------------------------------------------------------------------------- void LLCharacter::requestStopMotion( LLMotion* motion) { -// LL_INFOS() << "DEBUG: Char::onDeactivateMotion( " << motionName << " )" << LL_ENDL; +// LL_INFOS() << "DEBUG: Char::onDeactivateMotion( " << motionName << " )" << LL_ENDL; } @@ -191,22 +191,22 @@ void LLCharacter::requestStopMotion( LLMotion* motion) void LLCharacter::updateMotions(e_update_t update_type) { LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR; - if (update_type == HIDDEN_UPDATE) - { - mMotionController.updateMotionsMinimal(); - } - else - { - // unpause if the number of outstanding pause requests has dropped to the initial one - if (mMotionController.isPaused() && mPauseRequest->getNumRefs() == 1) - { - mMotionController.unpauseAllMotions(); - } - bool force_update = (update_type == FORCE_UPDATE); - { - mMotionController.updateMotions(force_update); - } - } + if (update_type == HIDDEN_UPDATE) + { + mMotionController.updateMotionsMinimal(); + } + else + { + // unpause if the number of outstanding pause requests has dropped to the initial one + if (mMotionController.isPaused() && mPauseRequest->getNumRefs() == 1) + { + mMotionController.unpauseAllMotions(); + } + bool force_update = (update_type == FORCE_UPDATE); + { + mMotionController.updateMotions(force_update); + } + } } @@ -215,7 +215,7 @@ void LLCharacter::updateMotions(e_update_t update_type) //----------------------------------------------------------------------------- void LLCharacter::deactivateAllMotions() { - mMotionController.deactivateAllMotions(); + mMotionController.deactivateAllMotions(); } @@ -224,7 +224,7 @@ void LLCharacter::deactivateAllMotions() //----------------------------------------------------------------------------- void LLCharacter::flushAllMotions() { - mMotionController.flushAllMotions(); + mMotionController.flushAllMotions(); } @@ -233,23 +233,23 @@ void LLCharacter::flushAllMotions() //----------------------------------------------------------------------------- void LLCharacter::dumpCharacter( LLJoint* joint ) { - // handle top level entry into recursion - if (joint == NULL) - { - LL_INFOS() << "DEBUG: Dumping Character @" << this << LL_ENDL; - dumpCharacter( getRootJoint() ); - LL_INFOS() << "DEBUG: Done." << LL_ENDL; - return; - } - - // print joint info - LL_INFOS() << "DEBUG: " << joint->getName() << " (" << (joint->getParent()?joint->getParent()->getName():std::string("ROOT")) << ")" << LL_ENDL; - - // recurse - for (LLJoint* child_joint : joint->mChildren) - { - dumpCharacter(child_joint); - } + // handle top level entry into recursion + if (joint == NULL) + { + LL_INFOS() << "DEBUG: Dumping Character @" << this << LL_ENDL; + dumpCharacter( getRootJoint() ); + LL_INFOS() << "DEBUG: Done." << LL_ENDL; + return; + } + + // print joint info + LL_INFOS() << "DEBUG: " << joint->getName() << " (" << (joint->getParent()?joint->getParent()->getName():std::string("ROOT")) << ")" << LL_ENDL; + + // recurse + for (LLJoint* child_joint : joint->mChildren) + { + dumpCharacter(child_joint); + } } //----------------------------------------------------------------------------- @@ -257,7 +257,7 @@ void LLCharacter::dumpCharacter( LLJoint* joint ) //----------------------------------------------------------------------------- void LLCharacter::setAnimationData(std::string name, void *data) { - mAnimationData[name] = data; + mAnimationData[name] = data; } //----------------------------------------------------------------------------- @@ -265,7 +265,7 @@ void LLCharacter::setAnimationData(std::string name, void *data) //----------------------------------------------------------------------------- void* LLCharacter::getAnimationData(std::string name) { - return get_if_there(mAnimationData, name, (void*)NULL); + return get_if_there(mAnimationData, name, (void*)NULL); } //----------------------------------------------------------------------------- @@ -273,7 +273,7 @@ void* LLCharacter::getAnimationData(std::string name) //----------------------------------------------------------------------------- void LLCharacter::removeAnimationData(std::string name) { - mAnimationData.erase(name); + mAnimationData.erase(name); } //----------------------------------------------------------------------------- @@ -281,14 +281,14 @@ void LLCharacter::removeAnimationData(std::string name) //----------------------------------------------------------------------------- BOOL LLCharacter::setVisualParamWeight(const LLVisualParam* which_param, F32 weight) { - S32 index = which_param->getID(); - visual_param_index_map_t::iterator index_iter = mVisualParamIndexMap.find(index); - if (index_iter != mVisualParamIndexMap.end()) - { - index_iter->second->setWeight(weight); - return TRUE; - } - return FALSE; + S32 index = which_param->getID(); + visual_param_index_map_t::iterator index_iter = mVisualParamIndexMap.find(index); + if (index_iter != mVisualParamIndexMap.end()) + { + index_iter->second->setWeight(weight); + return TRUE; + } + return FALSE; } //----------------------------------------------------------------------------- @@ -296,17 +296,17 @@ BOOL LLCharacter::setVisualParamWeight(const LLVisualParam* which_param, F32 wei //----------------------------------------------------------------------------- BOOL LLCharacter::setVisualParamWeight(const char* param_name, F32 weight) { - std::string tname(param_name); - LLStringUtil::toLower(tname); - char *tableptr = sVisualParamNames.checkString(tname); - visual_param_name_map_t::iterator name_iter = mVisualParamNameMap.find(tableptr); - if (name_iter != mVisualParamNameMap.end()) - { - name_iter->second->setWeight(weight); - return TRUE; - } - LL_WARNS() << "LLCharacter::setVisualParamWeight() Invalid visual parameter: " << param_name << LL_ENDL; - return FALSE; + std::string tname(param_name); + LLStringUtil::toLower(tname); + char *tableptr = sVisualParamNames.checkString(tname); + visual_param_name_map_t::iterator name_iter = mVisualParamNameMap.find(tableptr); + if (name_iter != mVisualParamNameMap.end()) + { + name_iter->second->setWeight(weight); + return TRUE; + } + LL_WARNS() << "LLCharacter::setVisualParamWeight() Invalid visual parameter: " << param_name << LL_ENDL; + return FALSE; } //----------------------------------------------------------------------------- @@ -314,14 +314,14 @@ BOOL LLCharacter::setVisualParamWeight(const char* param_name, F32 weight) //----------------------------------------------------------------------------- BOOL LLCharacter::setVisualParamWeight(S32 index, F32 weight) { - visual_param_index_map_t::iterator index_iter = mVisualParamIndexMap.find(index); - if (index_iter != mVisualParamIndexMap.end()) - { - index_iter->second->setWeight(weight); - return TRUE; - } - LL_WARNS() << "LLCharacter::setVisualParamWeight() Invalid visual parameter index: " << index << LL_ENDL; - return FALSE; + visual_param_index_map_t::iterator index_iter = mVisualParamIndexMap.find(index); + if (index_iter != mVisualParamIndexMap.end()) + { + index_iter->second->setWeight(weight); + return TRUE; + } + LL_WARNS() << "LLCharacter::setVisualParamWeight() Invalid visual parameter index: " << index << LL_ENDL; + return FALSE; } //----------------------------------------------------------------------------- @@ -329,17 +329,17 @@ BOOL LLCharacter::setVisualParamWeight(S32 index, F32 weight) //----------------------------------------------------------------------------- F32 LLCharacter::getVisualParamWeight(LLVisualParam *which_param) { - S32 index = which_param->getID(); - visual_param_index_map_t::iterator index_iter = mVisualParamIndexMap.find(index); - if (index_iter != mVisualParamIndexMap.end()) - { - return index_iter->second->getWeight(); - } - else - { - LL_WARNS() << "LLCharacter::getVisualParamWeight() Invalid visual parameter*, index= " << index << LL_ENDL; - return 0.f; - } + S32 index = which_param->getID(); + visual_param_index_map_t::iterator index_iter = mVisualParamIndexMap.find(index); + if (index_iter != mVisualParamIndexMap.end()) + { + return index_iter->second->getWeight(); + } + else + { + LL_WARNS() << "LLCharacter::getVisualParamWeight() Invalid visual parameter*, index= " << index << LL_ENDL; + return 0.f; + } } //----------------------------------------------------------------------------- @@ -347,16 +347,16 @@ F32 LLCharacter::getVisualParamWeight(LLVisualParam *which_param) //----------------------------------------------------------------------------- F32 LLCharacter::getVisualParamWeight(const char* param_name) { - std::string tname(param_name); - LLStringUtil::toLower(tname); - char *tableptr = sVisualParamNames.checkString(tname); - visual_param_name_map_t::iterator name_iter = mVisualParamNameMap.find(tableptr); - if (name_iter != mVisualParamNameMap.end()) - { - return name_iter->second->getWeight(); - } - LL_WARNS() << "LLCharacter::getVisualParamWeight() Invalid visual parameter: " << param_name << LL_ENDL; - return 0.f; + std::string tname(param_name); + LLStringUtil::toLower(tname); + char *tableptr = sVisualParamNames.checkString(tname); + visual_param_name_map_t::iterator name_iter = mVisualParamNameMap.find(tableptr); + if (name_iter != mVisualParamNameMap.end()) + { + return name_iter->second->getWeight(); + } + LL_WARNS() << "LLCharacter::getVisualParamWeight() Invalid visual parameter: " << param_name << LL_ENDL; + return 0.f; } //----------------------------------------------------------------------------- @@ -364,16 +364,16 @@ F32 LLCharacter::getVisualParamWeight(const char* param_name) //----------------------------------------------------------------------------- F32 LLCharacter::getVisualParamWeight(S32 index) { - visual_param_index_map_t::iterator index_iter = mVisualParamIndexMap.find(index); - if (index_iter != mVisualParamIndexMap.end()) - { - return index_iter->second->getWeight(); - } - else - { - LL_WARNS() << "LLCharacter::getVisualParamWeight() Invalid visual parameter index: " << index << LL_ENDL; - return 0.f; - } + visual_param_index_map_t::iterator index_iter = mVisualParamIndexMap.find(index); + if (index_iter != mVisualParamIndexMap.end()) + { + return index_iter->second->getWeight(); + } + else + { + LL_WARNS() << "LLCharacter::getVisualParamWeight() Invalid visual parameter index: " << index << LL_ENDL; + return 0.f; + } } //----------------------------------------------------------------------------- @@ -381,32 +381,32 @@ F32 LLCharacter::getVisualParamWeight(S32 index) //----------------------------------------------------------------------------- void LLCharacter::clearVisualParamWeights() { - for (LLVisualParam *param = getFirstVisualParam(); - param; - param = getNextVisualParam()) - { - if (param->isTweakable()) - { - param->setWeight( param->getDefaultWeight()); - } - } + for (LLVisualParam *param = getFirstVisualParam(); + param; + param = getNextVisualParam()) + { + if (param->isTweakable()) + { + param->setWeight( param->getDefaultWeight()); + } + } } //----------------------------------------------------------------------------- // getVisualParam() //----------------------------------------------------------------------------- -LLVisualParam* LLCharacter::getVisualParam(const char *param_name) +LLVisualParam* LLCharacter::getVisualParam(const char *param_name) { - std::string tname(param_name); - LLStringUtil::toLower(tname); - char *tableptr = sVisualParamNames.checkString(tname); - visual_param_name_map_t::iterator name_iter = mVisualParamNameMap.find(tableptr); - if (name_iter != mVisualParamNameMap.end()) - { - return name_iter->second; - } - LL_WARNS() << "LLCharacter::getVisualParam() Invalid visual parameter: " << param_name << LL_ENDL; - return NULL; + std::string tname(param_name); + LLStringUtil::toLower(tname); + char *tableptr = sVisualParamNames.checkString(tname); + visual_param_name_map_t::iterator name_iter = mVisualParamNameMap.find(tableptr); + if (name_iter != mVisualParamNameMap.end()) + { + return name_iter->second; + } + LL_WARNS() << "LLCharacter::getVisualParam() Invalid visual parameter: " << param_name << LL_ENDL; + return NULL; } //----------------------------------------------------------------------------- @@ -414,25 +414,25 @@ LLVisualParam* LLCharacter::getVisualParam(const char *param_name) //----------------------------------------------------------------------------- void LLCharacter::addSharedVisualParam(LLVisualParam *param) { - S32 index = param->getID(); - visual_param_index_map_t::iterator index_iter = mVisualParamIndexMap.find(index); - LLVisualParam* current_param = 0; - if (index_iter != mVisualParamIndexMap.end()) - current_param = index_iter->second; - if( current_param ) - { - LLVisualParam* next_param = current_param; - while(next_param->getNextParam()) - { - next_param = next_param->getNextParam(); - } - next_param->setNextParam(param); - } - else - { - LL_WARNS() << "Shared visual parameter " << param->getName() << " does not already exist with ID " << - param->getID() << LL_ENDL; - } + S32 index = param->getID(); + visual_param_index_map_t::iterator index_iter = mVisualParamIndexMap.find(index); + LLVisualParam* current_param = 0; + if (index_iter != mVisualParamIndexMap.end()) + current_param = index_iter->second; + if( current_param ) + { + LLVisualParam* next_param = current_param; + while(next_param->getNextParam()) + { + next_param = next_param->getNextParam(); + } + next_param->setNextParam(param); + } + else + { + LL_WARNS() << "Shared visual parameter " << param->getName() << " does not already exist with ID " << + param->getID() << LL_ENDL; + } } //----------------------------------------------------------------------------- @@ -440,34 +440,34 @@ void LLCharacter::addSharedVisualParam(LLVisualParam *param) //----------------------------------------------------------------------------- void LLCharacter::addVisualParam(LLVisualParam *param) { - S32 index = param->getID(); - // Add Index map - std::pair<visual_param_index_map_t::iterator, bool> idxres; - idxres = mVisualParamIndexMap.insert(visual_param_index_map_t::value_type(index, param)); - if (!idxres.second) - { - LL_WARNS() << "Visual parameter " << param->getName() << " already exists with same ID as " << - param->getName() << LL_ENDL; - visual_param_index_map_t::iterator index_iter = idxres.first; - index_iter->second = param; - } - - if (param->getInfo()) - { - // Add name map - std::string tname(param->getName()); - LLStringUtil::toLower(tname); - char *tableptr = sVisualParamNames.addString(tname); - std::pair<visual_param_name_map_t::iterator, bool> nameres; - nameres = mVisualParamNameMap.insert(visual_param_name_map_t::value_type(tableptr, param)); - if (!nameres.second) - { - // Already exists, copy param - visual_param_name_map_t::iterator name_iter = nameres.first; - name_iter->second = param; - } - } - //LL_INFOS() << "Adding Visual Param '" << param->getName() << "' ( " << index << " )" << LL_ENDL; + S32 index = param->getID(); + // Add Index map + std::pair<visual_param_index_map_t::iterator, bool> idxres; + idxres = mVisualParamIndexMap.insert(visual_param_index_map_t::value_type(index, param)); + if (!idxres.second) + { + LL_WARNS() << "Visual parameter " << param->getName() << " already exists with same ID as " << + param->getName() << LL_ENDL; + visual_param_index_map_t::iterator index_iter = idxres.first; + index_iter->second = param; + } + + if (param->getInfo()) + { + // Add name map + std::string tname(param->getName()); + LLStringUtil::toLower(tname); + char *tableptr = sVisualParamNames.addString(tname); + std::pair<visual_param_name_map_t::iterator, bool> nameres; + nameres = mVisualParamNameMap.insert(visual_param_name_map_t::value_type(tableptr, param)); + if (!nameres.second) + { + // Already exists, copy param + visual_param_name_map_t::iterator name_iter = nameres.first; + name_iter->second = param; + } + } + //LL_INFOS() << "Adding Visual Param '" << param->getName() << "' ( " << index << " )" << LL_ENDL; } //----------------------------------------------------------------------------- @@ -475,26 +475,26 @@ void LLCharacter::addVisualParam(LLVisualParam *param) //----------------------------------------------------------------------------- void LLCharacter::updateVisualParams() { - for (LLVisualParam *param = getFirstVisualParam(); - param; - param = getNextVisualParam()) - { - if (param->isAnimating()) - { - continue; - } - // only apply parameters whose effective weight has changed - F32 effective_weight = ( param->getSex() & mSex ) ? param->getWeight() : param->getDefaultWeight(); - if (effective_weight != param->getLastWeight()) - { - param->apply( mSex ); - } - } + for (LLVisualParam *param = getFirstVisualParam(); + param; + param = getNextVisualParam()) + { + if (param->isAnimating()) + { + continue; + } + // only apply parameters whose effective weight has changed + F32 effective_weight = ( param->getSex() & mSex ) ? param->getWeight() : param->getDefaultWeight(); + if (effective_weight != param->getLastWeight()) + { + param->apply( mSex ); + } + } } - + LLAnimPauseRequest LLCharacter::requestPause() { - mMotionController.pauseAllMotions(); - return mPauseRequest; + mMotionController.pauseAllMotions(); + return mPauseRequest; } diff --git a/indra/llcharacter/llcharacter.h b/indra/llcharacter/llcharacter.h index 6d56d59e8c..b186b9052e 100644 --- a/indra/llcharacter/llcharacter.h +++ b/indra/llcharacter/llcharacter.h @@ -1,25 +1,25 @@ -/** +/** * @file llcharacter.h * @brief Implementation of LLCharacter class. * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -44,7 +44,7 @@ class LLPolyMesh; class LLPauseRequestHandle : public LLThreadSafeRefCount { public: - LLPauseRequestHandle() {}; + LLPauseRequestHandle() {}; }; typedef LLPointer<LLPauseRequestHandle> LLAnimPauseRequest; @@ -55,236 +55,236 @@ typedef LLPointer<LLPauseRequestHandle> LLAnimPauseRequest; class LLCharacter { public: - // Constructor - LLCharacter(); + // Constructor + LLCharacter(); + + // Destructor + virtual ~LLCharacter(); + + //------------------------------------------------------------------------- + // LLCharacter Interface + // These functions must be implemented by subclasses. + //------------------------------------------------------------------------- + + // get the prefix to be used to lookup motion data files + // from the viewer data directory + virtual const char *getAnimationPrefix() = 0; + + // get the root joint of the character + virtual LLJoint *getRootJoint() = 0; + + // get the specified joint + // default implementation does recursive search, + // subclasses may optimize/cache results. + virtual LLJoint *getJoint( const std::string &name ); + + // get the position of the character + virtual LLVector3 getCharacterPosition() = 0; + + // get the rotation of the character + virtual LLQuaternion getCharacterRotation() = 0; + + // get the velocity of the character + virtual LLVector3 getCharacterVelocity() = 0; + + // get the angular velocity of the character + virtual LLVector3 getCharacterAngularVelocity() = 0; + + // get the height & normal of the ground under a point + virtual void getGround(const LLVector3 &inPos, LLVector3 &outPos, LLVector3 &outNorm) = 0; + + // skeleton joint accessor to support joint subclasses + virtual LLJoint *getCharacterJoint( U32 i ) = 0; + + // get the physics time dilation for the simulator + virtual F32 getTimeDilation() = 0; + + // gets current pixel area of this character + virtual F32 getPixelArea() const = 0; + + // gets the head mesh of the character + virtual LLPolyMesh* getHeadMesh() = 0; + + // gets the upper body mesh of the character + virtual LLPolyMesh* getUpperBodyMesh() = 0; + + // gets global coordinates from agent local coordinates + virtual LLVector3d getPosGlobalFromAgent(const LLVector3 &position) = 0; + + // gets agent local coordinates from global coordinates + virtual LLVector3 getPosAgentFromGlobal(const LLVector3d &position) = 0; + + // updates all visual parameters for this character + virtual void updateVisualParams(); + + virtual void addDebugText( const std::string& text ) = 0; + + virtual const LLUUID& getID() const = 0; + //------------------------------------------------------------------------- + // End Interface + //------------------------------------------------------------------------- + // registers a motion with the character + // returns true if successfull + BOOL registerMotion( const LLUUID& id, LLMotionConstructor create ); + + void removeMotion( const LLUUID& id ); + + // returns an instance of a registered motion, creating one if necessary + LLMotion* createMotion( const LLUUID &id ); + + // returns an existing instance of a registered motion + LLMotion* findMotion( const LLUUID &id ); + + // start a motion + // returns true if successful, false if an error occurred + virtual BOOL startMotion( const LLUUID& id, F32 start_offset = 0.f); + + // stop a motion + virtual BOOL stopMotion( const LLUUID& id, BOOL stop_immediate = FALSE ); + + // is this motion active? + BOOL isMotionActive( const LLUUID& id ); + + // Event handler for motion deactivation. + // Called when a motion has completely stopped and has been deactivated. + // Subclasses may optionally override this. + // The default implementation does nothing. + virtual void requestStopMotion( LLMotion* motion ); + + // periodic update function, steps the motion controller + enum e_update_t { NORMAL_UPDATE, HIDDEN_UPDATE, FORCE_UPDATE }; + void updateMotions(e_update_t update_type); + + LLAnimPauseRequest requestPause(); + BOOL areAnimationsPaused() const { return mMotionController.isPaused(); } + void setAnimTimeFactor(F32 factor) { mMotionController.setTimeFactor(factor); } + void setTimeStep(F32 time_step) { mMotionController.setTimeStep(time_step); } + + LLMotionController& getMotionController() { return mMotionController; } + + // Releases all motion instances which should result in + // no cached references to character joint data. This is + // useful if a character wants to rebuild it's skeleton. + virtual void flushAllMotions(); + + // Flush only wipes active animations. + virtual void deactivateAllMotions(); - // Destructor - virtual ~LLCharacter(); + // dumps information for debugging + virtual void dumpCharacter( LLJoint *joint = NULL ); - //------------------------------------------------------------------------- - // LLCharacter Interface - // These functions must be implemented by subclasses. - //------------------------------------------------------------------------- + virtual F32 getPreferredPelvisHeight() { return mPreferredPelvisHeight; } - // get the prefix to be used to lookup motion data files - // from the viewer data directory - virtual const char *getAnimationPrefix() = 0; + virtual LLVector3 getVolumePos(S32 joint_index, LLVector3& volume_offset) { return LLVector3::zero; } - // get the root joint of the character - virtual LLJoint *getRootJoint() = 0; + virtual LLJoint* findCollisionVolume(S32 volume_id) { return NULL; } - // get the specified joint - // default implementation does recursive search, - // subclasses may optimize/cache results. - virtual LLJoint *getJoint( const std::string &name ); + virtual S32 getCollisionVolumeID(std::string &name) { return -1; } - // get the position of the character - virtual LLVector3 getCharacterPosition() = 0; + void setAnimationData(std::string name, void *data); - // get the rotation of the character - virtual LLQuaternion getCharacterRotation() = 0; + void *getAnimationData(std::string name); - // get the velocity of the character - virtual LLVector3 getCharacterVelocity() = 0; + void removeAnimationData(std::string name); - // get the angular velocity of the character - virtual LLVector3 getCharacterAngularVelocity() = 0; + void addVisualParam(LLVisualParam *param); + void addSharedVisualParam(LLVisualParam *param); - // get the height & normal of the ground under a point - virtual void getGround(const LLVector3 &inPos, LLVector3 &outPos, LLVector3 &outNorm) = 0; + virtual BOOL setVisualParamWeight(const LLVisualParam *which_param, F32 weight); + virtual BOOL setVisualParamWeight(const char* param_name, F32 weight); + virtual BOOL setVisualParamWeight(S32 index, F32 weight); - // skeleton joint accessor to support joint subclasses - virtual LLJoint *getCharacterJoint( U32 i ) = 0; + // get visual param weight by param or name + F32 getVisualParamWeight(LLVisualParam *distortion); + F32 getVisualParamWeight(const char* param_name); + F32 getVisualParamWeight(S32 index); - // get the physics time dilation for the simulator - virtual F32 getTimeDilation() = 0; + // set all morph weights to defaults + void clearVisualParamWeights(); - // gets current pixel area of this character - virtual F32 getPixelArea() const = 0; + // visual parameter accessors + LLVisualParam* getFirstVisualParam() + { + mCurIterator = mVisualParamIndexMap.begin(); + return getNextVisualParam(); + } + LLVisualParam* getNextVisualParam() + { + if (mCurIterator == mVisualParamIndexMap.end()) + return 0; + return (mCurIterator++)->second; + } - // gets the head mesh of the character - virtual LLPolyMesh* getHeadMesh() = 0; + S32 getVisualParamCountInGroup(const EVisualParamGroup group) const + { + S32 rtn = 0; + for (const visual_param_index_map_t::value_type& index_pair : mVisualParamIndexMap) + { + if (index_pair.second->getGroup() == group) + { + ++rtn; + } + } + return rtn; + } - // gets the upper body mesh of the character - virtual LLPolyMesh* getUpperBodyMesh() = 0; + LLVisualParam* getVisualParam(S32 id) const + { + visual_param_index_map_t::const_iterator iter = mVisualParamIndexMap.find(id); + return (iter == mVisualParamIndexMap.end()) ? 0 : iter->second; + } + S32 getVisualParamID(LLVisualParam *id) + { + for (visual_param_index_map_t::value_type& index_pair : mVisualParamIndexMap) + { + if (index_pair.second == id) + return index_pair.first; + } + return 0; + } + S32 getVisualParamCount() const { return (S32)mVisualParamIndexMap.size(); } + LLVisualParam* getVisualParam(const char *name); + + + ESex getSex() const { return mSex; } + void setSex( ESex sex ) { mSex = sex; } + + U32 getAppearanceSerialNum() const { return mAppearanceSerialNum; } + void setAppearanceSerialNum( U32 num ) { mAppearanceSerialNum = num; } + + U32 getSkeletonSerialNum() const { return mSkeletonSerialNum; } + void setSkeletonSerialNum( U32 num ) { mSkeletonSerialNum = num; } - // gets global coordinates from agent local coordinates - virtual LLVector3d getPosGlobalFromAgent(const LLVector3 &position) = 0; - - // gets agent local coordinates from global coordinates - virtual LLVector3 getPosAgentFromGlobal(const LLVector3d &position) = 0; - - // updates all visual parameters for this character - virtual void updateVisualParams(); - - virtual void addDebugText( const std::string& text ) = 0; - - virtual const LLUUID& getID() const = 0; - //------------------------------------------------------------------------- - // End Interface - //------------------------------------------------------------------------- - // registers a motion with the character - // returns true if successfull - BOOL registerMotion( const LLUUID& id, LLMotionConstructor create ); - - void removeMotion( const LLUUID& id ); - - // returns an instance of a registered motion, creating one if necessary - LLMotion* createMotion( const LLUUID &id ); - - // returns an existing instance of a registered motion - LLMotion* findMotion( const LLUUID &id ); - - // start a motion - // returns true if successful, false if an error occurred - virtual BOOL startMotion( const LLUUID& id, F32 start_offset = 0.f); - - // stop a motion - virtual BOOL stopMotion( const LLUUID& id, BOOL stop_immediate = FALSE ); - - // is this motion active? - BOOL isMotionActive( const LLUUID& id ); - - // Event handler for motion deactivation. - // Called when a motion has completely stopped and has been deactivated. - // Subclasses may optionally override this. - // The default implementation does nothing. - virtual void requestStopMotion( LLMotion* motion ); - - // periodic update function, steps the motion controller - enum e_update_t { NORMAL_UPDATE, HIDDEN_UPDATE, FORCE_UPDATE }; - void updateMotions(e_update_t update_type); - - LLAnimPauseRequest requestPause(); - BOOL areAnimationsPaused() const { return mMotionController.isPaused(); } - void setAnimTimeFactor(F32 factor) { mMotionController.setTimeFactor(factor); } - void setTimeStep(F32 time_step) { mMotionController.setTimeStep(time_step); } - - LLMotionController& getMotionController() { return mMotionController; } - - // Releases all motion instances which should result in - // no cached references to character joint data. This is - // useful if a character wants to rebuild it's skeleton. - virtual void flushAllMotions(); - - // Flush only wipes active animations. - virtual void deactivateAllMotions(); - - // dumps information for debugging - virtual void dumpCharacter( LLJoint *joint = NULL ); - - virtual F32 getPreferredPelvisHeight() { return mPreferredPelvisHeight; } - - virtual LLVector3 getVolumePos(S32 joint_index, LLVector3& volume_offset) { return LLVector3::zero; } - - virtual LLJoint* findCollisionVolume(S32 volume_id) { return NULL; } - - virtual S32 getCollisionVolumeID(std::string &name) { return -1; } - - void setAnimationData(std::string name, void *data); - - void *getAnimationData(std::string name); - - void removeAnimationData(std::string name); - - void addVisualParam(LLVisualParam *param); - void addSharedVisualParam(LLVisualParam *param); - - virtual BOOL setVisualParamWeight(const LLVisualParam *which_param, F32 weight); - virtual BOOL setVisualParamWeight(const char* param_name, F32 weight); - virtual BOOL setVisualParamWeight(S32 index, F32 weight); - - // get visual param weight by param or name - F32 getVisualParamWeight(LLVisualParam *distortion); - F32 getVisualParamWeight(const char* param_name); - F32 getVisualParamWeight(S32 index); - - // set all morph weights to defaults - void clearVisualParamWeights(); - - // visual parameter accessors - LLVisualParam* getFirstVisualParam() - { - mCurIterator = mVisualParamIndexMap.begin(); - return getNextVisualParam(); - } - LLVisualParam* getNextVisualParam() - { - if (mCurIterator == mVisualParamIndexMap.end()) - return 0; - return (mCurIterator++)->second; - } - - S32 getVisualParamCountInGroup(const EVisualParamGroup group) const - { - S32 rtn = 0; - for (const visual_param_index_map_t::value_type& index_pair : mVisualParamIndexMap) - { - if (index_pair.second->getGroup() == group) - { - ++rtn; - } - } - return rtn; - } - - LLVisualParam* getVisualParam(S32 id) const - { - visual_param_index_map_t::const_iterator iter = mVisualParamIndexMap.find(id); - return (iter == mVisualParamIndexMap.end()) ? 0 : iter->second; - } - S32 getVisualParamID(LLVisualParam *id) - { - for (visual_param_index_map_t::value_type& index_pair : mVisualParamIndexMap) - { - if (index_pair.second == id) - return index_pair.first; - } - return 0; - } - S32 getVisualParamCount() const { return (S32)mVisualParamIndexMap.size(); } - LLVisualParam* getVisualParam(const char *name); - - - ESex getSex() const { return mSex; } - void setSex( ESex sex ) { mSex = sex; } - - U32 getAppearanceSerialNum() const { return mAppearanceSerialNum; } - void setAppearanceSerialNum( U32 num ) { mAppearanceSerialNum = num; } - - U32 getSkeletonSerialNum() const { return mSkeletonSerialNum; } - void setSkeletonSerialNum( U32 num ) { mSkeletonSerialNum = num; } - - static std::vector< LLCharacter* > sInstances; - static BOOL sAllowInstancesChange ; //debug use - - virtual void setHoverOffset(const LLVector3& hover_offset, bool send_update=true) { mHoverOffset = hover_offset; } - const LLVector3& getHoverOffset() const { return mHoverOffset; } + static std::vector< LLCharacter* > sInstances; + static BOOL sAllowInstancesChange ; //debug use + + virtual void setHoverOffset(const LLVector3& hover_offset, bool send_update=true) { mHoverOffset = hover_offset; } + const LLVector3& getHoverOffset() const { return mHoverOffset; } protected: - LLMotionController mMotionController; + LLMotionController mMotionController; - typedef std::map<std::string, void *> animation_data_map_t; - animation_data_map_t mAnimationData; + typedef std::map<std::string, void *> animation_data_map_t; + animation_data_map_t mAnimationData; - F32 mPreferredPelvisHeight; - ESex mSex; - U32 mAppearanceSerialNum; - U32 mSkeletonSerialNum; - LLAnimPauseRequest mPauseRequest; + F32 mPreferredPelvisHeight; + ESex mSex; + U32 mAppearanceSerialNum; + U32 mSkeletonSerialNum; + LLAnimPauseRequest mPauseRequest; private: - // visual parameter stuff - typedef std::map<S32, LLVisualParam *> visual_param_index_map_t; - typedef std::map<char *, LLVisualParam *> visual_param_name_map_t; + // visual parameter stuff + typedef std::map<S32, LLVisualParam *> visual_param_index_map_t; + typedef std::map<char *, LLVisualParam *> visual_param_name_map_t; - visual_param_index_map_t::iterator mCurIterator; - visual_param_index_map_t mVisualParamIndexMap; - visual_param_name_map_t mVisualParamNameMap; + visual_param_index_map_t::iterator mCurIterator; + visual_param_index_map_t mVisualParamIndexMap; + visual_param_name_map_t mVisualParamNameMap; - static LLStringTable sVisualParamNames; + static LLStringTable sVisualParamNames; - LLVector3 mHoverOffset; + LLVector3 mHoverOffset; }; #endif // LL_LLCHARACTER_H diff --git a/indra/llcharacter/lleditingmotion.cpp b/indra/llcharacter/lleditingmotion.cpp index c5757163d9..b46f210d2b 100644 --- a/indra/llcharacter/lleditingmotion.cpp +++ b/indra/llcharacter/lleditingmotion.cpp @@ -1,25 +1,25 @@ -/** +/** * @file lleditingmotion.cpp * @brief Implementation of LLEditingMotion class. * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -38,7 +38,7 @@ // Constants //----------------------------------------------------------------------------- const LLQuaternion EDIT_MOTION_WRIST_ROTATION(F_PI_BY_TWO * 0.7f, LLVector3(1.0f, 0.0f, 0.0f)); -const F32 TARGET_LAG_HALF_LIFE = 0.1f; // half-life of IK targeting +const F32 TARGET_LAG_HALF_LIFE = 0.1f; // half-life of IK targeting S32 LLEditingMotion::sHandPose = LLHandMotion::HAND_POSE_RELAXED_R; S32 LLEditingMotion::sHandPosePriority = 3; @@ -49,20 +49,20 @@ S32 LLEditingMotion::sHandPosePriority = 3; //----------------------------------------------------------------------------- LLEditingMotion::LLEditingMotion( const LLUUID &id) : LLMotion(id) { - mCharacter = NULL; + mCharacter = NULL; - // create kinematic chain - mParentJoint.addChild( &mShoulderJoint ); - mShoulderJoint.addChild( &mElbowJoint ); - mElbowJoint.addChild( &mWristJoint ); + // create kinematic chain + mParentJoint.addChild( &mShoulderJoint ); + mShoulderJoint.addChild( &mElbowJoint ); + mElbowJoint.addChild( &mWristJoint ); - mName = "editing"; + mName = "editing"; - mParentState = new LLJointState; - mShoulderState = new LLJointState; - mElbowState = new LLJointState; - mWristState = new LLJointState; - mTorsoState = new LLJointState; + mParentState = new LLJointState; + mShoulderState = new LLJointState; + mElbowState = new LLJointState; + mWristState = new LLJointState; + mTorsoState = new LLJointState; } @@ -79,63 +79,63 @@ LLEditingMotion::~LLEditingMotion() //----------------------------------------------------------------------------- LLMotion::LLMotionInitStatus LLEditingMotion::onInitialize(LLCharacter *character) { - // save character for future use - mCharacter = character; - - // make sure character skeleton is copacetic - if (!mCharacter->getJoint("mShoulderLeft") || - !mCharacter->getJoint("mElbowLeft") || - !mCharacter->getJoint("mWristLeft")) - { - LL_WARNS() << "Invalid skeleton for editing motion!" << LL_ENDL; - return STATUS_FAILURE; - } - - // get the shoulder, elbow, wrist joints from the character - mParentState->setJoint( mCharacter->getJoint("mShoulderLeft")->getParent() ); - mShoulderState->setJoint( mCharacter->getJoint("mShoulderLeft") ); - mElbowState->setJoint( mCharacter->getJoint("mElbowLeft") ); - mWristState->setJoint( mCharacter->getJoint("mWristLeft") ); - mTorsoState->setJoint( mCharacter->getJoint("mTorso")); - - if ( ! mParentState->getJoint() ) - { - LL_INFOS() << getName() << ": Can't get parent joint." << LL_ENDL; - return STATUS_FAILURE; - } - - mWristOffset = LLVector3(0.0f, 0.2f, 0.0f); - - // add joint states to the pose - mShoulderState->setUsage(LLJointState::ROT); - mElbowState->setUsage(LLJointState::ROT); - mTorsoState->setUsage(LLJointState::ROT); - mWristState->setUsage(LLJointState::ROT); - addJointState( mShoulderState ); - addJointState( mElbowState ); - addJointState( mTorsoState ); - addJointState( mWristState ); - - // propagate joint positions to kinematic chain + // save character for future use + mCharacter = character; + + // make sure character skeleton is copacetic + if (!mCharacter->getJoint("mShoulderLeft") || + !mCharacter->getJoint("mElbowLeft") || + !mCharacter->getJoint("mWristLeft")) + { + LL_WARNS() << "Invalid skeleton for editing motion!" << LL_ENDL; + return STATUS_FAILURE; + } + + // get the shoulder, elbow, wrist joints from the character + mParentState->setJoint( mCharacter->getJoint("mShoulderLeft")->getParent() ); + mShoulderState->setJoint( mCharacter->getJoint("mShoulderLeft") ); + mElbowState->setJoint( mCharacter->getJoint("mElbowLeft") ); + mWristState->setJoint( mCharacter->getJoint("mWristLeft") ); + mTorsoState->setJoint( mCharacter->getJoint("mTorso")); + + if ( ! mParentState->getJoint() ) + { + LL_INFOS() << getName() << ": Can't get parent joint." << LL_ENDL; + return STATUS_FAILURE; + } + + mWristOffset = LLVector3(0.0f, 0.2f, 0.0f); + + // add joint states to the pose + mShoulderState->setUsage(LLJointState::ROT); + mElbowState->setUsage(LLJointState::ROT); + mTorsoState->setUsage(LLJointState::ROT); + mWristState->setUsage(LLJointState::ROT); + addJointState( mShoulderState ); + addJointState( mElbowState ); + addJointState( mTorsoState ); + addJointState( mWristState ); + + // propagate joint positions to kinematic chain // SL-315 - mParentJoint.setPosition( mParentState->getJoint()->getWorldPosition() ); - mShoulderJoint.setPosition( mShoulderState->getJoint()->getPosition() ); - mElbowJoint.setPosition( mElbowState->getJoint()->getPosition() ); - mWristJoint.setPosition( mWristState->getJoint()->getPosition() + mWristOffset ); - - // propagate current joint rotations to kinematic chain - mParentJoint.setRotation( mParentState->getJoint()->getWorldRotation() ); - mShoulderJoint.setRotation( mShoulderState->getJoint()->getRotation() ); - mElbowJoint.setRotation( mElbowState->getJoint()->getRotation() ); - - // connect the ikSolver to the chain - mIKSolver.setPoleVector( LLVector3( -1.0f, 1.0f, 0.0f ) ); - // specifying the elbow's axis will prevent bad IK for the more - // singular configurations, but the axis is limb-specific -- Leviathan - mIKSolver.setBAxis( LLVector3( -0.682683f, 0.0f, -0.730714f ) ); - mIKSolver.setupJoints( &mShoulderJoint, &mElbowJoint, &mWristJoint, &mTarget ); - - return STATUS_SUCCESS; + mParentJoint.setPosition( mParentState->getJoint()->getWorldPosition() ); + mShoulderJoint.setPosition( mShoulderState->getJoint()->getPosition() ); + mElbowJoint.setPosition( mElbowState->getJoint()->getPosition() ); + mWristJoint.setPosition( mWristState->getJoint()->getPosition() + mWristOffset ); + + // propagate current joint rotations to kinematic chain + mParentJoint.setRotation( mParentState->getJoint()->getWorldRotation() ); + mShoulderJoint.setRotation( mShoulderState->getJoint()->getRotation() ); + mElbowJoint.setRotation( mElbowState->getJoint()->getRotation() ); + + // connect the ikSolver to the chain + mIKSolver.setPoleVector( LLVector3( -1.0f, 1.0f, 0.0f ) ); + // specifying the elbow's axis will prevent bad IK for the more + // singular configurations, but the axis is limb-specific -- Leviathan + mIKSolver.setBAxis( LLVector3( -0.682683f, 0.0f, -0.730714f ) ); + mIKSolver.setupJoints( &mShoulderJoint, &mElbowJoint, &mWristJoint, &mTarget ); + + return STATUS_SUCCESS; } //----------------------------------------------------------------------------- @@ -143,19 +143,19 @@ LLMotion::LLMotionInitStatus LLEditingMotion::onInitialize(LLCharacter *characte //----------------------------------------------------------------------------- BOOL LLEditingMotion::onActivate() { - // propagate joint positions to kinematic chain + // propagate joint positions to kinematic chain // SL-315 - mParentJoint.setPosition( mParentState->getJoint()->getWorldPosition() ); - mShoulderJoint.setPosition( mShoulderState->getJoint()->getPosition() ); - mElbowJoint.setPosition( mElbowState->getJoint()->getPosition() ); - mWristJoint.setPosition( mWristState->getJoint()->getPosition() + mWristOffset ); + mParentJoint.setPosition( mParentState->getJoint()->getWorldPosition() ); + mShoulderJoint.setPosition( mShoulderState->getJoint()->getPosition() ); + mElbowJoint.setPosition( mElbowState->getJoint()->getPosition() ); + mWristJoint.setPosition( mWristState->getJoint()->getPosition() + mWristOffset ); - // propagate current joint rotations to kinematic chain - mParentJoint.setRotation( mParentState->getJoint()->getWorldRotation() ); - mShoulderJoint.setRotation( mShoulderState->getJoint()->getRotation() ); - mElbowJoint.setRotation( mElbowState->getJoint()->getRotation() ); + // propagate current joint rotations to kinematic chain + mParentJoint.setRotation( mParentState->getJoint()->getWorldRotation() ); + mShoulderJoint.setRotation( mShoulderState->getJoint()->getRotation() ); + mElbowJoint.setRotation( mElbowState->getJoint()->getRotation() ); - return TRUE; + return TRUE; } //----------------------------------------------------------------------------- @@ -164,92 +164,92 @@ BOOL LLEditingMotion::onActivate() BOOL LLEditingMotion::onUpdate(F32 time, U8* joint_mask) { LL_PROFILE_ZONE_SCOPED; - LLVector3 focus_pt; - LLVector3* pointAtPt = (LLVector3*)mCharacter->getAnimationData("PointAtPoint"); + LLVector3 focus_pt; + LLVector3* pointAtPt = (LLVector3*)mCharacter->getAnimationData("PointAtPoint"); - BOOL result = TRUE; + BOOL result = TRUE; - if (!pointAtPt) - { - focus_pt = mLastSelectPt; - result = FALSE; - } - else - { - focus_pt = *pointAtPt; - mLastSelectPt = focus_pt; - } + if (!pointAtPt) + { + focus_pt = mLastSelectPt; + result = FALSE; + } + else + { + focus_pt = *pointAtPt; + mLastSelectPt = focus_pt; + } - focus_pt += mCharacter->getCharacterPosition(); + focus_pt += mCharacter->getCharacterPosition(); - // propagate joint positions to kinematic chain + // propagate joint positions to kinematic chain // SL-315 - mParentJoint.setPosition( mParentState->getJoint()->getWorldPosition() ); - mShoulderJoint.setPosition( mShoulderState->getJoint()->getPosition() ); - mElbowJoint.setPosition( mElbowState->getJoint()->getPosition() ); - mWristJoint.setPosition( mWristState->getJoint()->getPosition() + mWristOffset ); - - // propagate current joint rotations to kinematic chain - mParentJoint.setRotation( mParentState->getJoint()->getWorldRotation() ); - mShoulderJoint.setRotation( mShoulderState->getJoint()->getRotation() ); - mElbowJoint.setRotation( mElbowState->getJoint()->getRotation() ); - - // update target position from character - LLVector3 target = focus_pt - mParentJoint.getPosition(); - F32 target_dist = target.normVec(); - - LLVector3 edit_plane_normal(1.f / F_SQRT2, 1.f / F_SQRT2, 0.f); - edit_plane_normal.normVec(); - - edit_plane_normal.rotVec(mTorsoState->getJoint()->getWorldRotation()); - - F32 dot = edit_plane_normal * target; - - if (dot < 0.f) - { - target = target + (edit_plane_normal * (dot * 2.f)); - target.mV[VZ] += clamp_rescale(dot, 0.f, -1.f, 0.f, 5.f); - target.normVec(); - } - - target = target * target_dist; - if (!target.isFinite()) - { - // Don't error out here, set a fail-safe target vector - LL_WARNS() << "Non finite target in editing motion with target distance of " << target_dist << - " and focus point " << focus_pt << LL_ENDL; - target.setVec(1.f, 1.f, 1.f); - } + mParentJoint.setPosition( mParentState->getJoint()->getWorldPosition() ); + mShoulderJoint.setPosition( mShoulderState->getJoint()->getPosition() ); + mElbowJoint.setPosition( mElbowState->getJoint()->getPosition() ); + mWristJoint.setPosition( mWristState->getJoint()->getPosition() + mWristOffset ); + + // propagate current joint rotations to kinematic chain + mParentJoint.setRotation( mParentState->getJoint()->getWorldRotation() ); + mShoulderJoint.setRotation( mShoulderState->getJoint()->getRotation() ); + mElbowJoint.setRotation( mElbowState->getJoint()->getRotation() ); + + // update target position from character + LLVector3 target = focus_pt - mParentJoint.getPosition(); + F32 target_dist = target.normVec(); + + LLVector3 edit_plane_normal(1.f / F_SQRT2, 1.f / F_SQRT2, 0.f); + edit_plane_normal.normVec(); + + edit_plane_normal.rotVec(mTorsoState->getJoint()->getWorldRotation()); + + F32 dot = edit_plane_normal * target; + + if (dot < 0.f) + { + target = target + (edit_plane_normal * (dot * 2.f)); + target.mV[VZ] += clamp_rescale(dot, 0.f, -1.f, 0.f, 5.f); + target.normVec(); + } + + target = target * target_dist; + if (!target.isFinite()) + { + // Don't error out here, set a fail-safe target vector + LL_WARNS() << "Non finite target in editing motion with target distance of " << target_dist << + " and focus point " << focus_pt << LL_ENDL; + target.setVec(1.f, 1.f, 1.f); + } // SL-315 - mTarget.setPosition( target + mParentJoint.getPosition()); - -// LL_INFOS() << "Point At: " << mTarget.getPosition() << LL_ENDL; - - // update the ikSolver - if (!mTarget.getPosition().isExactlyZero()) - { - LLQuaternion shoulderRot = mShoulderJoint.getRotation(); - LLQuaternion elbowRot = mElbowJoint.getRotation(); - mIKSolver.solve(); - - // use blending... - F32 slerp_amt = LLSmoothInterpolation::getInterpolant(TARGET_LAG_HALF_LIFE); - shoulderRot = slerp(slerp_amt, mShoulderJoint.getRotation(), shoulderRot); - elbowRot = slerp(slerp_amt, mElbowJoint.getRotation(), elbowRot); - - // now put blended values back into joints - llassert(shoulderRot.isFinite()); - llassert(elbowRot.isFinite()); - mShoulderState->setRotation(shoulderRot); - mElbowState->setRotation(elbowRot); - mWristState->setRotation(LLQuaternion::DEFAULT); - } - - mCharacter->setAnimationData("Hand Pose", &sHandPose); - mCharacter->setAnimationData("Hand Pose Priority", &sHandPosePriority); - return result; + mTarget.setPosition( target + mParentJoint.getPosition()); + +// LL_INFOS() << "Point At: " << mTarget.getPosition() << LL_ENDL; + + // update the ikSolver + if (!mTarget.getPosition().isExactlyZero()) + { + LLQuaternion shoulderRot = mShoulderJoint.getRotation(); + LLQuaternion elbowRot = mElbowJoint.getRotation(); + mIKSolver.solve(); + + // use blending... + F32 slerp_amt = LLSmoothInterpolation::getInterpolant(TARGET_LAG_HALF_LIFE); + shoulderRot = slerp(slerp_amt, mShoulderJoint.getRotation(), shoulderRot); + elbowRot = slerp(slerp_amt, mElbowJoint.getRotation(), elbowRot); + + // now put blended values back into joints + llassert(shoulderRot.isFinite()); + llassert(elbowRot.isFinite()); + mShoulderState->setRotation(shoulderRot); + mElbowState->setRotation(elbowRot); + mWristState->setRotation(LLQuaternion::DEFAULT); + } + + mCharacter->setAnimationData("Hand Pose", &sHandPose); + mCharacter->setAnimationData("Hand Pose Priority", &sHandPosePriority); + return result; } //----------------------------------------------------------------------------- diff --git a/indra/llcharacter/lleditingmotion.h b/indra/llcharacter/lleditingmotion.h index 80c1717a70..f8834ebdea 100644 --- a/indra/llcharacter/lleditingmotion.h +++ b/indra/llcharacter/lleditingmotion.h @@ -1,25 +1,25 @@ -/** +/** * @file lleditingmotion.h * @brief Implementation of LLEditingMotion class. * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -34,7 +34,7 @@ #include "lljointsolverrp3.h" #include "v3dmath.h" -#define EDITING_EASEIN_DURATION 0.0f +#define EDITING_EASEIN_DURATION 0.0f #define EDITING_EASEOUT_DURATION 0.5f #define EDITING_PRIORITY LLJoint::HIGH_PRIORITY #define MIN_REQUIRED_PIXEL_AREA_EDITING 500.f @@ -44,91 +44,91 @@ //----------------------------------------------------------------------------- LL_ALIGN_PREFIX(16) class LLEditingMotion : - public LLMotion + public LLMotion { LL_ALIGN_NEW public: - // Constructor - LLEditingMotion(const LLUUID &id); + // Constructor + LLEditingMotion(const LLUUID &id); - // Destructor - virtual ~LLEditingMotion(); + // Destructor + virtual ~LLEditingMotion(); public: - //------------------------------------------------------------------------- - // functions to support MotionController and MotionRegistry - //------------------------------------------------------------------------- + //------------------------------------------------------------------------- + // functions to support MotionController and MotionRegistry + //------------------------------------------------------------------------- - // static constructor - // all subclasses must implement such a function and register it - static LLMotion *create(const LLUUID &id) { return new LLEditingMotion(id); } + // static constructor + // all subclasses must implement such a function and register it + static LLMotion *create(const LLUUID &id) { return new LLEditingMotion(id); } public: - //------------------------------------------------------------------------- - // animation callbacks to be implemented by subclasses - //------------------------------------------------------------------------- + //------------------------------------------------------------------------- + // animation callbacks to be implemented by subclasses + //------------------------------------------------------------------------- - // motions must specify whether or not they loop - virtual BOOL getLoop() { return TRUE; } + // motions must specify whether or not they loop + virtual BOOL getLoop() { return TRUE; } - // motions must report their total duration - virtual F32 getDuration() { return 0.0; } + // motions must report their total duration + virtual F32 getDuration() { return 0.0; } - // motions must report their "ease in" duration - virtual F32 getEaseInDuration() { return EDITING_EASEIN_DURATION; } + // motions must report their "ease in" duration + virtual F32 getEaseInDuration() { return EDITING_EASEIN_DURATION; } - // motions must report their "ease out" duration. - virtual F32 getEaseOutDuration() { return EDITING_EASEOUT_DURATION; } + // motions must report their "ease out" duration. + virtual F32 getEaseOutDuration() { return EDITING_EASEOUT_DURATION; } - // motions must report their priority - virtual LLJoint::JointPriority getPriority() { return EDITING_PRIORITY; } + // motions must report their priority + virtual LLJoint::JointPriority getPriority() { return EDITING_PRIORITY; } - virtual LLMotionBlendType getBlendType() { return NORMAL_BLEND; } + virtual LLMotionBlendType getBlendType() { return NORMAL_BLEND; } - // called to determine when a motion should be activated/deactivated based on avatar pixel coverage - virtual F32 getMinPixelArea() { return MIN_REQUIRED_PIXEL_AREA_EDITING; } + // called to determine when a motion should be activated/deactivated based on avatar pixel coverage + virtual F32 getMinPixelArea() { return MIN_REQUIRED_PIXEL_AREA_EDITING; } - // run-time (post constructor) initialization, - // called after parameters have been set - // must return true to indicate success and be available for activation - virtual LLMotionInitStatus onInitialize(LLCharacter *character); + // run-time (post constructor) initialization, + // called after parameters have been set + // must return true to indicate success and be available for activation + virtual LLMotionInitStatus onInitialize(LLCharacter *character); - // called when a motion is activated - // must return TRUE to indicate success, or else - // it will be deactivated - virtual BOOL onActivate(); + // called when a motion is activated + // must return TRUE to indicate success, or else + // it will be deactivated + virtual BOOL onActivate(); - // called per time step - // must return TRUE while it is active, and - // must return FALSE when the motion is completed. - virtual BOOL onUpdate(F32 time, U8* joint_mask); + // called per time step + // must return TRUE while it is active, and + // must return FALSE when the motion is completed. + virtual BOOL onUpdate(F32 time, U8* joint_mask); - // called when a motion is deactivated - virtual void onDeactivate(); + // called when a motion is deactivated + virtual void onDeactivate(); public: - //------------------------------------------------------------------------- - // joint states to be animated - //------------------------------------------------------------------------- - LL_ALIGN_16(LLJoint mParentJoint); - LL_ALIGN_16(LLJoint mShoulderJoint); - LL_ALIGN_16(LLJoint mElbowJoint); - LL_ALIGN_16(LLJoint mWristJoint); - LL_ALIGN_16(LLJoint mTarget); - LLJointSolverRP3 mIKSolver; - - LLCharacter *mCharacter; - LLVector3 mWristOffset; - - LLPointer<LLJointState> mParentState; - LLPointer<LLJointState> mShoulderState; - LLPointer<LLJointState> mElbowState; - LLPointer<LLJointState> mWristState; - LLPointer<LLJointState> mTorsoState; - - static S32 sHandPose; - static S32 sHandPosePriority; - LLVector3 mLastSelectPt; + //------------------------------------------------------------------------- + // joint states to be animated + //------------------------------------------------------------------------- + LL_ALIGN_16(LLJoint mParentJoint); + LL_ALIGN_16(LLJoint mShoulderJoint); + LL_ALIGN_16(LLJoint mElbowJoint); + LL_ALIGN_16(LLJoint mWristJoint); + LL_ALIGN_16(LLJoint mTarget); + LLJointSolverRP3 mIKSolver; + + LLCharacter *mCharacter; + LLVector3 mWristOffset; + + LLPointer<LLJointState> mParentState; + LLPointer<LLJointState> mShoulderState; + LLPointer<LLJointState> mElbowState; + LLPointer<LLJointState> mWristState; + LLPointer<LLJointState> mTorsoState; + + static S32 sHandPose; + static S32 sHandPosePriority; + LLVector3 mLastSelectPt; } LL_ALIGN_POSTFIX(16); #endif // LL_LLKEYFRAMEMOTION_H diff --git a/indra/llcharacter/llgesture.cpp b/indra/llcharacter/llgesture.cpp index 80717d8d26..8533605c2d 100644 --- a/indra/llcharacter/llgesture.cpp +++ b/indra/llcharacter/llgesture.cpp @@ -1,24 +1,24 @@ -/** +/** * @file llgesture.cpp * * $LicenseInfo:firstyear=2002&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -37,134 +37,134 @@ const S32 LLGestureList::SERIAL_HEADER_SIZE = sizeof(S32); const S32 LLGesture::MAX_SERIAL_SIZE = sizeof(KEY) + sizeof(MASK) + 16 + 26 + 41 + 41; LLGesture::LLGesture() -: mKey(KEY_NONE), - mMask(MASK_NONE), - mTrigger(), - mTriggerLower(), - mSoundItemID(), - mAnimation(), - mOutputString() +: mKey(KEY_NONE), + mMask(MASK_NONE), + mTrigger(), + mTriggerLower(), + mSoundItemID(), + mAnimation(), + mOutputString() { } LLGesture::LLGesture(KEY key, MASK mask, const std::string &trigger, - const LLUUID &sound_item_id, - const std::string &animation, - const std::string &output_string) + const LLUUID &sound_item_id, + const std::string &animation, + const std::string &output_string) : - mKey(key), - mMask(mask), - mTrigger(trigger), - mTriggerLower(trigger), - mSoundItemID(sound_item_id), - mAnimation(animation), - mOutputString(output_string) + mKey(key), + mMask(mask), + mTrigger(trigger), + mTriggerLower(trigger), + mSoundItemID(sound_item_id), + mAnimation(animation), + mOutputString(output_string) { - mTriggerLower = utf8str_tolower(mTriggerLower); + mTriggerLower = utf8str_tolower(mTriggerLower); } LLGesture::LLGesture(U8 **buffer, S32 max_size) { - *buffer = deserialize(*buffer, max_size); + *buffer = deserialize(*buffer, max_size); } LLGesture::LLGesture(const LLGesture &rhs) { - mKey = rhs.mKey; - mMask = rhs.mMask; - mTrigger = rhs.mTrigger; - mTriggerLower = rhs.mTriggerLower; - mSoundItemID = rhs.mSoundItemID; - mAnimation = rhs.mAnimation; - mOutputString = rhs.mOutputString; + mKey = rhs.mKey; + mMask = rhs.mMask; + mTrigger = rhs.mTrigger; + mTriggerLower = rhs.mTriggerLower; + mSoundItemID = rhs.mSoundItemID; + mAnimation = rhs.mAnimation; + mOutputString = rhs.mOutputString; } const LLGesture &LLGesture::operator =(const LLGesture &rhs) { - mKey = rhs.mKey; - mMask = rhs.mMask; - mTrigger = rhs.mTrigger; - mTriggerLower = rhs.mTriggerLower; - mSoundItemID = rhs.mSoundItemID; - mAnimation = rhs.mAnimation; - mOutputString = rhs.mOutputString; - return (*this); + mKey = rhs.mKey; + mMask = rhs.mMask; + mTrigger = rhs.mTrigger; + mTriggerLower = rhs.mTriggerLower; + mSoundItemID = rhs.mSoundItemID; + mAnimation = rhs.mAnimation; + mOutputString = rhs.mOutputString; + return (*this); } BOOL LLGesture::trigger(KEY key, MASK mask) { - LL_WARNS() << "Parent class trigger called: you probably didn't mean this." << LL_ENDL; - return FALSE; + LL_WARNS() << "Parent class trigger called: you probably didn't mean this." << LL_ENDL; + return FALSE; } BOOL LLGesture::trigger(const std::string& trigger_string) { - LL_WARNS() << "Parent class trigger called: you probably didn't mean this." << LL_ENDL; - return FALSE; + LL_WARNS() << "Parent class trigger called: you probably didn't mean this." << LL_ENDL; + return FALSE; } // NOT endian-neutral U8 *LLGesture::serialize(U8 *buffer) const { - htolememcpy(buffer, &mKey, MVT_S8, 1); - buffer += sizeof(mKey); - htolememcpy(buffer, &mMask, MVT_U32, 4); - buffer += sizeof(mMask); - htolememcpy(buffer, mSoundItemID.mData, MVT_LLUUID, 16); - buffer += 16; - - memcpy(buffer, mTrigger.c_str(), mTrigger.length() + 1); /* Flawfinder: ignore */ - buffer += mTrigger.length() + 1; - memcpy(buffer, mAnimation.c_str(), mAnimation.length() + 1); /* Flawfinder: ignore */ - buffer += mAnimation.length() + 1; - memcpy(buffer, mOutputString.c_str(), mOutputString.length() + 1); /* Flawfinder: ignore */ - buffer += mOutputString.length() + 1; - - return buffer; + htolememcpy(buffer, &mKey, MVT_S8, 1); + buffer += sizeof(mKey); + htolememcpy(buffer, &mMask, MVT_U32, 4); + buffer += sizeof(mMask); + htolememcpy(buffer, mSoundItemID.mData, MVT_LLUUID, 16); + buffer += 16; + + memcpy(buffer, mTrigger.c_str(), mTrigger.length() + 1); /* Flawfinder: ignore */ + buffer += mTrigger.length() + 1; + memcpy(buffer, mAnimation.c_str(), mAnimation.length() + 1); /* Flawfinder: ignore */ + buffer += mAnimation.length() + 1; + memcpy(buffer, mOutputString.c_str(), mOutputString.length() + 1); /* Flawfinder: ignore */ + buffer += mOutputString.length() + 1; + + return buffer; } U8 *LLGesture::deserialize(U8 *buffer, S32 max_size) { - U8 *tmp = buffer; - - if (tmp + sizeof(mKey) + sizeof(mMask) + 16 > buffer + max_size) - { - LL_WARNS() << "Attempt to read past end of buffer, bad data!!!!" << LL_ENDL; - return buffer; - } - - htolememcpy(&mKey, tmp, MVT_S8, 1); - tmp += sizeof(mKey); - htolememcpy(&mMask, tmp, MVT_U32, 4); - tmp += sizeof(mMask); - htolememcpy(mSoundItemID.mData, tmp, MVT_LLUUID, 16); - tmp += 16; - - mTrigger.assign((char *)tmp); - mTriggerLower = mTrigger; - mTriggerLower = utf8str_tolower(mTriggerLower); - tmp += mTrigger.length() + 1; - mAnimation.assign((char *)tmp); - //RN: force animation names to lower case - // must do this for backwards compatibility - mAnimation = utf8str_tolower(mAnimation); - tmp += mAnimation.length() + 1; - mOutputString.assign((char *)tmp); - tmp += mOutputString.length() + 1; - - if (tmp > buffer + max_size) - { - LL_WARNS() << "Read past end of buffer, bad data!!!!" << LL_ENDL; - return tmp; - } - - return tmp; + U8 *tmp = buffer; + + if (tmp + sizeof(mKey) + sizeof(mMask) + 16 > buffer + max_size) + { + LL_WARNS() << "Attempt to read past end of buffer, bad data!!!!" << LL_ENDL; + return buffer; + } + + htolememcpy(&mKey, tmp, MVT_S8, 1); + tmp += sizeof(mKey); + htolememcpy(&mMask, tmp, MVT_U32, 4); + tmp += sizeof(mMask); + htolememcpy(mSoundItemID.mData, tmp, MVT_LLUUID, 16); + tmp += 16; + + mTrigger.assign((char *)tmp); + mTriggerLower = mTrigger; + mTriggerLower = utf8str_tolower(mTriggerLower); + tmp += mTrigger.length() + 1; + mAnimation.assign((char *)tmp); + //RN: force animation names to lower case + // must do this for backwards compatibility + mAnimation = utf8str_tolower(mAnimation); + tmp += mAnimation.length() + 1; + mOutputString.assign((char *)tmp); + tmp += mOutputString.length() + 1; + + if (tmp > buffer + max_size) + { + LL_WARNS() << "Read past end of buffer, bad data!!!!" << LL_ENDL; + return tmp; + } + + return tmp; } S32 LLGesture::getMaxSerialSize() { - return MAX_SERIAL_SIZE; + return MAX_SERIAL_SIZE; } //--------------------------------------------------------------------- @@ -172,18 +172,18 @@ S32 LLGesture::getMaxSerialSize() //--------------------------------------------------------------------- LLGestureList::LLGestureList() -: mList(0) +: mList(0) {} LLGestureList::~LLGestureList() { - deleteAll(); + deleteAll(); } void LLGestureList::deleteAll() { - delete_and_clear(mList); + delete_and_clear(mList); } // Iterates through space delimited tokens in string, triggering any gestures found. @@ -191,147 +191,147 @@ void LLGestureList::deleteAll() // and (as a minor side effect) has multiple spaces in a row replaced by single spaces. BOOL LLGestureList::triggerAndReviseString(const std::string &string, std::string* revised_string) { - std::string tokenized = string; - - BOOL found_gestures = FALSE; - BOOL first_token = TRUE; - - typedef boost::tokenizer<boost::char_separator<char> > tokenizer; - boost::char_separator<char> sep(" "); - tokenizer tokens(string, sep); - - for(const std::string& cur_token : tokens) - { - LLGesture* gesture = NULL; - - if( !found_gestures ) // Only pay attention to the first gesture in the string. - { - std::string cur_token_lower = cur_token; - LLStringUtil::toLower(cur_token_lower); - - for (U32 i = 0; i < mList.size(); i++) - { - gesture = mList.at(i); - if (gesture->trigger(cur_token_lower)) - { - if( !gesture->getOutputString().empty() ) - { - if( !first_token ) - { - revised_string->append( " " ); - } - - // Don't muck with the user's capitalization if we don't have to. - const std::string& output = gesture->getOutputString(); - std::string output_lower = std::string(output.c_str()); - LLStringUtil::toLower(output_lower); - if( cur_token_lower == output_lower ) - { - revised_string->append(cur_token); - } - else - { - revised_string->append(output); - } - - } - found_gestures = TRUE; - break; - } - gesture = NULL; - } - } - - if( !gesture ) - { - if( !first_token ) - { - revised_string->append( " " ); - } - revised_string->append( cur_token ); - } - - first_token = FALSE; - } - return found_gestures; + std::string tokenized = string; + + BOOL found_gestures = FALSE; + BOOL first_token = TRUE; + + typedef boost::tokenizer<boost::char_separator<char> > tokenizer; + boost::char_separator<char> sep(" "); + tokenizer tokens(string, sep); + + for(const std::string& cur_token : tokens) + { + LLGesture* gesture = NULL; + + if( !found_gestures ) // Only pay attention to the first gesture in the string. + { + std::string cur_token_lower = cur_token; + LLStringUtil::toLower(cur_token_lower); + + for (U32 i = 0; i < mList.size(); i++) + { + gesture = mList.at(i); + if (gesture->trigger(cur_token_lower)) + { + if( !gesture->getOutputString().empty() ) + { + if( !first_token ) + { + revised_string->append( " " ); + } + + // Don't muck with the user's capitalization if we don't have to. + const std::string& output = gesture->getOutputString(); + std::string output_lower = std::string(output.c_str()); + LLStringUtil::toLower(output_lower); + if( cur_token_lower == output_lower ) + { + revised_string->append(cur_token); + } + else + { + revised_string->append(output); + } + + } + found_gestures = TRUE; + break; + } + gesture = NULL; + } + } + + if( !gesture ) + { + if( !first_token ) + { + revised_string->append( " " ); + } + revised_string->append( cur_token ); + } + + first_token = FALSE; + } + return found_gestures; } BOOL LLGestureList::trigger(KEY key, MASK mask) { - for (U32 i = 0; i < mList.size(); i++) - { - LLGesture* gesture = mList.at(i); - if( gesture ) - { - if (gesture->trigger(key, mask)) - { - return TRUE; - } - } - else - { - LL_WARNS() << "NULL gesture in gesture list (" << i << ")" << LL_ENDL; - } - } - return FALSE; + for (U32 i = 0; i < mList.size(); i++) + { + LLGesture* gesture = mList.at(i); + if( gesture ) + { + if (gesture->trigger(key, mask)) + { + return TRUE; + } + } + else + { + LL_WARNS() << "NULL gesture in gesture list (" << i << ")" << LL_ENDL; + } + } + return FALSE; } // NOT endian-neutral U8 *LLGestureList::serialize(U8 *buffer) const { - // a single S32 serves as the header that tells us how many to read - U32 count = mList.size(); - htolememcpy(buffer, &count, MVT_S32, 4); - buffer += sizeof(count); + // a single S32 serves as the header that tells us how many to read + U32 count = mList.size(); + htolememcpy(buffer, &count, MVT_S32, 4); + buffer += sizeof(count); - for (S32 i = 0; i < count; i++) - { - buffer = mList[i]->serialize(buffer); - } + for (S32 i = 0; i < count; i++) + { + buffer = mList[i]->serialize(buffer); + } - return buffer; + return buffer; } const S32 MAX_GESTURES = 4096; U8 *LLGestureList::deserialize(U8 *buffer, S32 max_size) { - deleteAll(); + deleteAll(); - S32 count; - U8 *tmp = buffer; + S32 count; + U8 *tmp = buffer; - if (tmp + sizeof(count) > buffer + max_size) - { - LL_WARNS() << "Invalid max_size" << LL_ENDL; - return buffer; - } + if (tmp + sizeof(count) > buffer + max_size) + { + LL_WARNS() << "Invalid max_size" << LL_ENDL; + return buffer; + } - htolememcpy(&count, tmp, MVT_S32, 4); + htolememcpy(&count, tmp, MVT_S32, 4); - if (count > MAX_GESTURES) - { - LL_WARNS() << "Unreasonably large gesture list count in deserialize: " << count << LL_ENDL; - return tmp; - } + if (count > MAX_GESTURES) + { + LL_WARNS() << "Unreasonably large gesture list count in deserialize: " << count << LL_ENDL; + return tmp; + } - tmp += sizeof(count); + tmp += sizeof(count); - mList.resize(count); + mList.resize(count); - for (S32 i = 0; i < count; i++) - { - mList[i] = create_gesture(&tmp, max_size - (S32)(tmp - buffer)); - if (tmp - buffer > max_size) - { - LL_WARNS() << "Deserialization read past end of buffer, bad data!!!!" << LL_ENDL; - return tmp; - } - } + for (S32 i = 0; i < count; i++) + { + mList[i] = create_gesture(&tmp, max_size - (S32)(tmp - buffer)); + if (tmp - buffer > max_size) + { + LL_WARNS() << "Deserialization read past end of buffer, bad data!!!!" << LL_ENDL; + return tmp; + } + } - return tmp; + return tmp; } // this is a helper for deserialize @@ -339,10 +339,10 @@ U8 *LLGestureList::deserialize(U8 *buffer, S32 max_size) // overridden by child class to use local LLGesture implementation LLGesture *LLGestureList::create_gesture(U8 **buffer, S32 max_size) { - return new LLGesture(buffer, max_size); + return new LLGesture(buffer, max_size); } S32 LLGestureList::getMaxSerialSize() { - return SERIAL_HEADER_SIZE + (count() * LLGesture::getMaxSerialSize()); + return SERIAL_HEADER_SIZE + (count() * LLGesture::getMaxSerialSize()); } diff --git a/indra/llcharacter/llgesture.h b/indra/llcharacter/llgesture.h index cfb489f727..4e7fb6d1cc 100644 --- a/indra/llcharacter/llgesture.h +++ b/indra/llcharacter/llgesture.h @@ -1,4 +1,4 @@ -/** +/** * @file llgesture.h * @brief A gesture is a combination of a triggering chat phrase or * key, a sound, an animation, and a chat string. @@ -6,21 +6,21 @@ * $LicenseInfo:firstyear=2002&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -35,79 +35,79 @@ class LLGesture { public: - LLGesture(); - LLGesture(KEY key, MASK mask, const std::string &trigger, - const LLUUID &sound_item_id, const std::string &animation, - const std::string &output_string); + LLGesture(); + LLGesture(KEY key, MASK mask, const std::string &trigger, + const LLUUID &sound_item_id, const std::string &animation, + const std::string &output_string); - LLGesture(U8 **buffer, S32 max_size); // deserializes, advances buffer - LLGesture(const LLGesture &gesture); - const LLGesture &operator=(const LLGesture &rhs); + LLGesture(U8 **buffer, S32 max_size); // deserializes, advances buffer + LLGesture(const LLGesture &gesture); + const LLGesture &operator=(const LLGesture &rhs); - virtual ~LLGesture() {}; + virtual ~LLGesture() {}; - // Accessors - KEY getKey() const { return mKey; } - MASK getMask() const { return mMask; } - const std::string& getTrigger() const { return mTrigger; } - const LLUUID& getSound() const { return mSoundItemID; } - const std::string& getAnimation() const { return mAnimation; } - const std::string& getOutputString() const { return mOutputString; } + // Accessors + KEY getKey() const { return mKey; } + MASK getMask() const { return mMask; } + const std::string& getTrigger() const { return mTrigger; } + const LLUUID& getSound() const { return mSoundItemID; } + const std::string& getAnimation() const { return mAnimation; } + const std::string& getOutputString() const { return mOutputString; } - // Triggers if a key/mask matches it - virtual BOOL trigger(KEY key, MASK mask); + // Triggers if a key/mask matches it + virtual BOOL trigger(KEY key, MASK mask); - // Triggers if case-insensitive substring matches (assumes string is lowercase) - virtual BOOL trigger(const std::string &string); + // Triggers if case-insensitive substring matches (assumes string is lowercase) + virtual BOOL trigger(const std::string &string); - // non-endian-neutral serialization - U8 *serialize(U8 *buffer) const; - U8 *deserialize(U8 *buffer, S32 max_size); - static S32 getMaxSerialSize(); + // non-endian-neutral serialization + U8 *serialize(U8 *buffer) const; + U8 *deserialize(U8 *buffer, S32 max_size); + static S32 getMaxSerialSize(); protected: - KEY mKey; // usually a function key - MASK mMask; // usually MASK_NONE, or MASK_SHIFT - std::string mTrigger; // string, no whitespace allowed - std::string mTriggerLower; // lowercase version of mTrigger - LLUUID mSoundItemID; // ItemID of sound to play, LLUUID::null if none - std::string mAnimation; // canonical name of animation or face animation - std::string mOutputString; // string to say - - static const S32 MAX_SERIAL_SIZE; + KEY mKey; // usually a function key + MASK mMask; // usually MASK_NONE, or MASK_SHIFT + std::string mTrigger; // string, no whitespace allowed + std::string mTriggerLower; // lowercase version of mTrigger + LLUUID mSoundItemID; // ItemID of sound to play, LLUUID::null if none + std::string mAnimation; // canonical name of animation or face animation + std::string mOutputString; // string to say + + static const S32 MAX_SERIAL_SIZE; }; class LLGestureList { public: - LLGestureList(); - virtual ~LLGestureList(); + LLGestureList(); + virtual ~LLGestureList(); - // Triggers if a key/mask matches one in the list - BOOL trigger(KEY key, MASK mask); + // Triggers if a key/mask matches one in the list + BOOL trigger(KEY key, MASK mask); - // Triggers if substring matches and generates revised string. - BOOL triggerAndReviseString(const std::string &string, std::string* revised_string); + // Triggers if substring matches and generates revised string. + BOOL triggerAndReviseString(const std::string &string, std::string* revised_string); - // Used for construction from UI - S32 count() const { return mList.size(); } - virtual LLGesture* get(S32 i) const { return mList.at(i); } - virtual void put(LLGesture* gesture) { mList.push_back( gesture ); } - void deleteAll(); + // Used for construction from UI + S32 count() const { return mList.size(); } + virtual LLGesture* get(S32 i) const { return mList.at(i); } + virtual void put(LLGesture* gesture) { mList.push_back( gesture ); } + void deleteAll(); - // non-endian-neutral serialization - U8 *serialize(U8 *buffer) const; - U8 *deserialize(U8 *buffer, S32 max_size); - S32 getMaxSerialSize(); + // non-endian-neutral serialization + U8 *serialize(U8 *buffer) const; + U8 *deserialize(U8 *buffer, S32 max_size); + S32 getMaxSerialSize(); protected: - // overridden by child class to use local LLGesture implementation - virtual LLGesture *create_gesture(U8 **buffer, S32 max_size); + // overridden by child class to use local LLGesture implementation + virtual LLGesture *create_gesture(U8 **buffer, S32 max_size); protected: - std::vector<LLGesture*> mList; + std::vector<LLGesture*> mList; - static const S32 SERIAL_HEADER_SIZE; + static const S32 SERIAL_HEADER_SIZE; }; #endif diff --git a/indra/llcharacter/llhandmotion.cpp b/indra/llcharacter/llhandmotion.cpp index ceba956214..5fc98a4b4d 100644 --- a/indra/llcharacter/llhandmotion.cpp +++ b/indra/llcharacter/llhandmotion.cpp @@ -1,25 +1,25 @@ -/** +/** * @file llhandmotion.cpp * @brief Implementation of LLHandMotion class. * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -39,20 +39,20 @@ const char *gHandPoseNames[LLHandMotion::NUM_HAND_POSES] = /* Flawfinder: ignore */ { - "", - "Hands_Relaxed", - "Hands_Point", - "Hands_Fist", - "Hands_Relaxed_L", - "Hands_Point_L", - "Hands_Fist_L", - "Hands_Relaxed_R", - "Hands_Point_R", - "Hands_Fist_R", - "Hands_Salute_R", - "Hands_Typing", - "Hands_Peace_R", - "Hands_Spread_R" + "", + "Hands_Relaxed", + "Hands_Point", + "Hands_Fist", + "Hands_Relaxed_L", + "Hands_Point_L", + "Hands_Fist_L", + "Hands_Relaxed_R", + "Hands_Point_R", + "Hands_Fist_R", + "Hands_Salute_R", + "Hands_Typing", + "Hands_Peace_R", + "Hands_Spread_R" }; const F32 HAND_MORPH_BLEND_TIME = 0.2f; @@ -63,16 +63,16 @@ const F32 HAND_MORPH_BLEND_TIME = 0.2f; //----------------------------------------------------------------------------- LLHandMotion::LLHandMotion(const LLUUID &id) : LLMotion(id) { - mCharacter = NULL; - mLastTime = 0.f; - mCurrentPose = HAND_POSE_RELAXED; - mNewPose = HAND_POSE_RELAXED; - mName = "hand_motion"; - - //RN: flag hand joint as highest priority for now, until we implement a proper animation track - mJointSignature[0][LL_HAND_JOINT_NUM] = 0xff; - mJointSignature[1][LL_HAND_JOINT_NUM] = 0xff; - mJointSignature[2][LL_HAND_JOINT_NUM] = 0xff; + mCharacter = NULL; + mLastTime = 0.f; + mCurrentPose = HAND_POSE_RELAXED; + mNewPose = HAND_POSE_RELAXED; + mName = "hand_motion"; + + //RN: flag hand joint as highest priority for now, until we implement a proper animation track + mJointSignature[0][LL_HAND_JOINT_NUM] = 0xff; + mJointSignature[1][LL_HAND_JOINT_NUM] = 0xff; + mJointSignature[2][LL_HAND_JOINT_NUM] = 0xff; } @@ -89,9 +89,9 @@ LLHandMotion::~LLHandMotion() //----------------------------------------------------------------------------- LLMotion::LLMotionInitStatus LLHandMotion::onInitialize(LLCharacter *character) { - mCharacter = character; + mCharacter = character; - return STATUS_SUCCESS; + return STATUS_SUCCESS; } @@ -100,19 +100,19 @@ LLMotion::LLMotionInitStatus LLHandMotion::onInitialize(LLCharacter *character) //----------------------------------------------------------------------------- BOOL LLHandMotion::onActivate() { - LLPolyMesh *upperBodyMesh = mCharacter->getUpperBodyMesh(); - - if (upperBodyMesh) - { - // Note: 0 is the default - for (S32 i = 1; i < LLHandMotion::NUM_HAND_POSES; i++) - { - mCharacter->setVisualParamWeight(gHandPoseNames[i], 0.f); - } - mCharacter->setVisualParamWeight(gHandPoseNames[mCurrentPose], 1.f); - mCharacter->updateVisualParams(); - } - return TRUE; + LLPolyMesh *upperBodyMesh = mCharacter->getUpperBodyMesh(); + + if (upperBodyMesh) + { + // Note: 0 is the default + for (S32 i = 1; i < LLHandMotion::NUM_HAND_POSES; i++) + { + mCharacter->setVisualParamWeight(gHandPoseNames[i], 0.f); + } + mCharacter->setVisualParamWeight(gHandPoseNames[mCurrentPose], 1.f); + mCharacter->updateVisualParams(); + } + return TRUE; } @@ -122,118 +122,118 @@ BOOL LLHandMotion::onActivate() BOOL LLHandMotion::onUpdate(F32 time, U8* joint_mask) { LL_PROFILE_ZONE_SCOPED; - eHandPose *requestedHandPose; - - F32 timeDelta = time - mLastTime; - mLastTime = time; - - requestedHandPose = (eHandPose *)mCharacter->getAnimationData("Hand Pose"); - // check to see if requested pose has changed - if (!requestedHandPose) - { - if (mNewPose != HAND_POSE_RELAXED && mNewPose != mCurrentPose) - { - // Only set param weight for poses other than - // default (HAND_POSE_SPREAD); HAND_POSE_SPREAD - // is not an animatable morph! - if (mNewPose != HAND_POSE_SPREAD) - { - mCharacter->setVisualParamWeight(gHandPoseNames[mNewPose], 0.f); - } - - // Reset morph weight for current pose back to its - // full extend or it might be stuck somewhere in the middle if a - // pose is requested and the old pose is requested again shortly - // after while still blending to the other pose! - if (mCurrentPose != HAND_POSE_SPREAD) - { - mCharacter->setVisualParamWeight(gHandPoseNames[mCurrentPose], 1.f); - } - - // Update visual params now if we won't blend - if (mCurrentPose == HAND_POSE_RELAXED) - { - mCharacter->updateVisualParams(); - } - } - mNewPose = HAND_POSE_RELAXED; - } - else - { - // Sometimes we seem to get garbage here, with poses that are out of bounds. - // So check for a valid pose first. - if (*requestedHandPose >= 0 && *requestedHandPose < NUM_HAND_POSES) - { - // This is a new morph we didn't know about before: - // Reset morph weight for both current and new pose - // back their starting values while still blending. - if (*requestedHandPose != mNewPose && mNewPose != mCurrentPose) - { - if (mNewPose != HAND_POSE_SPREAD) - { - mCharacter->setVisualParamWeight(gHandPoseNames[mNewPose], 0.f); - } - - // Reset morph weight for current pose back to its full extend - // or it might be stuck somewhere in the middle if a pose is - // requested and the old pose is requested again shortly after - // while still blending to the other pose! - if (mCurrentPose != HAND_POSE_SPREAD) - { - mCharacter->setVisualParamWeight(gHandPoseNames[mCurrentPose], 1.f); - } - - // Update visual params now if we won't blend - if (mCurrentPose == *requestedHandPose) - { - mCharacter->updateVisualParams(); - } - } - mNewPose = *requestedHandPose; - } - else - { - LL_WARNS() << "Requested hand pose out of range. Ignoring requested pose." << LL_ENDL; - } - } - - mCharacter->removeAnimationData("Hand Pose"); - mCharacter->removeAnimationData("Hand Pose Priority"); - -// if (requestedHandPose) -// LL_INFOS() << "Hand Pose " << *requestedHandPose << LL_ENDL; - - // if we are still blending... - if (mCurrentPose != mNewPose) - { - F32 incomingWeight = 1.f; - F32 outgoingWeight = 0.f; - - if (mNewPose != HAND_POSE_SPREAD) - { - incomingWeight = mCharacter->getVisualParamWeight(gHandPoseNames[mNewPose]); - incomingWeight += (timeDelta / HAND_MORPH_BLEND_TIME); - incomingWeight = llclamp(incomingWeight, 0.f, 1.f); - mCharacter->setVisualParamWeight(gHandPoseNames[mNewPose], incomingWeight); - } - - if (mCurrentPose != HAND_POSE_SPREAD) - { - outgoingWeight = mCharacter->getVisualParamWeight(gHandPoseNames[mCurrentPose]); - outgoingWeight -= (timeDelta / HAND_MORPH_BLEND_TIME); - outgoingWeight = llclamp(outgoingWeight, 0.f, 1.f); - mCharacter->setVisualParamWeight(gHandPoseNames[mCurrentPose], outgoingWeight); - } - - mCharacter->updateVisualParams(); - - if (incomingWeight == 1.f && outgoingWeight == 0.f) - { - mCurrentPose = mNewPose; - } - } - - return TRUE; + eHandPose *requestedHandPose; + + F32 timeDelta = time - mLastTime; + mLastTime = time; + + requestedHandPose = (eHandPose *)mCharacter->getAnimationData("Hand Pose"); + // check to see if requested pose has changed + if (!requestedHandPose) + { + if (mNewPose != HAND_POSE_RELAXED && mNewPose != mCurrentPose) + { + // Only set param weight for poses other than + // default (HAND_POSE_SPREAD); HAND_POSE_SPREAD + // is not an animatable morph! + if (mNewPose != HAND_POSE_SPREAD) + { + mCharacter->setVisualParamWeight(gHandPoseNames[mNewPose], 0.f); + } + + // Reset morph weight for current pose back to its + // full extend or it might be stuck somewhere in the middle if a + // pose is requested and the old pose is requested again shortly + // after while still blending to the other pose! + if (mCurrentPose != HAND_POSE_SPREAD) + { + mCharacter->setVisualParamWeight(gHandPoseNames[mCurrentPose], 1.f); + } + + // Update visual params now if we won't blend + if (mCurrentPose == HAND_POSE_RELAXED) + { + mCharacter->updateVisualParams(); + } + } + mNewPose = HAND_POSE_RELAXED; + } + else + { + // Sometimes we seem to get garbage here, with poses that are out of bounds. + // So check for a valid pose first. + if (*requestedHandPose >= 0 && *requestedHandPose < NUM_HAND_POSES) + { + // This is a new morph we didn't know about before: + // Reset morph weight for both current and new pose + // back their starting values while still blending. + if (*requestedHandPose != mNewPose && mNewPose != mCurrentPose) + { + if (mNewPose != HAND_POSE_SPREAD) + { + mCharacter->setVisualParamWeight(gHandPoseNames[mNewPose], 0.f); + } + + // Reset morph weight for current pose back to its full extend + // or it might be stuck somewhere in the middle if a pose is + // requested and the old pose is requested again shortly after + // while still blending to the other pose! + if (mCurrentPose != HAND_POSE_SPREAD) + { + mCharacter->setVisualParamWeight(gHandPoseNames[mCurrentPose], 1.f); + } + + // Update visual params now if we won't blend + if (mCurrentPose == *requestedHandPose) + { + mCharacter->updateVisualParams(); + } + } + mNewPose = *requestedHandPose; + } + else + { + LL_WARNS() << "Requested hand pose out of range. Ignoring requested pose." << LL_ENDL; + } + } + + mCharacter->removeAnimationData("Hand Pose"); + mCharacter->removeAnimationData("Hand Pose Priority"); + +// if (requestedHandPose) +// LL_INFOS() << "Hand Pose " << *requestedHandPose << LL_ENDL; + + // if we are still blending... + if (mCurrentPose != mNewPose) + { + F32 incomingWeight = 1.f; + F32 outgoingWeight = 0.f; + + if (mNewPose != HAND_POSE_SPREAD) + { + incomingWeight = mCharacter->getVisualParamWeight(gHandPoseNames[mNewPose]); + incomingWeight += (timeDelta / HAND_MORPH_BLEND_TIME); + incomingWeight = llclamp(incomingWeight, 0.f, 1.f); + mCharacter->setVisualParamWeight(gHandPoseNames[mNewPose], incomingWeight); + } + + if (mCurrentPose != HAND_POSE_SPREAD) + { + outgoingWeight = mCharacter->getVisualParamWeight(gHandPoseNames[mCurrentPose]); + outgoingWeight -= (timeDelta / HAND_MORPH_BLEND_TIME); + outgoingWeight = llclamp(outgoingWeight, 0.f, 1.f); + mCharacter->setVisualParamWeight(gHandPoseNames[mCurrentPose], outgoingWeight); + } + + mCharacter->updateVisualParams(); + + if (incomingWeight == 1.f && outgoingWeight == 0.f) + { + mCurrentPose = mNewPose; + } + } + + return TRUE; } @@ -249,23 +249,23 @@ void LLHandMotion::onDeactivate() //----------------------------------------------------------------------------- std::string LLHandMotion::getHandPoseName(eHandPose pose) { - if ((S32)pose < LLHandMotion::NUM_HAND_POSES && (S32)pose >= 0) - { - return std::string(gHandPoseNames[pose]); - } - return LLStringUtil::null; + if ((S32)pose < LLHandMotion::NUM_HAND_POSES && (S32)pose >= 0) + { + return std::string(gHandPoseNames[pose]); + } + return LLStringUtil::null; } LLHandMotion::eHandPose LLHandMotion::getHandPose(std::string posename) { - for (S32 pose = 0; pose < LLHandMotion::NUM_HAND_POSES; ++pose) - { - if (gHandPoseNames[pose] == posename) - { - return (eHandPose)pose; - } - } - return (eHandPose)0; + for (S32 pose = 0; pose < LLHandMotion::NUM_HAND_POSES; ++pose) + { + if (gHandPoseNames[pose] == posename) + { + return (eHandPose)pose; + } + } + return (eHandPose)0; } // End diff --git a/indra/llcharacter/llhandmotion.h b/indra/llcharacter/llhandmotion.h index 08de7056c8..a88a2aa85a 100644 --- a/indra/llcharacter/llhandmotion.h +++ b/indra/llcharacter/llhandmotion.h @@ -1,25 +1,25 @@ -/** +/** * @file llhandmotion.h * @brief Implementation of LLHandMotion class. * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -39,101 +39,101 @@ // class LLHandMotion //----------------------------------------------------------------------------- class LLHandMotion : - public LLMotion + public LLMotion { public: - typedef enum e_hand_pose - { - HAND_POSE_SPREAD, - HAND_POSE_RELAXED, - HAND_POSE_POINT, - HAND_POSE_FIST, - HAND_POSE_RELAXED_L, - HAND_POSE_POINT_L, - HAND_POSE_FIST_L, - HAND_POSE_RELAXED_R, - HAND_POSE_POINT_R, - HAND_POSE_FIST_R, - HAND_POSE_SALUTE_R, - HAND_POSE_TYPING, - HAND_POSE_PEACE_R, - HAND_POSE_PALM_R, - NUM_HAND_POSES - } eHandPose; - - // Constructor - LLHandMotion(const LLUUID &id); - - // Destructor - virtual ~LLHandMotion(); + typedef enum e_hand_pose + { + HAND_POSE_SPREAD, + HAND_POSE_RELAXED, + HAND_POSE_POINT, + HAND_POSE_FIST, + HAND_POSE_RELAXED_L, + HAND_POSE_POINT_L, + HAND_POSE_FIST_L, + HAND_POSE_RELAXED_R, + HAND_POSE_POINT_R, + HAND_POSE_FIST_R, + HAND_POSE_SALUTE_R, + HAND_POSE_TYPING, + HAND_POSE_PEACE_R, + HAND_POSE_PALM_R, + NUM_HAND_POSES + } eHandPose; + + // Constructor + LLHandMotion(const LLUUID &id); + + // Destructor + virtual ~LLHandMotion(); public: - //------------------------------------------------------------------------- - // functions to support MotionController and MotionRegistry - //------------------------------------------------------------------------- + //------------------------------------------------------------------------- + // functions to support MotionController and MotionRegistry + //------------------------------------------------------------------------- - // static constructor - // all subclasses must implement such a function and register it - static LLMotion *create(const LLUUID &id) { return new LLHandMotion(id); } + // static constructor + // all subclasses must implement such a function and register it + static LLMotion *create(const LLUUID &id) { return new LLHandMotion(id); } public: - //------------------------------------------------------------------------- - // animation callbacks to be implemented by subclasses - //------------------------------------------------------------------------- + //------------------------------------------------------------------------- + // animation callbacks to be implemented by subclasses + //------------------------------------------------------------------------- - // motions must specify whether or not they loop - virtual BOOL getLoop() { return TRUE; } + // motions must specify whether or not they loop + virtual BOOL getLoop() { return TRUE; } - // motions must report their total duration - virtual F32 getDuration() { return 0.0; } + // motions must report their total duration + virtual F32 getDuration() { return 0.0; } - // motions must report their "ease in" duration - virtual F32 getEaseInDuration() { return 0.0; } + // motions must report their "ease in" duration + virtual F32 getEaseInDuration() { return 0.0; } - // motions must report their "ease out" duration. - virtual F32 getEaseOutDuration() { return 0.0; } + // motions must report their "ease out" duration. + virtual F32 getEaseOutDuration() { return 0.0; } - // called to determine when a motion should be activated/deactivated based on avatar pixel coverage - virtual F32 getMinPixelArea() { return MIN_REQUIRED_PIXEL_AREA_HAND; } + // called to determine when a motion should be activated/deactivated based on avatar pixel coverage + virtual F32 getMinPixelArea() { return MIN_REQUIRED_PIXEL_AREA_HAND; } - // motions must report their priority - virtual LLJoint::JointPriority getPriority() { return LLJoint::MEDIUM_PRIORITY; } + // motions must report their priority + virtual LLJoint::JointPriority getPriority() { return LLJoint::MEDIUM_PRIORITY; } - virtual LLMotionBlendType getBlendType() { return NORMAL_BLEND; } + virtual LLMotionBlendType getBlendType() { return NORMAL_BLEND; } - // run-time (post constructor) initialization, - // called after parameters have been set - // must return true to indicate success and be available for activation - virtual LLMotionInitStatus onInitialize(LLCharacter *character); + // run-time (post constructor) initialization, + // called after parameters have been set + // must return true to indicate success and be available for activation + virtual LLMotionInitStatus onInitialize(LLCharacter *character); - // called when a motion is activated - // must return TRUE to indicate success, or else - // it will be deactivated - virtual BOOL onActivate(); + // called when a motion is activated + // must return TRUE to indicate success, or else + // it will be deactivated + virtual BOOL onActivate(); - // called per time step - // must return TRUE while it is active, and - // must return FALSE when the motion is completed. - virtual BOOL onUpdate(F32 time, U8* joint_mask); + // called per time step + // must return TRUE while it is active, and + // must return FALSE when the motion is completed. + virtual BOOL onUpdate(F32 time, U8* joint_mask); - // called when a motion is deactivated - virtual void onDeactivate(); + // called when a motion is deactivated + virtual void onDeactivate(); - virtual BOOL canDeprecate() { return FALSE; } + virtual BOOL canDeprecate() { return FALSE; } - static std::string getHandPoseName(eHandPose pose); - static eHandPose getHandPose(std::string posename); + static std::string getHandPoseName(eHandPose pose); + static eHandPose getHandPose(std::string posename); public: - //------------------------------------------------------------------------- - // joint states to be animated - //------------------------------------------------------------------------- + //------------------------------------------------------------------------- + // joint states to be animated + //------------------------------------------------------------------------- - LLCharacter *mCharacter; + LLCharacter *mCharacter; - F32 mLastTime; - eHandPose mCurrentPose; - eHandPose mNewPose; + F32 mLastTime; + eHandPose mCurrentPose; + eHandPose mNewPose; }; #endif // LL_LLHANDMOTION_H diff --git a/indra/llcharacter/llheadrotmotion.cpp b/indra/llcharacter/llheadrotmotion.cpp index 07a3aaebb6..55acb12490 100644 --- a/indra/llcharacter/llheadrotmotion.cpp +++ b/indra/llcharacter/llheadrotmotion.cpp @@ -1,25 +1,25 @@ -/** +/** * @file llheadrotmotion.cpp * @brief Implementation of LLHeadRotMotion class. * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -39,12 +39,12 @@ //----------------------------------------------------------------------------- // Constants //----------------------------------------------------------------------------- -const F32 TORSO_LAG = 0.35f; // torso rotation factor -const F32 NECK_LAG = 0.5f; // neck rotation factor -const F32 HEAD_LOOKAT_LAG_HALF_LIFE = 0.15f; // half-life of lookat targeting for head -const F32 TORSO_LOOKAT_LAG_HALF_LIFE = 0.27f; // half-life of lookat targeting for torso -const F32 HEAD_ROTATION_CONSTRAINT = F_PI_BY_TWO * 0.8f; // limit angle for head rotation -const F32 MIN_HEAD_LOOKAT_DISTANCE = 0.3f; // minimum distance from head before we turn to look at it +const F32 TORSO_LAG = 0.35f; // torso rotation factor +const F32 NECK_LAG = 0.5f; // neck rotation factor +const F32 HEAD_LOOKAT_LAG_HALF_LIFE = 0.15f; // half-life of lookat targeting for head +const F32 TORSO_LOOKAT_LAG_HALF_LIFE = 0.27f; // half-life of lookat targeting for torso +const F32 HEAD_ROTATION_CONSTRAINT = F_PI_BY_TWO * 0.8f; // limit angle for head rotation +const F32 MIN_HEAD_LOOKAT_DISTANCE = 0.3f; // minimum distance from head before we turn to look at it const F32 EYE_JITTER_MIN_TIME = 0.3f; // min amount of time between eye "jitter" motions const F32 EYE_JITTER_MAX_TIME = 2.5f; // max amount of time between eye "jitter" motions const F32 EYE_JITTER_MAX_YAW = 0.08f; // max yaw of eye jitter motion @@ -58,26 +58,26 @@ const F32 EYE_LOOK_AWAY_MAX_PITCH = 0.12f; // max pitch of look away motion const F32 EYE_ROT_LIMIT_ANGLE = F_PI_BY_TWO * 0.3f; //max angle in radians for eye rotation const F32 EYE_BLINK_MIN_TIME = 0.5f; // minimum amount of time between blinks -const F32 EYE_BLINK_MAX_TIME = 8.f; // maximum amount of time between blinks +const F32 EYE_BLINK_MAX_TIME = 8.f; // maximum amount of time between blinks const F32 EYE_BLINK_CLOSE_TIME = 0.03f; // how long the eye stays closed in a blink -const F32 EYE_BLINK_SPEED = 0.015f; // seconds it takes for a eye open/close movement +const F32 EYE_BLINK_SPEED = 0.015f; // seconds it takes for a eye open/close movement const F32 EYE_BLINK_TIME_DELTA = 0.005f; // time between one eye starting a blink and the other following //----------------------------------------------------------------------------- // LLHeadRotMotion() // Class Constructor //----------------------------------------------------------------------------- -LLHeadRotMotion::LLHeadRotMotion(const LLUUID &id) : - LLMotion(id), - mCharacter(NULL), - mTorsoJoint(NULL), - mHeadJoint(NULL) +LLHeadRotMotion::LLHeadRotMotion(const LLUUID &id) : + LLMotion(id), + mCharacter(NULL), + mTorsoJoint(NULL), + mHeadJoint(NULL) { - mName = "head_rot"; + mName = "head_rot"; - mTorsoState = new LLJointState; - mNeckState = new LLJointState; - mHeadState = new LLJointState; + mTorsoState = new LLJointState; + mNeckState = new LLJointState; + mHeadState = new LLJointState; } @@ -94,70 +94,70 @@ LLHeadRotMotion::~LLHeadRotMotion() //----------------------------------------------------------------------------- LLMotion::LLMotionInitStatus LLHeadRotMotion::onInitialize(LLCharacter *character) { - if (!character) - return STATUS_FAILURE; - mCharacter = character; - - mPelvisJoint = character->getJoint("mPelvis"); - if ( ! mPelvisJoint ) - { - LL_INFOS() << getName() << ": Can't get pelvis joint." << LL_ENDL; - return STATUS_FAILURE; - } - - mRootJoint = character->getJoint("mRoot"); - if ( ! mRootJoint ) - { - LL_INFOS() << getName() << ": Can't get root joint." << LL_ENDL; - return STATUS_FAILURE; - } - - mTorsoJoint = character->getJoint("mTorso"); - if ( ! mTorsoJoint ) - { - LL_INFOS() << getName() << ": Can't get torso joint." << LL_ENDL; - return STATUS_FAILURE; - } - - mHeadJoint = character->getJoint("mHead"); - if ( ! mHeadJoint ) - { - LL_INFOS() << getName() << ": Can't get head joint." << LL_ENDL; - return STATUS_FAILURE; - } - - mTorsoState->setJoint( character->getJoint("mTorso") ); - if ( ! mTorsoState->getJoint() ) - { - LL_INFOS() << getName() << ": Can't get torso joint." << LL_ENDL; - return STATUS_FAILURE; - } - - mNeckState->setJoint( character->getJoint("mNeck") ); - if ( ! mNeckState->getJoint() ) - { - LL_INFOS() << getName() << ": Can't get neck joint." << LL_ENDL; - return STATUS_FAILURE; - } - - mHeadState->setJoint( character->getJoint("mHead") ); - if ( ! mHeadState->getJoint() ) - { - LL_INFOS() << getName() << ": Can't get head joint." << LL_ENDL; - return STATUS_FAILURE; - } - - mTorsoState->setUsage(LLJointState::ROT); - mNeckState->setUsage(LLJointState::ROT); - mHeadState->setUsage(LLJointState::ROT); - - addJointState( mTorsoState ); - addJointState( mNeckState ); - addJointState( mHeadState ); - - mLastHeadRot.loadIdentity(); - - return STATUS_SUCCESS; + if (!character) + return STATUS_FAILURE; + mCharacter = character; + + mPelvisJoint = character->getJoint("mPelvis"); + if ( ! mPelvisJoint ) + { + LL_INFOS() << getName() << ": Can't get pelvis joint." << LL_ENDL; + return STATUS_FAILURE; + } + + mRootJoint = character->getJoint("mRoot"); + if ( ! mRootJoint ) + { + LL_INFOS() << getName() << ": Can't get root joint." << LL_ENDL; + return STATUS_FAILURE; + } + + mTorsoJoint = character->getJoint("mTorso"); + if ( ! mTorsoJoint ) + { + LL_INFOS() << getName() << ": Can't get torso joint." << LL_ENDL; + return STATUS_FAILURE; + } + + mHeadJoint = character->getJoint("mHead"); + if ( ! mHeadJoint ) + { + LL_INFOS() << getName() << ": Can't get head joint." << LL_ENDL; + return STATUS_FAILURE; + } + + mTorsoState->setJoint( character->getJoint("mTorso") ); + if ( ! mTorsoState->getJoint() ) + { + LL_INFOS() << getName() << ": Can't get torso joint." << LL_ENDL; + return STATUS_FAILURE; + } + + mNeckState->setJoint( character->getJoint("mNeck") ); + if ( ! mNeckState->getJoint() ) + { + LL_INFOS() << getName() << ": Can't get neck joint." << LL_ENDL; + return STATUS_FAILURE; + } + + mHeadState->setJoint( character->getJoint("mHead") ); + if ( ! mHeadState->getJoint() ) + { + LL_INFOS() << getName() << ": Can't get head joint." << LL_ENDL; + return STATUS_FAILURE; + } + + mTorsoState->setUsage(LLJointState::ROT); + mNeckState->setUsage(LLJointState::ROT); + mHeadState->setUsage(LLJointState::ROT); + + addJointState( mTorsoState ); + addJointState( mNeckState ); + addJointState( mHeadState ); + + mLastHeadRot.loadIdentity(); + + return STATUS_SUCCESS; } @@ -166,7 +166,7 @@ LLMotion::LLMotionInitStatus LLHeadRotMotion::onInitialize(LLCharacter *characte //----------------------------------------------------------------------------- BOOL LLHeadRotMotion::onActivate() { - return TRUE; + return TRUE; } @@ -176,82 +176,82 @@ BOOL LLHeadRotMotion::onActivate() BOOL LLHeadRotMotion::onUpdate(F32 time, U8* joint_mask) { LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR; - LLQuaternion targetHeadRotWorld; - LLQuaternion currentRootRotWorld = mRootJoint->getWorldRotation(); - LLQuaternion currentInvRootRotWorld = ~currentRootRotWorld; - - F32 head_slerp_amt = LLSmoothInterpolation::getInterpolant(HEAD_LOOKAT_LAG_HALF_LIFE); - F32 torso_slerp_amt = LLSmoothInterpolation::getInterpolant(TORSO_LOOKAT_LAG_HALF_LIFE); - - LLVector3* targetPos = (LLVector3*)mCharacter->getAnimationData("LookAtPoint"); - - if (targetPos) - { - LLVector3 headLookAt = *targetPos; - -// LL_INFOS() << "Look At: " << headLookAt + mHeadJoint->getWorldPosition() << LL_ENDL; - - F32 lookatDistance = headLookAt.normVec(); - - if (lookatDistance < MIN_HEAD_LOOKAT_DISTANCE) - { - targetHeadRotWorld = mPelvisJoint->getWorldRotation(); - } - else - { - LLVector3 root_up = LLVector3(0.f, 0.f, 1.f) * currentRootRotWorld; - LLVector3 left(root_up % headLookAt); - // if look_at has zero length, fail - // if look_at and skyward are parallel, fail - // - // Test both of these conditions with a cross product. - - if (left.magVecSquared() < 0.15f) - { - LLVector3 root_at = LLVector3(1.f, 0.f, 0.f) * currentRootRotWorld; - root_at.mV[VZ] = 0.f; - root_at.normVec(); - - headLookAt = lerp(headLookAt, root_at, 0.4f); - headLookAt.normVec(); - - left = root_up % headLookAt; - } - - // Make sure look_at and skyward and not parallel - // and neither are zero length - LLVector3 up(headLookAt % left); - - targetHeadRotWorld = LLQuaternion(headLookAt, left, up); - } - } - else - { - targetHeadRotWorld = currentRootRotWorld; - } - - LLQuaternion head_rot_local = targetHeadRotWorld * currentInvRootRotWorld; - head_rot_local.constrain(HEAD_ROTATION_CONSTRAINT); - - // set final torso rotation - // Set torso target rotation such that it lags behind the head rotation - // by a fixed amount. - LLQuaternion torso_rot_local = nlerp(TORSO_LAG, LLQuaternion::DEFAULT, head_rot_local ); - mTorsoState->setRotation( nlerp(torso_slerp_amt, mTorsoState->getRotation(), torso_rot_local) ); - - head_rot_local = nlerp(head_slerp_amt, mLastHeadRot, head_rot_local); - mLastHeadRot = head_rot_local; - - // Set the head rotation. - if(mNeckState->getJoint() && mNeckState->getJoint()->getParent()) - { - LLQuaternion torsoRotLocal = mNeckState->getJoint()->getParent()->getWorldRotation() * currentInvRootRotWorld; - head_rot_local = head_rot_local * ~torsoRotLocal; - mNeckState->setRotation( nlerp(NECK_LAG, LLQuaternion::DEFAULT, head_rot_local) ); - mHeadState->setRotation( nlerp(1.f - NECK_LAG, LLQuaternion::DEFAULT, head_rot_local)); - } - - return TRUE; + LLQuaternion targetHeadRotWorld; + LLQuaternion currentRootRotWorld = mRootJoint->getWorldRotation(); + LLQuaternion currentInvRootRotWorld = ~currentRootRotWorld; + + F32 head_slerp_amt = LLSmoothInterpolation::getInterpolant(HEAD_LOOKAT_LAG_HALF_LIFE); + F32 torso_slerp_amt = LLSmoothInterpolation::getInterpolant(TORSO_LOOKAT_LAG_HALF_LIFE); + + LLVector3* targetPos = (LLVector3*)mCharacter->getAnimationData("LookAtPoint"); + + if (targetPos) + { + LLVector3 headLookAt = *targetPos; + +// LL_INFOS() << "Look At: " << headLookAt + mHeadJoint->getWorldPosition() << LL_ENDL; + + F32 lookatDistance = headLookAt.normVec(); + + if (lookatDistance < MIN_HEAD_LOOKAT_DISTANCE) + { + targetHeadRotWorld = mPelvisJoint->getWorldRotation(); + } + else + { + LLVector3 root_up = LLVector3(0.f, 0.f, 1.f) * currentRootRotWorld; + LLVector3 left(root_up % headLookAt); + // if look_at has zero length, fail + // if look_at and skyward are parallel, fail + // + // Test both of these conditions with a cross product. + + if (left.magVecSquared() < 0.15f) + { + LLVector3 root_at = LLVector3(1.f, 0.f, 0.f) * currentRootRotWorld; + root_at.mV[VZ] = 0.f; + root_at.normVec(); + + headLookAt = lerp(headLookAt, root_at, 0.4f); + headLookAt.normVec(); + + left = root_up % headLookAt; + } + + // Make sure look_at and skyward and not parallel + // and neither are zero length + LLVector3 up(headLookAt % left); + + targetHeadRotWorld = LLQuaternion(headLookAt, left, up); + } + } + else + { + targetHeadRotWorld = currentRootRotWorld; + } + + LLQuaternion head_rot_local = targetHeadRotWorld * currentInvRootRotWorld; + head_rot_local.constrain(HEAD_ROTATION_CONSTRAINT); + + // set final torso rotation + // Set torso target rotation such that it lags behind the head rotation + // by a fixed amount. + LLQuaternion torso_rot_local = nlerp(TORSO_LAG, LLQuaternion::DEFAULT, head_rot_local ); + mTorsoState->setRotation( nlerp(torso_slerp_amt, mTorsoState->getRotation(), torso_rot_local) ); + + head_rot_local = nlerp(head_slerp_amt, mLastHeadRot, head_rot_local); + mLastHeadRot = head_rot_local; + + // Set the head rotation. + if(mNeckState->getJoint() && mNeckState->getJoint()->getParent()) + { + LLQuaternion torsoRotLocal = mNeckState->getJoint()->getParent()->getWorldRotation() * currentInvRootRotWorld; + head_rot_local = head_rot_local * ~torsoRotLocal; + mNeckState->setRotation( nlerp(NECK_LAG, LLQuaternion::DEFAULT, head_rot_local) ); + mHeadState->setRotation( nlerp(1.f - NECK_LAG, LLQuaternion::DEFAULT, head_rot_local)); + } + + return TRUE; } @@ -269,27 +269,27 @@ void LLHeadRotMotion::onDeactivate() //----------------------------------------------------------------------------- LLEyeMotion::LLEyeMotion(const LLUUID &id) : LLMotion(id) { - mCharacter = NULL; - mEyeJitterTime = 0.f; - mEyeJitterYaw = 0.f; - mEyeJitterPitch = 0.f; + mCharacter = NULL; + mEyeJitterTime = 0.f; + mEyeJitterYaw = 0.f; + mEyeJitterPitch = 0.f; + + mEyeLookAwayTime = 0.f; + mEyeLookAwayYaw = 0.f; + mEyeLookAwayPitch = 0.f; - mEyeLookAwayTime = 0.f; - mEyeLookAwayYaw = 0.f; - mEyeLookAwayPitch = 0.f; + mEyeBlinkTime = 0.f; + mEyesClosed = FALSE; - mEyeBlinkTime = 0.f; - mEyesClosed = FALSE; - - mHeadJoint = NULL; + mHeadJoint = NULL; - mName = "eye_rot"; + mName = "eye_rot"; - mLeftEyeState = new LLJointState; - mAltLeftEyeState = new LLJointState; + mLeftEyeState = new LLJointState; + mAltLeftEyeState = new LLJointState; - mRightEyeState = new LLJointState; - mAltRightEyeState = new LLJointState; + mRightEyeState = new LLJointState; + mAltRightEyeState = new LLJointState; } @@ -306,56 +306,56 @@ LLEyeMotion::~LLEyeMotion() //----------------------------------------------------------------------------- LLMotion::LLMotionInitStatus LLEyeMotion::onInitialize(LLCharacter *character) { - mCharacter = character; - - mHeadJoint = character->getJoint("mHead"); - if ( ! mHeadJoint ) - { - LL_INFOS() << getName() << ": Can't get head joint." << LL_ENDL; - return STATUS_FAILURE; - } - - mLeftEyeState->setJoint( character->getJoint("mEyeLeft") ); - if ( ! mLeftEyeState->getJoint() ) - { - LL_INFOS() << getName() << ": Can't get left eyeball joint." << LL_ENDL; - return STATUS_FAILURE; - } - - mAltLeftEyeState->setJoint( character->getJoint("mFaceEyeAltLeft") ); - if ( ! mAltLeftEyeState->getJoint() ) - { - LL_INFOS() << getName() << ": Can't get alt left eyeball joint." << LL_ENDL; - return STATUS_FAILURE; - } - - mRightEyeState->setJoint( character->getJoint("mEyeRight") ); - if ( ! mRightEyeState->getJoint() ) - { - LL_INFOS() << getName() << ": Can't get right eyeball joint." << LL_ENDL; - return STATUS_FAILURE; - } - - mAltRightEyeState->setJoint( character->getJoint("mFaceEyeAltRight") ); - if ( ! mAltRightEyeState->getJoint() ) - { - LL_INFOS() << getName() << ": Can't get alt right eyeball joint." << LL_ENDL; - return STATUS_FAILURE; - } - - mLeftEyeState->setUsage(LLJointState::ROT); - mAltLeftEyeState->setUsage(LLJointState::ROT); - - mRightEyeState->setUsage(LLJointState::ROT); - mAltRightEyeState->setUsage(LLJointState::ROT); - - addJointState( mLeftEyeState ); - addJointState( mAltLeftEyeState ); - - addJointState( mRightEyeState ); - addJointState( mAltRightEyeState ); - - return STATUS_SUCCESS; + mCharacter = character; + + mHeadJoint = character->getJoint("mHead"); + if ( ! mHeadJoint ) + { + LL_INFOS() << getName() << ": Can't get head joint." << LL_ENDL; + return STATUS_FAILURE; + } + + mLeftEyeState->setJoint( character->getJoint("mEyeLeft") ); + if ( ! mLeftEyeState->getJoint() ) + { + LL_INFOS() << getName() << ": Can't get left eyeball joint." << LL_ENDL; + return STATUS_FAILURE; + } + + mAltLeftEyeState->setJoint( character->getJoint("mFaceEyeAltLeft") ); + if ( ! mAltLeftEyeState->getJoint() ) + { + LL_INFOS() << getName() << ": Can't get alt left eyeball joint." << LL_ENDL; + return STATUS_FAILURE; + } + + mRightEyeState->setJoint( character->getJoint("mEyeRight") ); + if ( ! mRightEyeState->getJoint() ) + { + LL_INFOS() << getName() << ": Can't get right eyeball joint." << LL_ENDL; + return STATUS_FAILURE; + } + + mAltRightEyeState->setJoint( character->getJoint("mFaceEyeAltRight") ); + if ( ! mAltRightEyeState->getJoint() ) + { + LL_INFOS() << getName() << ": Can't get alt right eyeball joint." << LL_ENDL; + return STATUS_FAILURE; + } + + mLeftEyeState->setUsage(LLJointState::ROT); + mAltLeftEyeState->setUsage(LLJointState::ROT); + + mRightEyeState->setUsage(LLJointState::ROT); + mAltRightEyeState->setUsage(LLJointState::ROT); + + addJointState( mLeftEyeState ); + addJointState( mAltLeftEyeState ); + + addJointState( mRightEyeState ); + addJointState( mAltRightEyeState ); + + return STATUS_SUCCESS; } @@ -364,7 +364,7 @@ LLMotion::LLMotionInitStatus LLEyeMotion::onInitialize(LLCharacter *character) //----------------------------------------------------------------------------- BOOL LLEyeMotion::onActivate() { - return TRUE; + return TRUE; } //----------------------------------------------------------------------------- @@ -372,86 +372,86 @@ BOOL LLEyeMotion::onActivate() //----------------------------------------------------------------------------- void LLEyeMotion::adjustEyeTarget(LLVector3* targetPos, LLJointState& left_eye_state, LLJointState& right_eye_state) { - // Compute eye rotation. - BOOL has_eye_target = FALSE; - LLQuaternion target_eye_rot; - LLVector3 eye_look_at; - F32 vergence; - - if (targetPos) - { - LLVector3 skyward(0.f, 0.f, 1.f); - LLVector3 left; - LLVector3 up; - - eye_look_at = *targetPos; - has_eye_target = TRUE; - F32 lookAtDistance = eye_look_at.normVec(); - - left.setVec(skyward % eye_look_at); - up.setVec(eye_look_at % left); - - target_eye_rot = LLQuaternion(eye_look_at, left, up); - // convert target rotation to head-local coordinates - target_eye_rot *= ~mHeadJoint->getWorldRotation(); - // eliminate any Euler roll - we're lucky that roll is applied last. - F32 roll, pitch, yaw; - target_eye_rot.getEulerAngles(&roll, &pitch, &yaw); - target_eye_rot.setQuat(0.0f, pitch, yaw); - // constrain target orientation to be in front of avatar's face - target_eye_rot.constrain(EYE_ROT_LIMIT_ANGLE); - - // calculate vergence - F32 interocular_dist = (left_eye_state.getJoint()->getWorldPosition() - right_eye_state.getJoint()->getWorldPosition()).magVec(); - vergence = -atan2((interocular_dist / 2.f), lookAtDistance); - llclamp(vergence, -F_PI_BY_TWO, 0.f); - } - else - { - target_eye_rot = LLQuaternion::DEFAULT; - vergence = 0.f; - } - - //RN: subtract 4 degrees to account for foveal angular offset relative to pupil - vergence += 4.f * DEG_TO_RAD; - - // calculate eye jitter - LLQuaternion eye_jitter_rot; - - // vergence not too high... - if (vergence > -0.05f) - { - //...go ahead and jitter - eye_jitter_rot.setQuat(0.f, mEyeJitterPitch + mEyeLookAwayPitch, mEyeJitterYaw + mEyeLookAwayYaw); - } - else - { - //...or don't - eye_jitter_rot.loadIdentity(); - } - - // calculate vergence of eyes as an object gets closer to the avatar's head - LLQuaternion vergence_quat; - - if (has_eye_target) - { - vergence_quat.setQuat(vergence, LLVector3(0.f, 0.f, 1.f)); - } - else - { - vergence_quat.loadIdentity(); - } - - // calculate eye rotations - LLQuaternion left_eye_rot = target_eye_rot; - left_eye_rot = vergence_quat * eye_jitter_rot * left_eye_rot; - - LLQuaternion right_eye_rot = target_eye_rot; - vergence_quat.transQuat(); - right_eye_rot = vergence_quat * eye_jitter_rot * right_eye_rot; - - left_eye_state.setRotation( left_eye_rot ); - right_eye_state.setRotation( right_eye_rot ); + // Compute eye rotation. + BOOL has_eye_target = FALSE; + LLQuaternion target_eye_rot; + LLVector3 eye_look_at; + F32 vergence; + + if (targetPos) + { + LLVector3 skyward(0.f, 0.f, 1.f); + LLVector3 left; + LLVector3 up; + + eye_look_at = *targetPos; + has_eye_target = TRUE; + F32 lookAtDistance = eye_look_at.normVec(); + + left.setVec(skyward % eye_look_at); + up.setVec(eye_look_at % left); + + target_eye_rot = LLQuaternion(eye_look_at, left, up); + // convert target rotation to head-local coordinates + target_eye_rot *= ~mHeadJoint->getWorldRotation(); + // eliminate any Euler roll - we're lucky that roll is applied last. + F32 roll, pitch, yaw; + target_eye_rot.getEulerAngles(&roll, &pitch, &yaw); + target_eye_rot.setQuat(0.0f, pitch, yaw); + // constrain target orientation to be in front of avatar's face + target_eye_rot.constrain(EYE_ROT_LIMIT_ANGLE); + + // calculate vergence + F32 interocular_dist = (left_eye_state.getJoint()->getWorldPosition() - right_eye_state.getJoint()->getWorldPosition()).magVec(); + vergence = -atan2((interocular_dist / 2.f), lookAtDistance); + llclamp(vergence, -F_PI_BY_TWO, 0.f); + } + else + { + target_eye_rot = LLQuaternion::DEFAULT; + vergence = 0.f; + } + + //RN: subtract 4 degrees to account for foveal angular offset relative to pupil + vergence += 4.f * DEG_TO_RAD; + + // calculate eye jitter + LLQuaternion eye_jitter_rot; + + // vergence not too high... + if (vergence > -0.05f) + { + //...go ahead and jitter + eye_jitter_rot.setQuat(0.f, mEyeJitterPitch + mEyeLookAwayPitch, mEyeJitterYaw + mEyeLookAwayYaw); + } + else + { + //...or don't + eye_jitter_rot.loadIdentity(); + } + + // calculate vergence of eyes as an object gets closer to the avatar's head + LLQuaternion vergence_quat; + + if (has_eye_target) + { + vergence_quat.setQuat(vergence, LLVector3(0.f, 0.f, 1.f)); + } + else + { + vergence_quat.loadIdentity(); + } + + // calculate eye rotations + LLQuaternion left_eye_rot = target_eye_rot; + left_eye_rot = vergence_quat * eye_jitter_rot * left_eye_rot; + + LLQuaternion right_eye_rot = target_eye_rot; + vergence_quat.transQuat(); + right_eye_rot = vergence_quat * eye_jitter_rot * right_eye_rot; + + left_eye_state.setRotation( left_eye_rot ); + right_eye_state.setRotation( right_eye_rot ); } //----------------------------------------------------------------------------- @@ -460,84 +460,84 @@ void LLEyeMotion::adjustEyeTarget(LLVector3* targetPos, LLJointState& left_eye_s BOOL LLEyeMotion::onUpdate(F32 time, U8* joint_mask) { LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR; - //calculate jitter - if (mEyeJitterTimer.getElapsedTimeF32() > mEyeJitterTime) - { - mEyeJitterTime = EYE_JITTER_MIN_TIME + ll_frand(EYE_JITTER_MAX_TIME - EYE_JITTER_MIN_TIME); - mEyeJitterYaw = (ll_frand(2.f) - 1.f) * EYE_JITTER_MAX_YAW; - mEyeJitterPitch = (ll_frand(2.f) - 1.f) * EYE_JITTER_MAX_PITCH; - // make sure lookaway time count gets updated, because we're resetting the timer - mEyeLookAwayTime -= llmax(0.f, mEyeJitterTimer.getElapsedTimeF32()); - mEyeJitterTimer.reset(); - } - else if (mEyeJitterTimer.getElapsedTimeF32() > mEyeLookAwayTime) - { - if (ll_frand() > 0.1f) - { - // blink while moving eyes some percentage of the time - mEyeBlinkTime = mEyeBlinkTimer.getElapsedTimeF32(); - } - if (mEyeLookAwayYaw == 0.f && mEyeLookAwayPitch == 0.f) - { - mEyeLookAwayYaw = (ll_frand(2.f) - 1.f) * EYE_LOOK_AWAY_MAX_YAW; - mEyeLookAwayPitch = (ll_frand(2.f) - 1.f) * EYE_LOOK_AWAY_MAX_PITCH; - mEyeLookAwayTime = EYE_LOOK_BACK_MIN_TIME + ll_frand(EYE_LOOK_BACK_MAX_TIME - EYE_LOOK_BACK_MIN_TIME); - } - else - { - mEyeLookAwayYaw = 0.f; - mEyeLookAwayPitch = 0.f; - mEyeLookAwayTime = EYE_LOOK_AWAY_MIN_TIME + ll_frand(EYE_LOOK_AWAY_MAX_TIME - EYE_LOOK_AWAY_MIN_TIME); - } - } - - // do blinking - if (!mEyesClosed && mEyeBlinkTimer.getElapsedTimeF32() >= mEyeBlinkTime) - { - F32 leftEyeBlinkMorph = mEyeBlinkTimer.getElapsedTimeF32() - mEyeBlinkTime; - F32 rightEyeBlinkMorph = leftEyeBlinkMorph - EYE_BLINK_TIME_DELTA; - - leftEyeBlinkMorph = llclamp(leftEyeBlinkMorph / EYE_BLINK_SPEED, 0.f, 1.f); - rightEyeBlinkMorph = llclamp(rightEyeBlinkMorph / EYE_BLINK_SPEED, 0.f, 1.f); - mCharacter->setVisualParamWeight("Blink_Left", leftEyeBlinkMorph); - mCharacter->setVisualParamWeight("Blink_Right", rightEyeBlinkMorph); - mCharacter->updateVisualParams(); - - if (rightEyeBlinkMorph == 1.f) - { - mEyesClosed = TRUE; - mEyeBlinkTime = EYE_BLINK_CLOSE_TIME; - mEyeBlinkTimer.reset(); - } - } - else if (mEyesClosed) - { - if (mEyeBlinkTimer.getElapsedTimeF32() >= mEyeBlinkTime) - { - F32 leftEyeBlinkMorph = mEyeBlinkTimer.getElapsedTimeF32() - mEyeBlinkTime; - F32 rightEyeBlinkMorph = leftEyeBlinkMorph - EYE_BLINK_TIME_DELTA; - - leftEyeBlinkMorph = 1.f - llclamp(leftEyeBlinkMorph / EYE_BLINK_SPEED, 0.f, 1.f); - rightEyeBlinkMorph = 1.f - llclamp(rightEyeBlinkMorph / EYE_BLINK_SPEED, 0.f, 1.f); - mCharacter->setVisualParamWeight("Blink_Left", leftEyeBlinkMorph); - mCharacter->setVisualParamWeight("Blink_Right", rightEyeBlinkMorph); - mCharacter->updateVisualParams(); - - if (rightEyeBlinkMorph == 0.f) - { - mEyesClosed = FALSE; - mEyeBlinkTime = EYE_BLINK_MIN_TIME + ll_frand(EYE_BLINK_MAX_TIME - EYE_BLINK_MIN_TIME); - mEyeBlinkTimer.reset(); - } - } - } - - LLVector3* targetPos = (LLVector3*)mCharacter->getAnimationData("LookAtPoint"); - - adjustEyeTarget(targetPos, *mLeftEyeState, *mRightEyeState); - adjustEyeTarget(targetPos, *mAltLeftEyeState, *mAltRightEyeState); - - return TRUE; + //calculate jitter + if (mEyeJitterTimer.getElapsedTimeF32() > mEyeJitterTime) + { + mEyeJitterTime = EYE_JITTER_MIN_TIME + ll_frand(EYE_JITTER_MAX_TIME - EYE_JITTER_MIN_TIME); + mEyeJitterYaw = (ll_frand(2.f) - 1.f) * EYE_JITTER_MAX_YAW; + mEyeJitterPitch = (ll_frand(2.f) - 1.f) * EYE_JITTER_MAX_PITCH; + // make sure lookaway time count gets updated, because we're resetting the timer + mEyeLookAwayTime -= llmax(0.f, mEyeJitterTimer.getElapsedTimeF32()); + mEyeJitterTimer.reset(); + } + else if (mEyeJitterTimer.getElapsedTimeF32() > mEyeLookAwayTime) + { + if (ll_frand() > 0.1f) + { + // blink while moving eyes some percentage of the time + mEyeBlinkTime = mEyeBlinkTimer.getElapsedTimeF32(); + } + if (mEyeLookAwayYaw == 0.f && mEyeLookAwayPitch == 0.f) + { + mEyeLookAwayYaw = (ll_frand(2.f) - 1.f) * EYE_LOOK_AWAY_MAX_YAW; + mEyeLookAwayPitch = (ll_frand(2.f) - 1.f) * EYE_LOOK_AWAY_MAX_PITCH; + mEyeLookAwayTime = EYE_LOOK_BACK_MIN_TIME + ll_frand(EYE_LOOK_BACK_MAX_TIME - EYE_LOOK_BACK_MIN_TIME); + } + else + { + mEyeLookAwayYaw = 0.f; + mEyeLookAwayPitch = 0.f; + mEyeLookAwayTime = EYE_LOOK_AWAY_MIN_TIME + ll_frand(EYE_LOOK_AWAY_MAX_TIME - EYE_LOOK_AWAY_MIN_TIME); + } + } + + // do blinking + if (!mEyesClosed && mEyeBlinkTimer.getElapsedTimeF32() >= mEyeBlinkTime) + { + F32 leftEyeBlinkMorph = mEyeBlinkTimer.getElapsedTimeF32() - mEyeBlinkTime; + F32 rightEyeBlinkMorph = leftEyeBlinkMorph - EYE_BLINK_TIME_DELTA; + + leftEyeBlinkMorph = llclamp(leftEyeBlinkMorph / EYE_BLINK_SPEED, 0.f, 1.f); + rightEyeBlinkMorph = llclamp(rightEyeBlinkMorph / EYE_BLINK_SPEED, 0.f, 1.f); + mCharacter->setVisualParamWeight("Blink_Left", leftEyeBlinkMorph); + mCharacter->setVisualParamWeight("Blink_Right", rightEyeBlinkMorph); + mCharacter->updateVisualParams(); + + if (rightEyeBlinkMorph == 1.f) + { + mEyesClosed = TRUE; + mEyeBlinkTime = EYE_BLINK_CLOSE_TIME; + mEyeBlinkTimer.reset(); + } + } + else if (mEyesClosed) + { + if (mEyeBlinkTimer.getElapsedTimeF32() >= mEyeBlinkTime) + { + F32 leftEyeBlinkMorph = mEyeBlinkTimer.getElapsedTimeF32() - mEyeBlinkTime; + F32 rightEyeBlinkMorph = leftEyeBlinkMorph - EYE_BLINK_TIME_DELTA; + + leftEyeBlinkMorph = 1.f - llclamp(leftEyeBlinkMorph / EYE_BLINK_SPEED, 0.f, 1.f); + rightEyeBlinkMorph = 1.f - llclamp(rightEyeBlinkMorph / EYE_BLINK_SPEED, 0.f, 1.f); + mCharacter->setVisualParamWeight("Blink_Left", leftEyeBlinkMorph); + mCharacter->setVisualParamWeight("Blink_Right", rightEyeBlinkMorph); + mCharacter->updateVisualParams(); + + if (rightEyeBlinkMorph == 0.f) + { + mEyesClosed = FALSE; + mEyeBlinkTime = EYE_BLINK_MIN_TIME + ll_frand(EYE_BLINK_MAX_TIME - EYE_BLINK_MIN_TIME); + mEyeBlinkTimer.reset(); + } + } + } + + LLVector3* targetPos = (LLVector3*)mCharacter->getAnimationData("LookAtPoint"); + + adjustEyeTarget(targetPos, *mLeftEyeState, *mRightEyeState); + adjustEyeTarget(targetPos, *mAltLeftEyeState, *mAltRightEyeState); + + return TRUE; } @@ -546,29 +546,29 @@ BOOL LLEyeMotion::onUpdate(F32 time, U8* joint_mask) //----------------------------------------------------------------------------- void LLEyeMotion::onDeactivate() { - LLJoint* joint = mLeftEyeState->getJoint(); - if (joint) - { - joint->setRotation(LLQuaternion::DEFAULT); - } - - joint = mAltLeftEyeState->getJoint(); - if (joint) - { - joint->setRotation(LLQuaternion::DEFAULT); - } - - joint = mRightEyeState->getJoint(); - if (joint) - { - joint->setRotation(LLQuaternion::DEFAULT); - } - - joint = mAltRightEyeState->getJoint(); - if (joint) - { - joint->setRotation(LLQuaternion::DEFAULT); - } + LLJoint* joint = mLeftEyeState->getJoint(); + if (joint) + { + joint->setRotation(LLQuaternion::DEFAULT); + } + + joint = mAltLeftEyeState->getJoint(); + if (joint) + { + joint->setRotation(LLQuaternion::DEFAULT); + } + + joint = mRightEyeState->getJoint(); + if (joint) + { + joint->setRotation(LLQuaternion::DEFAULT); + } + + joint = mAltRightEyeState->getJoint(); + if (joint) + { + joint->setRotation(LLQuaternion::DEFAULT); + } } // End diff --git a/indra/llcharacter/llheadrotmotion.h b/indra/llcharacter/llheadrotmotion.h index 53ae1813bc..3239008b92 100644 --- a/indra/llcharacter/llheadrotmotion.h +++ b/indra/llcharacter/llheadrotmotion.h @@ -1,25 +1,25 @@ -/** +/** * @file llheadrotmotion.h * @brief Implementation of LLHeadRotMotion class. * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -40,176 +40,176 @@ // class LLHeadRotMotion //----------------------------------------------------------------------------- class LLHeadRotMotion : - public LLMotion + public LLMotion { public: - // Constructor - LLHeadRotMotion(const LLUUID &id); + // Constructor + LLHeadRotMotion(const LLUUID &id); - // Destructor - virtual ~LLHeadRotMotion(); + // Destructor + virtual ~LLHeadRotMotion(); public: - //------------------------------------------------------------------------- - // functions to support MotionController and MotionRegistry - //------------------------------------------------------------------------- + //------------------------------------------------------------------------- + // functions to support MotionController and MotionRegistry + //------------------------------------------------------------------------- - // static constructor - // all subclasses must implement such a function and register it - static LLMotion *create(const LLUUID &id) { return new LLHeadRotMotion(id); } + // static constructor + // all subclasses must implement such a function and register it + static LLMotion *create(const LLUUID &id) { return new LLHeadRotMotion(id); } public: - //------------------------------------------------------------------------- - // animation callbacks to be implemented by subclasses - //------------------------------------------------------------------------- + //------------------------------------------------------------------------- + // animation callbacks to be implemented by subclasses + //------------------------------------------------------------------------- - // motions must specify whether or not they loop - virtual BOOL getLoop() { return TRUE; } + // motions must specify whether or not they loop + virtual BOOL getLoop() { return TRUE; } - // motions must report their total duration - virtual F32 getDuration() { return 0.0; } + // motions must report their total duration + virtual F32 getDuration() { return 0.0; } - // motions must report their "ease in" duration - virtual F32 getEaseInDuration() { return 1.f; } + // motions must report their "ease in" duration + virtual F32 getEaseInDuration() { return 1.f; } - // motions must report their "ease out" duration. - virtual F32 getEaseOutDuration() { return 1.f; } + // motions must report their "ease out" duration. + virtual F32 getEaseOutDuration() { return 1.f; } - // called to determine when a motion should be activated/deactivated based on avatar pixel coverage - virtual F32 getMinPixelArea() { return MIN_REQUIRED_PIXEL_AREA_HEAD_ROT; } + // called to determine when a motion should be activated/deactivated based on avatar pixel coverage + virtual F32 getMinPixelArea() { return MIN_REQUIRED_PIXEL_AREA_HEAD_ROT; } - // motions must report their priority - virtual LLJoint::JointPriority getPriority() { return LLJoint::MEDIUM_PRIORITY; } + // motions must report their priority + virtual LLJoint::JointPriority getPriority() { return LLJoint::MEDIUM_PRIORITY; } - virtual LLMotionBlendType getBlendType() { return NORMAL_BLEND; } + virtual LLMotionBlendType getBlendType() { return NORMAL_BLEND; } - // run-time (post constructor) initialization, - // called after parameters have been set - // must return true to indicate success and be available for activation - virtual LLMotionInitStatus onInitialize(LLCharacter *character); + // run-time (post constructor) initialization, + // called after parameters have been set + // must return true to indicate success and be available for activation + virtual LLMotionInitStatus onInitialize(LLCharacter *character); - // called when a motion is activated - // must return TRUE to indicate success, or else - // it will be deactivated - virtual BOOL onActivate(); + // called when a motion is activated + // must return TRUE to indicate success, or else + // it will be deactivated + virtual BOOL onActivate(); - // called per time step - // must return TRUE while it is active, and - // must return FALSE when the motion is completed. - virtual BOOL onUpdate(F32 time, U8* joint_mask); + // called per time step + // must return TRUE while it is active, and + // must return FALSE when the motion is completed. + virtual BOOL onUpdate(F32 time, U8* joint_mask); - // called when a motion is deactivated - virtual void onDeactivate(); + // called when a motion is deactivated + virtual void onDeactivate(); public: - //------------------------------------------------------------------------- - // joint states to be animated - //------------------------------------------------------------------------- - LLCharacter *mCharacter; + //------------------------------------------------------------------------- + // joint states to be animated + //------------------------------------------------------------------------- + LLCharacter *mCharacter; - LLJoint *mTorsoJoint; - LLJoint *mHeadJoint; - LLJoint *mRootJoint; - LLJoint *mPelvisJoint; + LLJoint *mTorsoJoint; + LLJoint *mHeadJoint; + LLJoint *mRootJoint; + LLJoint *mPelvisJoint; - LLPointer<LLJointState> mTorsoState; - LLPointer<LLJointState> mNeckState; - LLPointer<LLJointState> mHeadState; + LLPointer<LLJointState> mTorsoState; + LLPointer<LLJointState> mNeckState; + LLPointer<LLJointState> mHeadState; - LLQuaternion mLastHeadRot; + LLQuaternion mLastHeadRot; }; //----------------------------------------------------------------------------- // class LLEyeMotion //----------------------------------------------------------------------------- class LLEyeMotion : - public LLMotion + public LLMotion { public: - // Constructor - LLEyeMotion(const LLUUID &id); + // Constructor + LLEyeMotion(const LLUUID &id); - // Destructor - virtual ~LLEyeMotion(); + // Destructor + virtual ~LLEyeMotion(); public: - //------------------------------------------------------------------------- - // functions to support MotionController and MotionRegistry - //------------------------------------------------------------------------- + //------------------------------------------------------------------------- + // functions to support MotionController and MotionRegistry + //------------------------------------------------------------------------- - // static constructor - // all subclasses must implement such a function and register it - static LLMotion *create( const LLUUID &id) { return new LLEyeMotion(id); } + // static constructor + // all subclasses must implement such a function and register it + static LLMotion *create( const LLUUID &id) { return new LLEyeMotion(id); } public: - //------------------------------------------------------------------------- - // animation callbacks to be implemented by subclasses - //------------------------------------------------------------------------- + //------------------------------------------------------------------------- + // animation callbacks to be implemented by subclasses + //------------------------------------------------------------------------- - // motions must specify whether or not they loop - virtual BOOL getLoop() { return TRUE; } + // motions must specify whether or not they loop + virtual BOOL getLoop() { return TRUE; } - // motions must report their total duration - virtual F32 getDuration() { return 0.0; } + // motions must report their total duration + virtual F32 getDuration() { return 0.0; } - // motions must report their "ease in" duration - virtual F32 getEaseInDuration() { return 0.5f; } + // motions must report their "ease in" duration + virtual F32 getEaseInDuration() { return 0.5f; } - // motions must report their "ease out" duration. - virtual F32 getEaseOutDuration() { return 0.5f; } + // motions must report their "ease out" duration. + virtual F32 getEaseOutDuration() { return 0.5f; } - // called to determine when a motion should be activated/deactivated based on avatar pixel coverage - virtual F32 getMinPixelArea() { return MIN_REQUIRED_PIXEL_AREA_EYE; } + // called to determine when a motion should be activated/deactivated based on avatar pixel coverage + virtual F32 getMinPixelArea() { return MIN_REQUIRED_PIXEL_AREA_EYE; } - // motions must report their priority - virtual LLJoint::JointPriority getPriority() { return LLJoint::MEDIUM_PRIORITY; } + // motions must report their priority + virtual LLJoint::JointPriority getPriority() { return LLJoint::MEDIUM_PRIORITY; } - virtual LLMotionBlendType getBlendType() { return NORMAL_BLEND; } + virtual LLMotionBlendType getBlendType() { return NORMAL_BLEND; } - // run-time (post constructor) initialization, - // called after parameters have been set - // must return true to indicate success and be available for activation - virtual LLMotionInitStatus onInitialize(LLCharacter *character); + // run-time (post constructor) initialization, + // called after parameters have been set + // must return true to indicate success and be available for activation + virtual LLMotionInitStatus onInitialize(LLCharacter *character); - // called when a motion is activated - // must return TRUE to indicate success, or else - // it will be deactivated - virtual BOOL onActivate(); + // called when a motion is activated + // must return TRUE to indicate success, or else + // it will be deactivated + virtual BOOL onActivate(); void adjustEyeTarget(LLVector3* targetPos, LLJointState& left_eye_state, LLJointState& right_eye_state); - // called per time step - // must return TRUE while it is active, and - // must return FALSE when the motion is completed. - virtual BOOL onUpdate(F32 time, U8* joint_mask); + // called per time step + // must return TRUE while it is active, and + // must return FALSE when the motion is completed. + virtual BOOL onUpdate(F32 time, U8* joint_mask); - // called when a motion is deactivated - virtual void onDeactivate(); + // called when a motion is deactivated + virtual void onDeactivate(); public: - //------------------------------------------------------------------------- - // joint states to be animated - //------------------------------------------------------------------------- - LLCharacter *mCharacter; - - LLJoint *mHeadJoint; - LLPointer<LLJointState> mLeftEyeState; - LLPointer<LLJointState> mRightEyeState; - LLPointer<LLJointState> mAltLeftEyeState; - LLPointer<LLJointState> mAltRightEyeState; - - LLFrameTimer mEyeJitterTimer; - F32 mEyeJitterTime; - F32 mEyeJitterYaw; - F32 mEyeJitterPitch; - F32 mEyeLookAwayTime; - F32 mEyeLookAwayYaw; - F32 mEyeLookAwayPitch; - - // eye blinking - LLFrameTimer mEyeBlinkTimer; - F32 mEyeBlinkTime; - BOOL mEyesClosed; + //------------------------------------------------------------------------- + // joint states to be animated + //------------------------------------------------------------------------- + LLCharacter *mCharacter; + + LLJoint *mHeadJoint; + LLPointer<LLJointState> mLeftEyeState; + LLPointer<LLJointState> mRightEyeState; + LLPointer<LLJointState> mAltLeftEyeState; + LLPointer<LLJointState> mAltRightEyeState; + + LLFrameTimer mEyeJitterTimer; + F32 mEyeJitterTime; + F32 mEyeJitterYaw; + F32 mEyeJitterPitch; + F32 mEyeLookAwayTime; + F32 mEyeLookAwayYaw; + F32 mEyeLookAwayPitch; + + // eye blinking + LLFrameTimer mEyeBlinkTimer; + F32 mEyeBlinkTime; + BOOL mEyesClosed; }; #endif // LL_LLHEADROTMOTION_H diff --git a/indra/llcharacter/lljoint.cpp b/indra/llcharacter/lljoint.cpp index 06f3bedf85..4e66777c11 100644 --- a/indra/llcharacter/lljoint.cpp +++ b/indra/llcharacter/lljoint.cpp @@ -1,25 +1,25 @@ -/** +/** * @file lljoint.cpp * @brief Implementation of LLJoint class. * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -38,61 +38,61 @@ S32 LLJoint::sNumUpdates = 0; S32 LLJoint::sNumTouches = 0; -template <class T> +template <class T> bool attachment_map_iter_compare_key(const T& a, const T& b) { - return a.first < b.first; + return a.first < b.first; } bool LLVector3OverrideMap::findActiveOverride(LLUUID& mesh_id, LLVector3& pos) const { - pos = LLVector3(0,0,0); - mesh_id = LLUUID(); - bool found = false; - - map_type::const_iterator it = std::max_element(m_map.begin(), - m_map.end(), - attachment_map_iter_compare_key<map_type::value_type>); - if (it != m_map.end()) - { - found = true; - pos = it->second; - mesh_id = it->first; - } - return found; + pos = LLVector3(0,0,0); + mesh_id = LLUUID(); + bool found = false; + + map_type::const_iterator it = std::max_element(m_map.begin(), + m_map.end(), + attachment_map_iter_compare_key<map_type::value_type>); + if (it != m_map.end()) + { + found = true; + pos = it->second; + mesh_id = it->first; + } + return found; } void LLVector3OverrideMap::showJointVector3Overrides( std::ostringstream& os ) const { - map_type::const_iterator max_it = std::max_element(m_map.begin(), - m_map.end(), - attachment_map_iter_compare_key<map_type::value_type>); - for (const map_type::value_type& pos_pair : m_map) - { - const LLVector3& pos = pos_pair.second; - os << " " << "[" << pos_pair.first <<": " << pos << "]" << ((pos_pair==(*max_it)) ? "*" : ""); - } + map_type::const_iterator max_it = std::max_element(m_map.begin(), + m_map.end(), + attachment_map_iter_compare_key<map_type::value_type>); + for (const map_type::value_type& pos_pair : m_map) + { + const LLVector3& pos = pos_pair.second; + os << " " << "[" << pos_pair.first <<": " << pos << "]" << ((pos_pair==(*max_it)) ? "*" : ""); + } } U32 LLVector3OverrideMap::count() const { - return m_map.size(); + return m_map.size(); } void LLVector3OverrideMap::add(const LLUUID& mesh_id, const LLVector3& pos) { - m_map[mesh_id] = pos; + m_map[mesh_id] = pos; } bool LLVector3OverrideMap::remove(const LLUUID& mesh_id) { - U32 remove_count = m_map.erase(mesh_id); - return (remove_count > 0); + U32 remove_count = m_map.erase(mesh_id); + return (remove_count > 0); } void LLVector3OverrideMap::clear() { - m_map.clear(); + m_map.clear(); } //----------------------------------------------------------------------------- @@ -103,28 +103,28 @@ void LLVector3OverrideMap::clear() void LLJoint::init() { - mName = "unnamed"; - mParent = NULL; - mXform.setScaleChildOffset(TRUE); - mXform.setScale(LLVector3(1.0f, 1.0f, 1.0f)); - mDirtyFlags = MATRIX_DIRTY | ROTATION_DIRTY | POSITION_DIRTY; - mUpdateXform = TRUE; + mName = "unnamed"; + mParent = NULL; + mXform.setScaleChildOffset(TRUE); + mXform.setScale(LLVector3(1.0f, 1.0f, 1.0f)); + mDirtyFlags = MATRIX_DIRTY | ROTATION_DIRTY | POSITION_DIRTY; + mUpdateXform = TRUE; mSupport = SUPPORT_BASE; mEnd = LLVector3(0.0f, 0.0f, 0.0f); } LLJoint::LLJoint() : - mJointNum(-1) + mJointNum(-1) { - init(); - touch(); + init(); + touch(); } LLJoint::LLJoint(S32 joint_num) : - mJointNum(joint_num) + mJointNum(joint_num) { - init(); - touch(); + init(); + touch(); } //----------------------------------------------------------------------------- @@ -132,17 +132,17 @@ LLJoint::LLJoint(S32 joint_num) : // Class Constructor //----------------------------------------------------------------------------- LLJoint::LLJoint(const std::string &name, LLJoint *parent) : - mJointNum(-2) + mJointNum(-2) { - init(); - mUpdateXform = FALSE; + init(); + mUpdateXform = FALSE; - setName(name); - if (parent) - { - parent->addChild( this ); - } - touch(); + setName(name); + if (parent) + { + parent->addChild( this ); + } + touch(); } //----------------------------------------------------------------------------- @@ -151,11 +151,11 @@ LLJoint::LLJoint(const std::string &name, LLJoint *parent) : //----------------------------------------------------------------------------- LLJoint::~LLJoint() { - if (mParent) - { - mParent->removeChild( this ); - } - removeAllChildren(); + if (mParent) + { + mParent->removeChild( this ); + } + removeAllChildren(); } @@ -164,11 +164,11 @@ LLJoint::~LLJoint() //----------------------------------------------------------------------------- void LLJoint::setup(const std::string &name, LLJoint *parent) { - setName(name); - if (parent) - { - parent->addChild( this ); - } + setName(name); + if (parent) + { + parent->addChild( this ); + } } //----------------------------------------------------------------------------- @@ -190,7 +190,7 @@ void LLJoint::setSupport(const std::string& support_name) setSupport(SUPPORT_BASE); } } - + //----------------------------------------------------------------------------- // touch() @@ -198,21 +198,21 @@ void LLJoint::setSupport(const std::string& support_name) //----------------------------------------------------------------------------- void LLJoint::touch(U32 flags) { - if ((flags | mDirtyFlags) != mDirtyFlags) - { - sNumTouches++; - mDirtyFlags |= flags; - U32 child_flags = flags; - if (flags & ROTATION_DIRTY) - { - child_flags |= POSITION_DIRTY; - } + if ((flags | mDirtyFlags) != mDirtyFlags) + { + sNumTouches++; + mDirtyFlags |= flags; + U32 child_flags = flags; + if (flags & ROTATION_DIRTY) + { + child_flags |= POSITION_DIRTY; + } - for (LLJoint* joint : mChildren) - { - joint->touch(child_flags); - } - } + for (LLJoint* joint : mChildren) + { + joint->touch(child_flags); + } + } } //----------------------------------------------------------------------------- @@ -232,11 +232,11 @@ void LLJoint::setJointNum(S32 joint_num) //----------------------------------------------------------------------------- LLJoint *LLJoint::getRoot() { - if ( getParent() == NULL ) - { - return this; - } - return getParent()->getRoot(); + if ( getParent() == NULL ) + { + return this; + } + return getParent()->getRoot(); } @@ -245,19 +245,19 @@ LLJoint *LLJoint::getRoot() //----------------------------------------------------------------------------- LLJoint *LLJoint::findJoint( const std::string &name ) { - if (name == getName()) - return this; + if (name == getName()) + return this; - for (LLJoint* joint : mChildren) - { - LLJoint *found = joint->findJoint(name); - if (found) - { - return found; - } - } + for (LLJoint* joint : mChildren) + { + LLJoint *found = joint->findJoint(name); + if (found) + { + return found; + } + } - return NULL; + return NULL; } @@ -266,13 +266,13 @@ LLJoint *LLJoint::findJoint( const std::string &name ) //-------------------------------------------------------------------- void LLJoint::addChild(LLJoint* joint) { - if (joint->mParent) - joint->mParent->removeChild(joint); + if (joint->mParent) + joint->mParent->removeChild(joint); - mChildren.push_back(joint); - joint->mXform.setParent(&mXform); - joint->mParent = this; - joint->touch(); + mChildren.push_back(joint); + joint->mXform.setParent(&mXform); + joint->mParent = this; + joint->touch(); } @@ -281,15 +281,15 @@ void LLJoint::addChild(LLJoint* joint) //-------------------------------------------------------------------- void LLJoint::removeChild(LLJoint* joint) { - joints_t::iterator iter = std::find(mChildren.begin(), mChildren.end(), joint); - if (iter != mChildren.end()) - { - mChildren.erase(iter); - - joint->mXform.setParent(NULL); - joint->mParent = NULL; - joint->touch(); - } + joints_t::iterator iter = std::find(mChildren.begin(), mChildren.end(), joint); + if (iter != mChildren.end()) + { + mChildren.erase(iter); + + joint->mXform.setParent(NULL); + joint->mParent = NULL; + joint->touch(); + } } @@ -298,16 +298,16 @@ void LLJoint::removeChild(LLJoint* joint) //-------------------------------------------------------------------- void LLJoint::removeAllChildren() { - for (LLJoint* joint : mChildren) - { - if (joint) + for (LLJoint* joint : mChildren) + { + if (joint) { - joint->mXform.setParent(NULL); - joint->mParent = NULL; - joint->touch(); + joint->mXform.setParent(NULL); + joint->mParent = NULL; + joint->touch(); //delete joint; } - } + } mChildren.clear(); } @@ -317,7 +317,7 @@ void LLJoint::removeAllChildren() //-------------------------------------------------------------------- const LLVector3& LLJoint::getPosition() { - return mXform.getPosition(); + return mXform.getPosition(); } bool do_debug_joint(const std::string& name) @@ -339,7 +339,7 @@ void LLJoint::setPosition( const LLVector3& requested_pos, bool apply_attachment LLVector3 active_override; LLUUID mesh_id; if (apply_attachment_overrides && m_attachmentPosOverrides.findActiveOverride(mesh_id,active_override)) - { + { if (pos != active_override && do_debug_joint(getName())) { LLScopedContextString str("setPosition"); @@ -348,15 +348,15 @@ void LLJoint::setPosition( const LLVector3& requested_pos, bool apply_attachment } pos = active_override; } - if ((pos != getPosition()) && do_debug_joint(getName())) - { + if ((pos != getPosition()) && do_debug_joint(getName())) + { LLScopedContextString str("setPosition"); LLCallStack cs; LLContextStatus con_status; LL_DEBUGS("Avatar") << " joint " << getName() << " set pos " << pos << LL_ENDL; LL_DEBUGS("Avatar") << "CONTEXT:\n" << "====================\n" << con_status << "====================" << LL_ENDL; LL_DEBUGS("Avatar") << "STACK:\n" << "====================\n" << cs << "====================" << LL_ENDL; - } + } if (pos != getPosition()) { mXform.setPosition(pos); @@ -404,14 +404,14 @@ bool LLJoint::aboveJointPosThreshold(const LLVector3& pos) const { LLVector3 diff = pos - getDefaultPosition(); const F32 max_joint_pos_offset = LL_JOINT_TRESHOLD_POS_OFFSET; // 0.1 mm - return diff.lengthSquared() > max_joint_pos_offset * max_joint_pos_offset; + return diff.lengthSquared() > max_joint_pos_offset * max_joint_pos_offset; } bool LLJoint::aboveJointScaleThreshold(const LLVector3& scale) const { LLVector3 diff = scale - getDefaultScale(); - const F32 max_joint_scale_offset = 0.0001f; // 0.1 mm - return diff.lengthSquared() > max_joint_scale_offset * max_joint_scale_offset; + const F32 max_joint_scale_offset = 0.0001f; // 0.1 mm + return diff.lengthSquared() > max_joint_scale_offset * max_joint_scale_offset; } //-------------------------------------------------------------------- @@ -420,28 +420,28 @@ bool LLJoint::aboveJointScaleThreshold(const LLVector3& scale) const void LLJoint::addAttachmentPosOverride( const LLVector3& pos, const LLUUID& mesh_id, const std::string& av_info, bool& active_override_changed ) { active_override_changed = false; - if (mesh_id.isNull()) - { - return; - } + if (mesh_id.isNull()) + { + return; + } LLVector3 before_pos; LLUUID before_mesh_id; bool has_active_override_before = hasAttachmentPosOverride( before_pos, before_mesh_id ); - if (!m_attachmentPosOverrides.count()) - { - if (do_debug_joint(getName())) - { - LL_DEBUGS("Avatar") << "av " << av_info << " joint " << getName() << " saving m_posBeforeOverrides " << getPosition() << LL_ENDL; - } - m_posBeforeOverrides = getPosition(); - } - m_attachmentPosOverrides.add(mesh_id,pos); + if (!m_attachmentPosOverrides.count()) + { + if (do_debug_joint(getName())) + { + LL_DEBUGS("Avatar") << "av " << av_info << " joint " << getName() << " saving m_posBeforeOverrides " << getPosition() << LL_ENDL; + } + m_posBeforeOverrides = getPosition(); + } + m_attachmentPosOverrides.add(mesh_id,pos); LLVector3 after_pos; LLUUID after_mesh_id; hasAttachmentPosOverride(after_pos, after_mesh_id); if (!has_active_override_before || (after_pos != before_pos)) { - active_override_changed = true; + active_override_changed = true; if (do_debug_joint(getName())) { LL_DEBUGS("Avatar") << "av " << av_info << " joint " << getName() << " addAttachmentPosOverride for mesh " << mesh_id << " pos " << pos << LL_ENDL; @@ -456,15 +456,15 @@ void LLJoint::addAttachmentPosOverride( const LLVector3& pos, const LLUUID& mesh void LLJoint::removeAttachmentPosOverride( const LLUUID& mesh_id, const std::string& av_info, bool& active_override_changed ) { active_override_changed = false; - if (mesh_id.isNull()) - { - return; - } + if (mesh_id.isNull()) + { + return; + } LLVector3 before_pos; LLUUID before_mesh_id; hasAttachmentPosOverride( before_pos, before_mesh_id ); - if (m_attachmentPosOverrides.remove(mesh_id)) - { + if (m_attachmentPosOverrides.remove(mesh_id)) + { LLVector3 after_pos; LLUUID after_mesh_id; bool has_active_override_after = hasAttachmentPosOverride(after_pos, after_mesh_id); @@ -479,7 +479,7 @@ void LLJoint::removeAttachmentPosOverride( const LLUUID& mesh_id, const std::str } updatePos(av_info); } - } + } } //-------------------------------------------------------------------- @@ -487,7 +487,7 @@ void LLJoint::removeAttachmentPosOverride( const LLUUID& mesh_id, const std::str //-------------------------------------------------------------------- bool LLJoint::hasAttachmentPosOverride( LLVector3& pos, LLUUID& mesh_id ) const { - return m_attachmentPosOverrides.findActiveOverride(mesh_id,pos); + return m_attachmentPosOverrides.findActiveOverride(mesh_id,pos); } //-------------------------------------------------------------------- @@ -495,11 +495,11 @@ bool LLJoint::hasAttachmentPosOverride( LLVector3& pos, LLUUID& mesh_id ) const //-------------------------------------------------------------------- void LLJoint::clearAttachmentPosOverrides() { - if (m_attachmentPosOverrides.count()) - { - m_attachmentPosOverrides.clear(); - setPosition(m_posBeforeOverrides); - } + if (m_attachmentPosOverrides.count()) + { + m_attachmentPosOverrides.clear(); + setPosition(m_posBeforeOverrides); + } } //-------------------------------------------------------------------- @@ -514,7 +514,7 @@ void LLJoint::getAllAttachmentPosOverrides(S32& num_pos_overrides, distinct_pos_overrides.insert(pos_override_pair.second); } } - + //-------------------------------------------------------------------- // getAllAttachmentScaleOverrides() //-------------------------------------------------------------------- @@ -527,7 +527,7 @@ void LLJoint::getAllAttachmentScaleOverrides(S32& num_scale_overrides, distinct_scale_overrides.insert(scale_override_pair.second); } } - + //-------------------------------------------------------------------- // showAttachmentPosOverrides() //-------------------------------------------------------------------- @@ -540,7 +540,7 @@ void LLJoint::showAttachmentPosOverrides(const std::string& av_info) const U32 count = m_attachmentPosOverrides.count(); if (count==1) { - LLVector3OverrideMap::map_type::const_iterator it = m_attachmentPosOverrides.getMap().begin(); + LLVector3OverrideMap::map_type::const_iterator it = m_attachmentPosOverrides.getMap().begin(); std::string highlight = (has_active_override && (it->second == active_override)) ? "*" : ""; LL_DEBUGS("Avatar") << "av " << av_info << " joint " << getName() << " has single attachment pos override " << highlight << "" << it->second << " default " << mDefaultPosition << LL_ENDL; @@ -548,7 +548,7 @@ void LLJoint::showAttachmentPosOverrides(const std::string& av_info) const else if (count>1) { LL_DEBUGS("Avatar") << "av " << av_info << " joint " << getName() << " has " << count << " attachment pos overrides" << LL_ENDL; - std::set<LLVector3> distinct_offsets; + std::set<LLVector3> distinct_offsets; for (const LLVector3OverrideMap::map_type::value_type& pos_override_pair : m_attachmentPosOverrides.getMap()) { distinct_offsets.insert(pos_override_pair.second); @@ -566,7 +566,7 @@ void LLJoint::showAttachmentPosOverrides(const std::string& av_info) const std::string highlight = (has_active_override && offset == active_override) ? "*" : ""; LL_DEBUGS("Avatar") << " POS " << highlight << "" << offset << " default " << mDefaultPosition << LL_ENDL; } - } + } } //-------------------------------------------------------------------- @@ -574,25 +574,25 @@ void LLJoint::showAttachmentPosOverrides(const std::string& av_info) const //-------------------------------------------------------------------- void LLJoint::updatePos(const std::string& av_info) { - LLVector3 pos, found_pos; - LLUUID mesh_id; - if (m_attachmentPosOverrides.findActiveOverride(mesh_id,found_pos)) - { + LLVector3 pos, found_pos; + LLUUID mesh_id; + if (m_attachmentPosOverrides.findActiveOverride(mesh_id,found_pos)) + { if (do_debug_joint(getName())) { LL_DEBUGS("Avatar") << "av " << av_info << " joint " << getName() << " updatePos, winner of " << m_attachmentPosOverrides.count() << " is mesh " << mesh_id << " pos " << found_pos << LL_ENDL; } - pos = found_pos; - } - else - { + pos = found_pos; + } + else + { if (do_debug_joint(getName())) { LL_DEBUGS("Avatar") << "av " << av_info << " joint " << getName() << " updatePos, winner is posBeforeOverrides " << m_posBeforeOverrides << LL_ENDL; } - pos = m_posBeforeOverrides; - } - setPosition(pos); + pos = m_posBeforeOverrides; + } + setPosition(pos); } //-------------------------------------------------------------------- @@ -600,25 +600,25 @@ void LLJoint::updatePos(const std::string& av_info) //-------------------------------------------------------------------- void LLJoint::updateScale(const std::string& av_info) { - LLVector3 scale, found_scale; - LLUUID mesh_id; - if (m_attachmentScaleOverrides.findActiveOverride(mesh_id,found_scale)) - { + LLVector3 scale, found_scale; + LLUUID mesh_id; + if (m_attachmentScaleOverrides.findActiveOverride(mesh_id,found_scale)) + { if (do_debug_joint(getName())) { LL_DEBUGS("Avatar") << "av " << av_info << " joint " << getName() << " updateScale, winner of " << m_attachmentScaleOverrides.count() << " is mesh " << mesh_id << " scale " << found_scale << LL_ENDL; } - scale = found_scale; - } - else - { + scale = found_scale; + } + else + { if (do_debug_joint(getName())) { LL_DEBUGS("Avatar") << "av " << av_info << " joint " << getName() << " updateScale, winner is scaleBeforeOverrides " << m_scaleBeforeOverrides << LL_ENDL; } - scale = m_scaleBeforeOverrides; - } - setScale(scale); + scale = m_scaleBeforeOverrides; + } + setScale(scale); } //-------------------------------------------------------------------- @@ -626,24 +626,24 @@ void LLJoint::updateScale(const std::string& av_info) //-------------------------------------------------------------------- void LLJoint::addAttachmentScaleOverride( const LLVector3& scale, const LLUUID& mesh_id, const std::string& av_info ) { - if (mesh_id.isNull()) - { - return; - } - if (!m_attachmentScaleOverrides.count()) - { - if (do_debug_joint(getName())) - { - LL_DEBUGS("Avatar") << "av " << av_info << " joint " << getName() << " saving m_scaleBeforeOverrides " << getScale() << LL_ENDL; - } - m_scaleBeforeOverrides = getScale(); - } - m_attachmentScaleOverrides.add(mesh_id,scale); - if (do_debug_joint(getName())) - { - LL_DEBUGS("Avatar") << "av " << av_info << " joint " << getName() << " addAttachmentScaleOverride for mesh " << mesh_id << " scale " << scale << LL_ENDL; - } - updateScale(av_info); + if (mesh_id.isNull()) + { + return; + } + if (!m_attachmentScaleOverrides.count()) + { + if (do_debug_joint(getName())) + { + LL_DEBUGS("Avatar") << "av " << av_info << " joint " << getName() << " saving m_scaleBeforeOverrides " << getScale() << LL_ENDL; + } + m_scaleBeforeOverrides = getScale(); + } + m_attachmentScaleOverrides.add(mesh_id,scale); + if (do_debug_joint(getName())) + { + LL_DEBUGS("Avatar") << "av " << av_info << " joint " << getName() << " addAttachmentScaleOverride for mesh " << mesh_id << " scale " << scale << LL_ENDL; + } + updateScale(av_info); } //-------------------------------------------------------------------- @@ -651,20 +651,20 @@ void LLJoint::addAttachmentScaleOverride( const LLVector3& scale, const LLUUID& //-------------------------------------------------------------------- void LLJoint::removeAttachmentScaleOverride( const LLUUID& mesh_id, const std::string& av_info ) { - if (mesh_id.isNull()) - { - return; - } - if (m_attachmentScaleOverrides.remove(mesh_id)) - { - if (do_debug_joint(getName())) - { - LL_DEBUGS("Avatar") << "av " << av_info << " joint " << getName() - << " removeAttachmentScaleOverride for " << mesh_id << LL_ENDL; - showJointScaleOverrides(*this, "remove", av_info); - } - updateScale(av_info); - } + if (mesh_id.isNull()) + { + return; + } + if (m_attachmentScaleOverrides.remove(mesh_id)) + { + if (do_debug_joint(getName())) + { + LL_DEBUGS("Avatar") << "av " << av_info << " joint " << getName() + << " removeAttachmentScaleOverride for " << mesh_id << LL_ENDL; + showJointScaleOverrides(*this, "remove", av_info); + } + updateScale(av_info); + } } //-------------------------------------------------------------------- @@ -672,7 +672,7 @@ void LLJoint::removeAttachmentScaleOverride( const LLUUID& mesh_id, const std::s //-------------------------------------------------------------------- bool LLJoint::hasAttachmentScaleOverride( LLVector3& scale, LLUUID& mesh_id ) const { - return m_attachmentScaleOverrides.findActiveOverride(mesh_id,scale); + return m_attachmentScaleOverrides.findActiveOverride(mesh_id,scale); } //-------------------------------------------------------------------- @@ -680,11 +680,11 @@ bool LLJoint::hasAttachmentScaleOverride( LLVector3& scale, LLUUID& mesh_id ) co //-------------------------------------------------------------------- void LLJoint::clearAttachmentScaleOverrides() { - if (m_attachmentScaleOverrides.count()) - { - m_attachmentScaleOverrides.clear(); - setScale(m_scaleBeforeOverrides); - } + if (m_attachmentScaleOverrides.count()) + { + m_attachmentScaleOverrides.clear(); + setScale(m_scaleBeforeOverrides); + } } //-------------------------------------------------------------------- @@ -699,7 +699,7 @@ void LLJoint::showAttachmentScaleOverrides(const std::string& av_info) const U32 count = m_attachmentScaleOverrides.count(); if (count==1) { - LLVector3OverrideMap::map_type::const_iterator it = m_attachmentScaleOverrides.getMap().begin(); + LLVector3OverrideMap::map_type::const_iterator it = m_attachmentScaleOverrides.getMap().begin(); std::string highlight = (has_active_override && (it->second == active_override)) ? "*" : ""; LL_DEBUGS("Avatar") << "av " << av_info << " joint " << getName() << " has single attachment scale override " << highlight << "" << it->second << " default " << mDefaultScale << LL_ENDL; @@ -707,7 +707,7 @@ void LLJoint::showAttachmentScaleOverrides(const std::string& av_info) const else if (count>1) { LL_DEBUGS("Avatar") << "av " << av_info << " joint " << getName() << " has " << count << " attachment scale overrides" << LL_ENDL; - std::set<LLVector3> distinct_offsets; + std::set<LLVector3> distinct_offsets; for (const LLVector3OverrideMap::map_type::value_type& scale_override_pair : m_attachmentScaleOverrides.getMap()) { distinct_offsets.insert(scale_override_pair.second); @@ -725,7 +725,7 @@ void LLJoint::showAttachmentScaleOverrides(const std::string& av_info) const std::string highlight = (has_active_override && offset == active_override) ? "*" : ""; LL_DEBUGS("Avatar") << " POS " << highlight << "" << offset << " default " << mDefaultScale << LL_ENDL; } - } + } } // init static @@ -750,8 +750,8 @@ void LLJoint::setDebugJointNames(const std::string& names_string) //-------------------------------------------------------------------- LLVector3 LLJoint::getWorldPosition() { - updateWorldPRSParent(); - return mXform.getWorldPosition(); + updateWorldPRSParent(); + return mXform.getWorldPosition(); } //----------------------------------------------------------------------------- @@ -759,34 +759,34 @@ LLVector3 LLJoint::getWorldPosition() //----------------------------------------------------------------------------- LLVector3 LLJoint::getLastWorldPosition() { - return mXform.getWorldPosition(); + return mXform.getWorldPosition(); } //-------------------------------------------------------------------- // setWorldPosition() //-------------------------------------------------------------------- void LLJoint::setWorldPosition( const LLVector3& pos ) { - if (mParent == NULL) - { - this->setPosition( pos ); - return; - } + if (mParent == NULL) + { + this->setPosition( pos ); + return; + } - LLMatrix4 temp_matrix = getWorldMatrix(); - temp_matrix.mMatrix[VW][VX] = pos.mV[VX]; - temp_matrix.mMatrix[VW][VY] = pos.mV[VY]; - temp_matrix.mMatrix[VW][VZ] = pos.mV[VZ]; + LLMatrix4 temp_matrix = getWorldMatrix(); + temp_matrix.mMatrix[VW][VX] = pos.mV[VX]; + temp_matrix.mMatrix[VW][VY] = pos.mV[VY]; + temp_matrix.mMatrix[VW][VZ] = pos.mV[VZ]; - LLMatrix4 parentWorldMatrix = mParent->getWorldMatrix(); - LLMatrix4 invParentWorldMatrix = parentWorldMatrix.invert(); + LLMatrix4 parentWorldMatrix = mParent->getWorldMatrix(); + LLMatrix4 invParentWorldMatrix = parentWorldMatrix.invert(); - temp_matrix *= invParentWorldMatrix; + temp_matrix *= invParentWorldMatrix; - LLVector3 localPos( temp_matrix.mMatrix[VW][VX], - temp_matrix.mMatrix[VW][VY], - temp_matrix.mMatrix[VW][VZ] ); + LLVector3 localPos( temp_matrix.mMatrix[VW][VX], + temp_matrix.mMatrix[VW][VY], + temp_matrix.mMatrix[VW][VZ] ); - setPosition( localPos ); + setPosition( localPos ); } @@ -795,7 +795,7 @@ void LLJoint::setWorldPosition( const LLVector3& pos ) //-------------------------------------------------------------------- const LLQuaternion& LLJoint::getRotation() { - return mXform.getRotation(); + return mXform.getRotation(); } @@ -804,14 +804,14 @@ const LLQuaternion& LLJoint::getRotation() //-------------------------------------------------------------------- void LLJoint::setRotation( const LLQuaternion& rot ) { - if (rot.isFinite()) - { - // if (mXform.getRotation() != rot) - { - mXform.setRotation(rot); - touch(MATRIX_DIRTY | ROTATION_DIRTY); - } - } + if (rot.isFinite()) + { + // if (mXform.getRotation() != rot) + { + mXform.setRotation(rot); + touch(MATRIX_DIRTY | ROTATION_DIRTY); + } + } } @@ -820,9 +820,9 @@ void LLJoint::setRotation( const LLQuaternion& rot ) //-------------------------------------------------------------------- LLQuaternion LLJoint::getWorldRotation() { - updateWorldPRSParent(); + updateWorldPRSParent(); - return mXform.getWorldRotation(); + return mXform.getWorldRotation(); } //----------------------------------------------------------------------------- @@ -830,7 +830,7 @@ LLQuaternion LLJoint::getWorldRotation() //----------------------------------------------------------------------------- LLQuaternion LLJoint::getLastWorldRotation() { - return mXform.getWorldRotation(); + return mXform.getWorldRotation(); } //-------------------------------------------------------------------- @@ -838,24 +838,24 @@ LLQuaternion LLJoint::getLastWorldRotation() //-------------------------------------------------------------------- void LLJoint::setWorldRotation( const LLQuaternion& rot ) { - if (mParent == NULL) - { - this->setRotation( rot ); - return; - } + if (mParent == NULL) + { + this->setRotation( rot ); + return; + } - LLMatrix4 temp_mat(rot); + LLMatrix4 temp_mat(rot); - LLMatrix4 parentWorldMatrix = mParent->getWorldMatrix(); - parentWorldMatrix.mMatrix[VW][VX] = 0; - parentWorldMatrix.mMatrix[VW][VY] = 0; - parentWorldMatrix.mMatrix[VW][VZ] = 0; + LLMatrix4 parentWorldMatrix = mParent->getWorldMatrix(); + parentWorldMatrix.mMatrix[VW][VX] = 0; + parentWorldMatrix.mMatrix[VW][VY] = 0; + parentWorldMatrix.mMatrix[VW][VZ] = 0; - LLMatrix4 invParentWorldMatrix = parentWorldMatrix.invert(); + LLMatrix4 invParentWorldMatrix = parentWorldMatrix.invert(); - temp_mat *= invParentWorldMatrix; + temp_mat *= invParentWorldMatrix; - setRotation(LLQuaternion(temp_mat)); + setRotation(LLQuaternion(temp_mat)); } @@ -876,7 +876,7 @@ void LLJoint::setScale( const LLVector3& requested_scale, bool apply_attachment_ LLUUID mesh_id; LLVector3 active_override; if (apply_attachment_overrides && m_attachmentScaleOverrides.findActiveOverride(mesh_id,active_override)) - { + { if (scale != active_override && do_debug_joint(getName())) { LLScopedContextString str("setScale"); @@ -885,15 +885,15 @@ void LLJoint::setScale( const LLVector3& requested_scale, bool apply_attachment_ } scale = active_override; } - if ((mXform.getScale() != scale) && do_debug_joint(getName())) - { + if ((mXform.getScale() != scale) && do_debug_joint(getName())) + { LLScopedContextString str("setScale"); LLCallStack cs; LLContextStatus con_status; LL_DEBUGS("Avatar") << " joint " << getName() << " set scale " << scale << LL_ENDL; LL_DEBUGS("Avatar") << "CONTEXT:\n" << "====================\n" << con_status << LL_ENDL; LL_DEBUGS("Avatar") << "STACK:\n" << "====================\n" << cs << "====================" << LL_ENDL; - } + } mXform.setScale(scale); touch(); @@ -906,9 +906,9 @@ void LLJoint::setScale( const LLVector3& requested_scale, bool apply_attachment_ //-------------------------------------------------------------------- const LLMatrix4 &LLJoint::getWorldMatrix() { - updateWorldMatrixParent(); + updateWorldMatrixParent(); - return mXform.getWorldMatrix(); + return mXform.getWorldMatrix(); } const LLMatrix4a& LLJoint::getWorldMatrix4a() @@ -924,17 +924,17 @@ const LLMatrix4a& LLJoint::getWorldMatrix4a() //-------------------------------------------------------------------- void LLJoint::setWorldMatrix( const LLMatrix4& mat ) { - LL_INFOS() << "WARNING: LLJoint::setWorldMatrix() not correctly implemented yet" << LL_ENDL; - // extract global translation - LLVector3 trans( mat.mMatrix[VW][VX], - mat.mMatrix[VW][VY], - mat.mMatrix[VW][VZ] ); + LL_INFOS() << "WARNING: LLJoint::setWorldMatrix() not correctly implemented yet" << LL_ENDL; + // extract global translation + LLVector3 trans( mat.mMatrix[VW][VX], + mat.mMatrix[VW][VY], + mat.mMatrix[VW][VZ] ); - // extract global rotation - LLQuaternion rot( mat ); + // extract global rotation + LLQuaternion rot( mat ); - setWorldPosition( trans ); - setWorldRotation( rot ); + setWorldPosition( trans ); + setWorldRotation( rot ); } //----------------------------------------------------------------------------- @@ -942,15 +942,15 @@ void LLJoint::setWorldMatrix( const LLMatrix4& mat ) //----------------------------------------------------------------------------- void LLJoint::updateWorldMatrixParent() { - if (mDirtyFlags & MATRIX_DIRTY) - { - LLJoint *parent = getParent(); - if (parent) - { - parent->updateWorldMatrixParent(); - } - updateWorldMatrix(); - } + if (mDirtyFlags & MATRIX_DIRTY) + { + LLJoint *parent = getParent(); + if (parent) + { + parent->updateWorldMatrixParent(); + } + updateWorldMatrix(); + } } //----------------------------------------------------------------------------- @@ -958,34 +958,34 @@ void LLJoint::updateWorldMatrixParent() //----------------------------------------------------------------------------- void LLJoint::updateWorldPRSParent() { - if (mDirtyFlags & (ROTATION_DIRTY | POSITION_DIRTY)) - { - LLJoint *parent = getParent(); - if (parent) - { - parent->updateWorldPRSParent(); - } + if (mDirtyFlags & (ROTATION_DIRTY | POSITION_DIRTY)) + { + LLJoint *parent = getParent(); + if (parent) + { + parent->updateWorldPRSParent(); + } - mXform.update(); - mDirtyFlags &= ~(ROTATION_DIRTY | POSITION_DIRTY); - } + mXform.update(); + mDirtyFlags &= ~(ROTATION_DIRTY | POSITION_DIRTY); + } } //----------------------------------------------------------------------------- // updateWorldMatrixChildren() //----------------------------------------------------------------------------- void LLJoint::updateWorldMatrixChildren() -{ - if (!this->mUpdateXform) return; +{ + if (!this->mUpdateXform) return; - if (mDirtyFlags & MATRIX_DIRTY) - { - updateWorldMatrix(); - } - for (LLJoint* joint : mChildren) - { - joint->updateWorldMatrixChildren(); - } + if (mDirtyFlags & MATRIX_DIRTY) + { + updateWorldMatrix(); + } + for (LLJoint* joint : mChildren) + { + joint->updateWorldMatrixChildren(); + } } //----------------------------------------------------------------------------- @@ -993,13 +993,13 @@ void LLJoint::updateWorldMatrixChildren() //----------------------------------------------------------------------------- void LLJoint::updateWorldMatrix() { - if (mDirtyFlags & MATRIX_DIRTY) - { - sNumUpdates++; - mXform.updateMatrix(FALSE); + if (mDirtyFlags & MATRIX_DIRTY) + { + sNumUpdates++; + mXform.updateMatrix(FALSE); mWorldMatrix.loadu(mXform.getWorldMatrix()); - mDirtyFlags = 0x0; - } + mDirtyFlags = 0x0; + } } //-------------------------------------------------------------------- @@ -1007,7 +1007,7 @@ void LLJoint::updateWorldMatrix() //-------------------------------------------------------------------- const LLVector3 &LLJoint::getSkinOffset() { - return mSkinOffset; + return mSkinOffset; } @@ -1016,7 +1016,7 @@ const LLVector3 &LLJoint::getSkinOffset() //-------------------------------------------------------------------- void LLJoint::setSkinOffset( const LLVector3& offset ) { - mSkinOffset = offset; + mSkinOffset = offset; } @@ -1025,18 +1025,18 @@ void LLJoint::setSkinOffset( const LLVector3& offset ) //----------------------------------------------------------------------------- void LLJoint::clampRotation(LLQuaternion old_rot, LLQuaternion new_rot) { - LLVector3 main_axis(1.f, 0.f, 0.f); - - for (LLJoint* joint : mChildren) - { - if (joint->isAnimatable()) - { - main_axis = joint->getPosition(); - main_axis.normVec(); - // only care about first animatable child - break; - } - } + LLVector3 main_axis(1.f, 0.f, 0.f); + + for (LLJoint* joint : mChildren) + { + if (joint->isAnimatable()) + { + main_axis = joint->getPosition(); + main_axis.normVec(); + // only care about first animatable child + break; + } + } } // End diff --git a/indra/llcharacter/lljoint.h b/indra/llcharacter/lljoint.h index 63d99b9209..1f08c9c91c 100644 --- a/indra/llcharacter/lljoint.h +++ b/indra/llcharacter/lljoint.h @@ -1,25 +1,25 @@ -/** +/** * @file lljoint.h * @brief Implementation of LLJoint class. * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -59,18 +59,18 @@ const F32 LL_JOINT_TRESHOLD_POS_OFFSET = 0.0001f; //0.1 mm class LLVector3OverrideMap { public: - LLVector3OverrideMap() {} - bool findActiveOverride(LLUUID& mesh_id, LLVector3& pos) const; - void showJointVector3Overrides(std::ostringstream& os) const; - U32 count() const; - void add(const LLUUID& mesh_id, const LLVector3& pos); - bool remove(const LLUUID& mesh_id); - void clear(); - - typedef std::map<LLUUID,LLVector3> map_type; + LLVector3OverrideMap() {} + bool findActiveOverride(LLUUID& mesh_id, LLVector3& pos) const; + void showJointVector3Overrides(std::ostringstream& os) const; + U32 count() const; + void add(const LLUUID& mesh_id, const LLVector3& pos); + bool remove(const LLUUID& mesh_id); + void clear(); + + typedef std::map<LLUUID,LLVector3> map_type; const map_type& getMap() const { return m_map; } private: - map_type m_map; + map_type m_map; }; inline bool operator==(const LLVector3OverrideMap& a, const LLVector3OverrideMap& b) @@ -91,25 +91,25 @@ class LLJoint { LL_ALIGN_NEW public: - // priority levels, from highest to lowest - enum JointPriority - { - USE_MOTION_PRIORITY = -1, - LOW_PRIORITY = 0, - MEDIUM_PRIORITY, - HIGH_PRIORITY, - HIGHER_PRIORITY, - HIGHEST_PRIORITY, - ADDITIVE_PRIORITY = LL_CHARACTER_MAX_PRIORITY - }; - - enum DirtyFlags - { - MATRIX_DIRTY = 0x1 << 0, - ROTATION_DIRTY = 0x1 << 1, - POSITION_DIRTY = 0x1 << 2, - ALL_DIRTY = 0x7 - }; + // priority levels, from highest to lowest + enum JointPriority + { + USE_MOTION_PRIORITY = -1, + LOW_PRIORITY = 0, + MEDIUM_PRIORITY, + HIGH_PRIORITY, + HIGHER_PRIORITY, + HIGHEST_PRIORITY, + ADDITIVE_PRIORITY = LL_CHARACTER_MAX_PRIORITY + }; + + enum DirtyFlags + { + MATRIX_DIRTY = 0x1 << 0, + ROTATION_DIRTY = 0x1 << 1, + POSITION_DIRTY = 0x1 << 2, + ALL_DIRTY = 0x7 + }; public: enum SupportCategory { @@ -120,55 +120,55 @@ protected: // explicit transformation members LL_ALIGN_16(LLMatrix4a mWorldMatrix); LLXformMatrix mXform; - - std::string mName; - SupportCategory mSupport; + std::string mName; - // parent joint - LLJoint *mParent; + SupportCategory mSupport; + + // parent joint + LLJoint *mParent; LLVector3 mDefaultPosition; LLVector3 mDefaultScale; - + public: - U32 mDirtyFlags; - BOOL mUpdateXform; + U32 mDirtyFlags; + BOOL mUpdateXform; - // describes the skin binding pose - LLVector3 mSkinOffset; + // describes the skin binding pose + LLVector3 mSkinOffset; // Endpoint of the bone, if applicable. This is only relevant for // external programs like Blender, and for diagnostic display. - LLVector3 mEnd; + LLVector3 mEnd; - S32 mJointNum; + S32 mJointNum; - // child joints - typedef std::vector<LLJoint*> joints_t; - joints_t mChildren; + // child joints + typedef std::vector<LLJoint*> joints_t; + joints_t mChildren; - // debug statics - static S32 sNumTouches; - static S32 sNumUpdates; + // debug statics + static S32 sNumTouches; + static S32 sNumUpdates; typedef std::set<std::string> debug_joint_name_t; static debug_joint_name_t s_debugJointNames; static void setDebugJointNames(const debug_joint_name_t& names); static void setDebugJointNames(const std::string& names_string); // Position overrides - LLVector3OverrideMap m_attachmentPosOverrides; - LLVector3 m_posBeforeOverrides; + LLVector3OverrideMap m_attachmentPosOverrides; + LLVector3 m_posBeforeOverrides; // Scale overrides - LLVector3OverrideMap m_attachmentScaleOverrides; - LLVector3 m_scaleBeforeOverrides; + LLVector3OverrideMap m_attachmentScaleOverrides; + LLVector3 m_scaleBeforeOverrides; - void updatePos(const std::string& av_info); - void updateScale(const std::string& av_info); + void updatePos(const std::string& av_info); + void updateScale(const std::string& av_info); public: - LLJoint(); + LLJoint(); // Note: these joint_num constructors are a bad idea because there // are only a couple of places in the code where it is useful to @@ -184,27 +184,27 @@ public: // constructors from LLJoint, LLViewerJoint, LLAvatarJoint, and // createAvatarJoint. LLJoint(S32 joint_num); - - // *TODO: Only used for LLVOAvatarSelf::mScreenp. *DOES NOT INITIALIZE mResetAfterRestoreOldXform* - LLJoint( const std::string &name, LLJoint *parent=NULL ); - virtual ~LLJoint(); + + // *TODO: Only used for LLVOAvatarSelf::mScreenp. *DOES NOT INITIALIZE mResetAfterRestoreOldXform* + LLJoint( const std::string &name, LLJoint *parent=NULL ); + virtual ~LLJoint(); private: - void init(); + void init(); public: - // set name and parent - void setup( const std::string &name, LLJoint *parent=NULL ); + // set name and parent + void setup( const std::string &name, LLJoint *parent=NULL ); - void touch(U32 flags = ALL_DIRTY); + void touch(U32 flags = ALL_DIRTY); - // get/set name - const std::string& getName() const { return mName; } - void setName( const std::string &name ) { mName = name; } + // get/set name + const std::string& getName() const { return mName; } + void setName( const std::string &name ) { mName = name; } // joint num - S32 getJointNum() const { return mJointNum; } - void setJointNum(S32 joint_num); + S32 getJointNum() const { return mJointNum; } + void setJointNum(S32 joint_num); // get/set support SupportCategory getSupport() const { return mSupport; } @@ -214,91 +214,91 @@ public: // get/set end point void setEnd( const LLVector3& end) { mEnd = end; } const LLVector3& getEnd() const { return mEnd; } - - // getParent - LLJoint *getParent() { return mParent; } - // getRoot - LLJoint *getRoot(); + // getParent + LLJoint *getParent() { return mParent; } + + // getRoot + LLJoint *getRoot(); - // search for child joints by name - LLJoint *findJoint( const std::string &name ); + // search for child joints by name + LLJoint *findJoint( const std::string &name ); - // add/remove children - void addChild( LLJoint *joint ); - void removeChild( LLJoint *joint ); - void removeAllChildren(); + // add/remove children + void addChild( LLJoint *joint ); + void removeChild( LLJoint *joint ); + void removeAllChildren(); - // get/set local position - const LLVector3& getPosition(); - void setPosition( const LLVector3& pos, bool apply_attachment_overrides = false ); + // get/set local position + const LLVector3& getPosition(); + void setPosition( const LLVector3& pos, bool apply_attachment_overrides = false ); // Tracks the default position defined by the skeleton - void setDefaultPosition( const LLVector3& pos ); - const LLVector3& getDefaultPosition() const; + void setDefaultPosition( const LLVector3& pos ); + const LLVector3& getDefaultPosition() const; // Tracks the default scale defined by the skeleton - void setDefaultScale( const LLVector3& scale ); - const LLVector3& getDefaultScale() const; + void setDefaultScale( const LLVector3& scale ); + const LLVector3& getDefaultScale() const; - // get/set world position - LLVector3 getWorldPosition(); - LLVector3 getLastWorldPosition(); - void setWorldPosition( const LLVector3& pos ); + // get/set world position + LLVector3 getWorldPosition(); + LLVector3 getLastWorldPosition(); + void setWorldPosition( const LLVector3& pos ); - // get/set local rotation - const LLQuaternion& getRotation(); - void setRotation( const LLQuaternion& rot ); + // get/set local rotation + const LLQuaternion& getRotation(); + void setRotation( const LLQuaternion& rot ); - // get/set world rotation - LLQuaternion getWorldRotation(); - LLQuaternion getLastWorldRotation(); - void setWorldRotation( const LLQuaternion& rot ); + // get/set world rotation + LLQuaternion getWorldRotation(); + LLQuaternion getLastWorldRotation(); + void setWorldRotation( const LLQuaternion& rot ); - // get/set local scale - const LLVector3& getScale(); - void setScale( const LLVector3& scale, bool apply_attachment_overrides = false ); + // get/set local scale + const LLVector3& getScale(); + void setScale( const LLVector3& scale, bool apply_attachment_overrides = false ); - // get/set world matrix - const LLMatrix4 &getWorldMatrix(); - void setWorldMatrix( const LLMatrix4& mat ); + // get/set world matrix + const LLMatrix4 &getWorldMatrix(); + void setWorldMatrix( const LLMatrix4& mat ); const LLMatrix4a& getWorldMatrix4a(); - void updateWorldMatrixChildren(); - void updateWorldMatrixParent(); + void updateWorldMatrixChildren(); + void updateWorldMatrixParent(); - void updateWorldPRSParent(); + void updateWorldPRSParent(); - void updateWorldMatrix(); + void updateWorldMatrix(); - // get/set skin offset - const LLVector3 &getSkinOffset(); - void setSkinOffset( const LLVector3 &offset); + // get/set skin offset + const LLVector3 &getSkinOffset(); + void setSkinOffset( const LLVector3 &offset); - LLXformMatrix *getXform() { return &mXform; } + LLXformMatrix *getXform() { return &mXform; } - void clampRotation(LLQuaternion old_rot, LLQuaternion new_rot); + void clampRotation(LLQuaternion old_rot, LLQuaternion new_rot); - virtual BOOL isAnimatable() const { return TRUE; } + virtual BOOL isAnimatable() const { return TRUE; } - void addAttachmentPosOverride( const LLVector3& pos, const LLUUID& mesh_id, const std::string& av_info, bool& active_override_changed ); - void removeAttachmentPosOverride( const LLUUID& mesh_id, const std::string& av_info, bool& active_override_changed ); - bool hasAttachmentPosOverride( LLVector3& pos, LLUUID& mesh_id ) const; - void clearAttachmentPosOverrides(); + void addAttachmentPosOverride( const LLVector3& pos, const LLUUID& mesh_id, const std::string& av_info, bool& active_override_changed ); + void removeAttachmentPosOverride( const LLUUID& mesh_id, const std::string& av_info, bool& active_override_changed ); + bool hasAttachmentPosOverride( LLVector3& pos, LLUUID& mesh_id ) const; + void clearAttachmentPosOverrides(); void showAttachmentPosOverrides(const std::string& av_info) const; - void addAttachmentScaleOverride( const LLVector3& scale, const LLUUID& mesh_id, const std::string& av_info ); - void removeAttachmentScaleOverride( const LLUUID& mesh_id, const std::string& av_info ); - bool hasAttachmentScaleOverride( LLVector3& scale, LLUUID& mesh_id ) const; - void clearAttachmentScaleOverrides(); + void addAttachmentScaleOverride( const LLVector3& scale, const LLUUID& mesh_id, const std::string& av_info ); + void removeAttachmentScaleOverride( const LLUUID& mesh_id, const std::string& av_info ); + bool hasAttachmentScaleOverride( LLVector3& scale, LLUUID& mesh_id ) const; + void clearAttachmentScaleOverrides(); void showAttachmentScaleOverrides(const std::string& av_info) const; void getAllAttachmentPosOverrides(S32& num_pos_overrides, std::set<LLVector3>& distinct_pos_overrides) const; void getAllAttachmentScaleOverrides(S32& num_scale_overrides, std::set<LLVector3>& distinct_scale_overrides) const; - + // These are used in checks of whether a pos/scale override is considered significant. bool aboveJointPosThreshold(const LLVector3& pos) const; bool aboveJointScaleThreshold(const LLVector3& scale) const; diff --git a/indra/llcharacter/lljointsolverrp3.cpp b/indra/llcharacter/lljointsolverrp3.cpp index f3d5e2e324..6ec04bdb00 100644 --- a/indra/llcharacter/lljointsolverrp3.cpp +++ b/indra/llcharacter/lljointsolverrp3.cpp @@ -1,25 +1,25 @@ -/** +/** * @file lljointsolverrp3.cpp * @brief Implementation of Joint Solver in 3D Real Projective space (RP3). See: https://en.wikipedia.org/wiki/Real_projective_space * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -46,16 +46,16 @@ //----------------------------------------------------------------------------- LLJointSolverRP3::LLJointSolverRP3() { - mJointA = NULL; - mJointB = NULL; - mJointC = NULL; - mJointGoal = NULL; - mLengthAB = 1.0f; - mLengthBC = 1.0f; - mPoleVector.setVec( 1.0f, 0.0f, 0.0f ); - mbUseBAxis = FALSE; - mTwist = 0.0f; - mFirstTime = TRUE; + mJointA = NULL; + mJointB = NULL; + mJointC = NULL; + mJointGoal = NULL; + mLengthAB = 1.0f; + mLengthBC = 1.0f; + mPoleVector.setVec( 1.0f, 0.0f, 0.0f ); + mbUseBAxis = FALSE; + mTwist = 0.0f; + mFirstTime = TRUE; } @@ -70,21 +70,21 @@ LLJointSolverRP3::LLJointSolverRP3() //----------------------------------------------------------------------------- // setupJoints() //----------------------------------------------------------------------------- -void LLJointSolverRP3::setupJoints( LLJoint* jointA, - LLJoint* jointB, - LLJoint* jointC, - LLJoint* jointGoal ) +void LLJointSolverRP3::setupJoints( LLJoint* jointA, + LLJoint* jointB, + LLJoint* jointC, + LLJoint* jointGoal ) { - mJointA = jointA; - mJointB = jointB; - mJointC = jointC; - mJointGoal = jointGoal; + mJointA = jointA; + mJointB = jointB; + mJointC = jointC; + mJointGoal = jointGoal; - mLengthAB = mJointB->getPosition().magVec(); - mLengthBC = mJointC->getPosition().magVec(); + mLengthAB = mJointB->getPosition().magVec(); + mLengthBC = mJointC->getPosition().magVec(); - mJointABaseRotation = jointA->getRotation(); - mJointBBaseRotation = jointB->getRotation(); + mJointABaseRotation = jointA->getRotation(); + mJointBBaseRotation = jointB->getRotation(); } @@ -93,7 +93,7 @@ void LLJointSolverRP3::setupJoints( LLJoint* jointA, //----------------------------------------------------------------------------- const LLVector3& LLJointSolverRP3::getPoleVector() { - return mPoleVector; + return mPoleVector; } @@ -102,8 +102,8 @@ const LLVector3& LLJointSolverRP3::getPoleVector() //----------------------------------------------------------------------------- void LLJointSolverRP3::setPoleVector( const LLVector3& poleVector ) { - mPoleVector = poleVector; - mPoleVector.normVec(); + mPoleVector = poleVector; + mPoleVector.normVec(); } @@ -112,9 +112,9 @@ void LLJointSolverRP3::setPoleVector( const LLVector3& poleVector ) //----------------------------------------------------------------------------- void LLJointSolverRP3::setBAxis( const LLVector3& bAxis ) { - mBAxis = bAxis; - mBAxis.normVec(); - mbUseBAxis = TRUE; + mBAxis = bAxis; + mBAxis.normVec(); + mbUseBAxis = TRUE; } //----------------------------------------------------------------------------- @@ -122,7 +122,7 @@ void LLJointSolverRP3::setBAxis( const LLVector3& bAxis ) //----------------------------------------------------------------------------- F32 LLJointSolverRP3::getTwist() { - return mTwist; + return mTwist; } @@ -131,7 +131,7 @@ F32 LLJointSolverRP3::getTwist() //----------------------------------------------------------------------------- void LLJointSolverRP3::setTwist( F32 twist ) { - mTwist = twist; + mTwist = twist; } @@ -141,254 +141,254 @@ void LLJointSolverRP3::setTwist( F32 twist ) void LLJointSolverRP3::solve() { - //------------------------------------------------------------------------- - // setup joints in their base rotations - //------------------------------------------------------------------------- - mJointA->setRotation( mJointABaseRotation ); - mJointB->setRotation( mJointBBaseRotation ); + //------------------------------------------------------------------------- + // setup joints in their base rotations + //------------------------------------------------------------------------- + mJointA->setRotation( mJointABaseRotation ); + mJointB->setRotation( mJointBBaseRotation ); - //------------------------------------------------------------------------- - // get joint positions in world space - //------------------------------------------------------------------------- - LLVector3 aPos = mJointA->getWorldPosition(); - LLVector3 bPos = mJointB->getWorldPosition(); - LLVector3 cPos = mJointC->getWorldPosition(); - LLVector3 gPos = mJointGoal->getWorldPosition(); + //------------------------------------------------------------------------- + // get joint positions in world space + //------------------------------------------------------------------------- + LLVector3 aPos = mJointA->getWorldPosition(); + LLVector3 bPos = mJointB->getWorldPosition(); + LLVector3 cPos = mJointC->getWorldPosition(); + LLVector3 gPos = mJointGoal->getWorldPosition(); #if DEBUG_JOINT_SOLVER - LL_DEBUGS("JointSolver") << "LLJointSolverRP3::solve()" << LL_NEWLINE - << "bPosLocal = " << mJointB->getPosition() << LL_NEWLINE - << "cPosLocal = " << mJointC->getPosition() << LL_NEWLINE - << "bRotLocal = " << mJointB->getRotation() << LL_NEWLINE - << "cRotLocal = " << mJointC->getRotation() << LL_NEWLINE - << "aPos : " << aPos << LL_NEWLINE - << "bPos : " << bPos << LL_NEWLINE - << "cPos : " << cPos << LL_NEWLINE - << "gPos : " << gPos << LL_ENDL; + LL_DEBUGS("JointSolver") << "LLJointSolverRP3::solve()" << LL_NEWLINE + << "bPosLocal = " << mJointB->getPosition() << LL_NEWLINE + << "cPosLocal = " << mJointC->getPosition() << LL_NEWLINE + << "bRotLocal = " << mJointB->getRotation() << LL_NEWLINE + << "cRotLocal = " << mJointC->getRotation() << LL_NEWLINE + << "aPos : " << aPos << LL_NEWLINE + << "bPos : " << bPos << LL_NEWLINE + << "cPos : " << cPos << LL_NEWLINE + << "gPos : " << gPos << LL_ENDL; #endif - //------------------------------------------------------------------------- - // get the poleVector in world space - //------------------------------------------------------------------------- - LLMatrix4 worldJointAParentMat; - if ( mJointA->getParent() ) - { - worldJointAParentMat = mJointA->getParent()->getWorldMatrix(); - } - LLVector3 poleVec = rotate_vector( mPoleVector, worldJointAParentMat ); - - //------------------------------------------------------------------------- - // compute the following: - // vector from A to B - // vector from B to C - // vector from A to C - // vector from A to G (goal) - //------------------------------------------------------------------------- - LLVector3 abVec = bPos - aPos; - LLVector3 bcVec = cPos - bPos; - LLVector3 acVec = cPos - aPos; - LLVector3 agVec = gPos - aPos; - - //------------------------------------------------------------------------- - // compute needed lengths of those vectors - //------------------------------------------------------------------------- - F32 abLen = abVec.magVec(); - F32 bcLen = bcVec.magVec(); - F32 agLen = agVec.magVec(); - - //------------------------------------------------------------------------- - // compute component vector of (A->B) orthogonal to (A->C) - //------------------------------------------------------------------------- - LLVector3 abacCompOrthoVec = abVec - acVec * ((abVec * acVec)/(acVec * acVec)); + //------------------------------------------------------------------------- + // get the poleVector in world space + //------------------------------------------------------------------------- + LLMatrix4 worldJointAParentMat; + if ( mJointA->getParent() ) + { + worldJointAParentMat = mJointA->getParent()->getWorldMatrix(); + } + LLVector3 poleVec = rotate_vector( mPoleVector, worldJointAParentMat ); + + //------------------------------------------------------------------------- + // compute the following: + // vector from A to B + // vector from B to C + // vector from A to C + // vector from A to G (goal) + //------------------------------------------------------------------------- + LLVector3 abVec = bPos - aPos; + LLVector3 bcVec = cPos - bPos; + LLVector3 acVec = cPos - aPos; + LLVector3 agVec = gPos - aPos; + + //------------------------------------------------------------------------- + // compute needed lengths of those vectors + //------------------------------------------------------------------------- + F32 abLen = abVec.magVec(); + F32 bcLen = bcVec.magVec(); + F32 agLen = agVec.magVec(); + + //------------------------------------------------------------------------- + // compute component vector of (A->B) orthogonal to (A->C) + //------------------------------------------------------------------------- + LLVector3 abacCompOrthoVec = abVec - acVec * ((abVec * acVec)/(acVec * acVec)); #if DEBUG_JOINT_SOLVER - LL_DEBUGS("JointSolver") << "abVec : " << abVec << LL_NEWLINE - << "bcVec : " << bcVec << LL_NEWLINE - << "acVec : " << acVec << LL_NEWLINE - << "agVec : " << agVec << LL_NEWLINE - << "abLen : " << abLen << LL_NEWLINE - << "bcLen : " << bcLen << LL_NEWLINE - << "agLen : " << agLen << LL_NEWLINE - << "abacCompOrthoVec : " << abacCompOrthoVec << LL_ENDL; + LL_DEBUGS("JointSolver") << "abVec : " << abVec << LL_NEWLINE + << "bcVec : " << bcVec << LL_NEWLINE + << "acVec : " << acVec << LL_NEWLINE + << "agVec : " << agVec << LL_NEWLINE + << "abLen : " << abLen << LL_NEWLINE + << "bcLen : " << bcLen << LL_NEWLINE + << "agLen : " << agLen << LL_NEWLINE + << "abacCompOrthoVec : " << abacCompOrthoVec << LL_ENDL; #endif - //------------------------------------------------------------------------- - // compute the normal of the original ABC plane (and store for later) - //------------------------------------------------------------------------- - LLVector3 abcNorm; - if (!mbUseBAxis) - { - if( are_parallel(abVec, bcVec, 0.001f) ) - { - // the current solution is maxed out, so we use the axis that is - // orthogonal to both poleVec and A->B - if ( are_parallel(poleVec, abVec, 0.001f) ) - { - // ACK! the problem is singular - if ( are_parallel(poleVec, agVec, 0.001f) ) - { - // the solutions is also singular - return; - } - else - { - abcNorm = poleVec % agVec; - } - } - else - { - abcNorm = poleVec % abVec; - } - } - else - { - abcNorm = abVec % bcVec; - } - } - else - { - abcNorm = mBAxis * mJointB->getWorldRotation(); - } - - //------------------------------------------------------------------------- - // compute rotation of B - //------------------------------------------------------------------------- - // angle between A->B and B->C - F32 abbcAng = angle_between(abVec, bcVec); - - // vector orthogonal to A->B and B->C - LLVector3 abbcOrthoVec = abVec % bcVec; - if (abbcOrthoVec.magVecSquared() < 0.001f) - { - abbcOrthoVec = poleVec % abVec; - abacCompOrthoVec = poleVec; - } - abbcOrthoVec.normVec(); - - F32 agLenSq = agLen * agLen; - - // angle arm for extension - F32 cosTheta = (agLenSq - abLen*abLen - bcLen*bcLen) / (2.0f * abLen * bcLen); - if (cosTheta > 1.0f) - cosTheta = 1.0f; - else if (cosTheta < -1.0f) - cosTheta = -1.0f; - - F32 theta = acos(cosTheta); - - LLQuaternion bRot(theta - abbcAng, abbcOrthoVec); + //------------------------------------------------------------------------- + // compute the normal of the original ABC plane (and store for later) + //------------------------------------------------------------------------- + LLVector3 abcNorm; + if (!mbUseBAxis) + { + if( are_parallel(abVec, bcVec, 0.001f) ) + { + // the current solution is maxed out, so we use the axis that is + // orthogonal to both poleVec and A->B + if ( are_parallel(poleVec, abVec, 0.001f) ) + { + // ACK! the problem is singular + if ( are_parallel(poleVec, agVec, 0.001f) ) + { + // the solutions is also singular + return; + } + else + { + abcNorm = poleVec % agVec; + } + } + else + { + abcNorm = poleVec % abVec; + } + } + else + { + abcNorm = abVec % bcVec; + } + } + else + { + abcNorm = mBAxis * mJointB->getWorldRotation(); + } + + //------------------------------------------------------------------------- + // compute rotation of B + //------------------------------------------------------------------------- + // angle between A->B and B->C + F32 abbcAng = angle_between(abVec, bcVec); + + // vector orthogonal to A->B and B->C + LLVector3 abbcOrthoVec = abVec % bcVec; + if (abbcOrthoVec.magVecSquared() < 0.001f) + { + abbcOrthoVec = poleVec % abVec; + abacCompOrthoVec = poleVec; + } + abbcOrthoVec.normVec(); + + F32 agLenSq = agLen * agLen; + + // angle arm for extension + F32 cosTheta = (agLenSq - abLen*abLen - bcLen*bcLen) / (2.0f * abLen * bcLen); + if (cosTheta > 1.0f) + cosTheta = 1.0f; + else if (cosTheta < -1.0f) + cosTheta = -1.0f; + + F32 theta = acos(cosTheta); + + LLQuaternion bRot(theta - abbcAng, abbcOrthoVec); #if DEBUG_JOINT_SOLVER - LL_DEBUGS("JointSolver") << "abbcAng : " << abbcAng << LL_NEWLINE - << "abbcOrthoVec : " << abbcOrthoVec << LL_NEWLINE - << "agLenSq : " << agLenSq << LL_NEWLINE - << "cosTheta : " << cosTheta << LL_NEWLINE - << "theta : " << theta << LL_NEWLINE - << "bRot : " << bRot << LL_NEWLINE - << "theta abbcAng theta-abbcAng: " - << theta*180.0/F_PI << " " - << abbcAng*180.0f/F_PI << " " - << (theta - abbcAng)*180.0f/F_PI - << LL_ENDL; + LL_DEBUGS("JointSolver") << "abbcAng : " << abbcAng << LL_NEWLINE + << "abbcOrthoVec : " << abbcOrthoVec << LL_NEWLINE + << "agLenSq : " << agLenSq << LL_NEWLINE + << "cosTheta : " << cosTheta << LL_NEWLINE + << "theta : " << theta << LL_NEWLINE + << "bRot : " << bRot << LL_NEWLINE + << "theta abbcAng theta-abbcAng: " + << theta*180.0/F_PI << " " + << abbcAng*180.0f/F_PI << " " + << (theta - abbcAng)*180.0f/F_PI + << LL_ENDL; #endif - //------------------------------------------------------------------------- - // compute rotation that rotates new A->C to A->G - //------------------------------------------------------------------------- - // rotate B->C by bRot - bcVec = bcVec * bRot; + //------------------------------------------------------------------------- + // compute rotation that rotates new A->C to A->G + //------------------------------------------------------------------------- + // rotate B->C by bRot + bcVec = bcVec * bRot; - // update A->C - acVec = abVec + bcVec; + // update A->C + acVec = abVec + bcVec; - LLQuaternion cgRot; - cgRot.shortestArc( acVec, agVec ); + LLQuaternion cgRot; + cgRot.shortestArc( acVec, agVec ); #if DEBUG_JOINT_SOLVER - LL_DEBUGS("JointSolver") << "bcVec : " << bcVec << LL_NEWLINE - << "acVec : " << acVec << LL_NEWLINE - << "cgRot : " << cgRot << LL_ENDL; + LL_DEBUGS("JointSolver") << "bcVec : " << bcVec << LL_NEWLINE + << "acVec : " << acVec << LL_NEWLINE + << "cgRot : " << cgRot << LL_ENDL; #endif - // update A->B and B->C with rotation from C to G - abVec = abVec * cgRot; - bcVec = bcVec * cgRot; - abcNorm = abcNorm * cgRot; - acVec = abVec + bcVec; - - //------------------------------------------------------------------------- - // compute the normal of the APG plane - //------------------------------------------------------------------------- - if (are_parallel(agVec, poleVec, 0.001f)) - { - // the solution plane is undefined ==> we're done - return; - } - LLVector3 apgNorm = poleVec % agVec; - apgNorm.normVec(); - - if (!mbUseBAxis) - { - //--------------------------------------------------------------------- - // compute the normal of the new ABC plane - // (only necessary if we're NOT using mBAxis) - //--------------------------------------------------------------------- - if( are_parallel(abVec, bcVec, 0.001f) ) - { - // G is either too close or too far away - // we'll use the old ABCnormal - } - else - { - abcNorm = abVec % bcVec; - } - abcNorm.normVec(); - } - - //------------------------------------------------------------------------- - // calcuate plane rotation - //------------------------------------------------------------------------- - LLQuaternion pRot; - if ( are_parallel( abcNorm, apgNorm, 0.001f) ) - { - if (abcNorm * apgNorm < 0.0f) - { - // we must be PI radians off ==> rotate by PI around agVec - pRot.setQuat(F_PI, agVec); - } - else - { - // we're done - } - } - else - { - pRot.shortestArc( abcNorm, apgNorm ); - } - - //------------------------------------------------------------------------- - // compute twist rotation - //------------------------------------------------------------------------- - LLQuaternion twistRot( mTwist, agVec ); + // update A->B and B->C with rotation from C to G + abVec = abVec * cgRot; + bcVec = bcVec * cgRot; + abcNorm = abcNorm * cgRot; + acVec = abVec + bcVec; + + //------------------------------------------------------------------------- + // compute the normal of the APG plane + //------------------------------------------------------------------------- + if (are_parallel(agVec, poleVec, 0.001f)) + { + // the solution plane is undefined ==> we're done + return; + } + LLVector3 apgNorm = poleVec % agVec; + apgNorm.normVec(); + + if (!mbUseBAxis) + { + //--------------------------------------------------------------------- + // compute the normal of the new ABC plane + // (only necessary if we're NOT using mBAxis) + //--------------------------------------------------------------------- + if( are_parallel(abVec, bcVec, 0.001f) ) + { + // G is either too close or too far away + // we'll use the old ABCnormal + } + else + { + abcNorm = abVec % bcVec; + } + abcNorm.normVec(); + } + + //------------------------------------------------------------------------- + // calcuate plane rotation + //------------------------------------------------------------------------- + LLQuaternion pRot; + if ( are_parallel( abcNorm, apgNorm, 0.001f) ) + { + if (abcNorm * apgNorm < 0.0f) + { + // we must be PI radians off ==> rotate by PI around agVec + pRot.setQuat(F_PI, agVec); + } + else + { + // we're done + } + } + else + { + pRot.shortestArc( abcNorm, apgNorm ); + } + + //------------------------------------------------------------------------- + // compute twist rotation + //------------------------------------------------------------------------- + LLQuaternion twistRot( mTwist, agVec ); #if DEBUG_JOINT_SOLVER - LL_DEBUGS("JointSolver") << "abcNorm = " << abcNorm << LL_NEWLINE - << "apgNorm = " << apgNorm << LL_NEWLINE - << "pRot = " << pRot << LL_NEWLINE - << "twist : " << mTwist*180.0/F_PI << LL_NEWLINE - << "twistRot : " << twistRot << LL_ENDL; + LL_DEBUGS("JointSolver") << "abcNorm = " << abcNorm << LL_NEWLINE + << "apgNorm = " << apgNorm << LL_NEWLINE + << "pRot = " << pRot << LL_NEWLINE + << "twist : " << mTwist*180.0/F_PI << LL_NEWLINE + << "twistRot : " << twistRot << LL_ENDL; #endif - //------------------------------------------------------------------------- - // compute rotation of A - //------------------------------------------------------------------------- - LLQuaternion aRot = cgRot * pRot * twistRot; + //------------------------------------------------------------------------- + // compute rotation of A + //------------------------------------------------------------------------- + LLQuaternion aRot = cgRot * pRot * twistRot; - //------------------------------------------------------------------------- - // apply the rotations - //------------------------------------------------------------------------- - mJointB->setWorldRotation( mJointB->getWorldRotation() * bRot ); - mJointA->setWorldRotation( mJointA->getWorldRotation() * aRot ); + //------------------------------------------------------------------------- + // apply the rotations + //------------------------------------------------------------------------- + mJointB->setWorldRotation( mJointB->getWorldRotation() * bRot ); + mJointA->setWorldRotation( mJointA->getWorldRotation() * aRot ); } diff --git a/indra/llcharacter/lljointsolverrp3.h b/indra/llcharacter/lljointsolverrp3.h index 88b5d08710..d6080a1ab2 100644 --- a/indra/llcharacter/lljointsolverrp3.h +++ b/indra/llcharacter/lljointsolverrp3.h @@ -1,25 +1,25 @@ -/** +/** * @file lljointsolverrp3.h * @brief Implementation of LLJointSolverRP3 class * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -52,7 +52,7 @@ // jointB - jointC are cached. During evaluation these bone lengths are // preserved. // -// A A +// A A // | | // | | // B B---CG A---B---C...G @@ -87,89 +87,89 @@ class LLJointSolverRP3 { protected: - LLJoint *mJointA; - LLJoint *mJointB; - LLJoint *mJointC; - LLJoint *mJointGoal; + LLJoint *mJointA; + LLJoint *mJointB; + LLJoint *mJointC; + LLJoint *mJointGoal; - F32 mLengthAB; - F32 mLengthBC; + F32 mLengthAB; + F32 mLengthBC; - LLVector3 mPoleVector; - LLVector3 mBAxis; - BOOL mbUseBAxis; + LLVector3 mPoleVector; + LLVector3 mBAxis; + BOOL mbUseBAxis; - F32 mTwist; + F32 mTwist; - BOOL mFirstTime; - LLMatrix4 mSavedJointAMat; - LLMatrix4 mSavedInvPlaneMat; + BOOL mFirstTime; + LLMatrix4 mSavedJointAMat; + LLMatrix4 mSavedInvPlaneMat; - LLQuaternion mJointABaseRotation; - LLQuaternion mJointBBaseRotation; + LLQuaternion mJointABaseRotation; + LLQuaternion mJointBBaseRotation; public: - //------------------------------------------------------------------------- - // Constructor/Destructor - //------------------------------------------------------------------------- - LLJointSolverRP3(); - virtual ~LLJointSolverRP3(); - - //------------------------------------------------------------------------- - // setupJoints() - // This must be called one time to setup the solver. - // This must be called AFTER the skeleton has been created, all parent/child - // relationships are established, and after the joints are placed in - // a valid configuration (as distances between them will be cached). - //------------------------------------------------------------------------- - void setupJoints( LLJoint* jointA, - LLJoint* jointB, - LLJoint* jointC, - LLJoint* jointGoal ); - - //------------------------------------------------------------------------- - // getPoleVector() - // Returns the current pole vector. - //------------------------------------------------------------------------- - const LLVector3& getPoleVector(); - - //------------------------------------------------------------------------- - // setPoleVector() - // Sets the pole vector. - // The pole vector is defined relative to (in the space of) jointA's parent. - // The default pole vector is (1,0,0), and this is used if this function - // is never called. - // This vector is normalized when set. - //------------------------------------------------------------------------- - void setPoleVector( const LLVector3& poleVector ); - - //------------------------------------------------------------------------- - // setBAxis() - // Sets the joint's axis in B's local frame, and enable "smarter" solve(). - // This allows for smarter IK when for twisted limbs. - //------------------------------------------------------------------------- - void setBAxis( const LLVector3& bAxis ); - - //------------------------------------------------------------------------- - // getTwist() - // Returns the current twist in radians. - //------------------------------------------------------------------------- - F32 getTwist(); - - //------------------------------------------------------------------------- - // setTwist() - // Sets the twist value. - // The default is 0.0. - //------------------------------------------------------------------------- - void setTwist( F32 twist ); - - //------------------------------------------------------------------------- - // solve() - // This is the "work" function. - // When called, the rotations of jointA and jointB will be modified - // such that jointC attempts to reach jointGoal. - //------------------------------------------------------------------------- - void solve(); + //------------------------------------------------------------------------- + // Constructor/Destructor + //------------------------------------------------------------------------- + LLJointSolverRP3(); + virtual ~LLJointSolverRP3(); + + //------------------------------------------------------------------------- + // setupJoints() + // This must be called one time to setup the solver. + // This must be called AFTER the skeleton has been created, all parent/child + // relationships are established, and after the joints are placed in + // a valid configuration (as distances between them will be cached). + //------------------------------------------------------------------------- + void setupJoints( LLJoint* jointA, + LLJoint* jointB, + LLJoint* jointC, + LLJoint* jointGoal ); + + //------------------------------------------------------------------------- + // getPoleVector() + // Returns the current pole vector. + //------------------------------------------------------------------------- + const LLVector3& getPoleVector(); + + //------------------------------------------------------------------------- + // setPoleVector() + // Sets the pole vector. + // The pole vector is defined relative to (in the space of) jointA's parent. + // The default pole vector is (1,0,0), and this is used if this function + // is never called. + // This vector is normalized when set. + //------------------------------------------------------------------------- + void setPoleVector( const LLVector3& poleVector ); + + //------------------------------------------------------------------------- + // setBAxis() + // Sets the joint's axis in B's local frame, and enable "smarter" solve(). + // This allows for smarter IK when for twisted limbs. + //------------------------------------------------------------------------- + void setBAxis( const LLVector3& bAxis ); + + //------------------------------------------------------------------------- + // getTwist() + // Returns the current twist in radians. + //------------------------------------------------------------------------- + F32 getTwist(); + + //------------------------------------------------------------------------- + // setTwist() + // Sets the twist value. + // The default is 0.0. + //------------------------------------------------------------------------- + void setTwist( F32 twist ); + + //------------------------------------------------------------------------- + // solve() + // This is the "work" function. + // When called, the rotations of jointA and jointB will be modified + // such that jointC attempts to reach jointGoal. + //------------------------------------------------------------------------- + void solve(); }; #endif // LL_LLJOINTSOLVERRP3_H diff --git a/indra/llcharacter/lljointstate.h b/indra/llcharacter/lljointstate.h index 1ccc6b5093..584b123046 100644 --- a/indra/llcharacter/lljointstate.h +++ b/indra/llcharacter/lljointstate.h @@ -1,25 +1,25 @@ -/** +/** * @file lljointstate.h * @brief Implementation of LLJointState class. * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -39,85 +39,85 @@ class LLJointState : public LLRefCount { public: - enum BlendPhase - { - INACTIVE, - EASE_IN, - ACTIVE, - EASE_OUT - }; + enum BlendPhase + { + INACTIVE, + EASE_IN, + ACTIVE, + EASE_OUT + }; protected: - // associated joint - LLJoint *mJoint; + // associated joint + LLJoint *mJoint; - // indicates which members are used - U32 mUsage; + // indicates which members are used + U32 mUsage; - // indicates weighted effect of this joint - F32 mWeight; + // indicates weighted effect of this joint + F32 mWeight; - // transformation members - LLVector3 mPosition; // position relative to parent joint - LLQuaternion mRotation; // joint rotation relative to parent joint - LLVector3 mScale; // scale relative to rotated frame - LLJoint::JointPriority mPriority; // how important this joint state is relative to others + // transformation members + LLVector3 mPosition; // position relative to parent joint + LLQuaternion mRotation; // joint rotation relative to parent joint + LLVector3 mScale; // scale relative to rotated frame + LLJoint::JointPriority mPriority; // how important this joint state is relative to others public: - // Constructor - LLJointState() - : mUsage(0) - , mJoint(NULL) - , mWeight(0.f) - , mPriority(LLJoint::USE_MOTION_PRIORITY) - {} - - LLJointState(LLJoint* joint) - : mUsage(0) - , mJoint(joint) - , mWeight(0.f) - , mPriority(LLJoint::USE_MOTION_PRIORITY) - {} - - // joint that this state is applied to - LLJoint* getJoint() { return mJoint; } - const LLJoint* getJoint() const { return mJoint; } - BOOL setJoint( LLJoint *joint ) { mJoint = joint; return mJoint != NULL; } - - // transform type (bitwise flags can be combined) - // Note that these are set automatically when various - // member setPos/setRot/setScale functions are called. - enum Usage - { - POS = 1, - ROT = 2, - SCALE = 4, - }; - U32 getUsage() const { return mUsage; } - void setUsage( U32 usage ) { mUsage = usage; } - F32 getWeight() const { return mWeight; } - void setWeight( F32 weight ) { mWeight = weight; } - - // get/set position - const LLVector3& getPosition() const { return mPosition; } - void setPosition( const LLVector3& pos ) { llassert(mUsage & POS); mPosition = pos; } - - // get/set rotation - const LLQuaternion& getRotation() const { return mRotation; } - void setRotation( const LLQuaternion& rot ) { llassert(mUsage & ROT); mRotation = rot; } - - // get/set scale - const LLVector3& getScale() const { return mScale; } - void setScale( const LLVector3& scale ) { llassert(mUsage & SCALE); mScale = scale; } - - // get/set priority - LLJoint::JointPriority getPriority() const { return mPriority; } - void setPriority( LLJoint::JointPriority priority ) { mPriority = priority; } + // Constructor + LLJointState() + : mUsage(0) + , mJoint(NULL) + , mWeight(0.f) + , mPriority(LLJoint::USE_MOTION_PRIORITY) + {} + + LLJointState(LLJoint* joint) + : mUsage(0) + , mJoint(joint) + , mWeight(0.f) + , mPriority(LLJoint::USE_MOTION_PRIORITY) + {} + + // joint that this state is applied to + LLJoint* getJoint() { return mJoint; } + const LLJoint* getJoint() const { return mJoint; } + BOOL setJoint( LLJoint *joint ) { mJoint = joint; return mJoint != NULL; } + + // transform type (bitwise flags can be combined) + // Note that these are set automatically when various + // member setPos/setRot/setScale functions are called. + enum Usage + { + POS = 1, + ROT = 2, + SCALE = 4, + }; + U32 getUsage() const { return mUsage; } + void setUsage( U32 usage ) { mUsage = usage; } + F32 getWeight() const { return mWeight; } + void setWeight( F32 weight ) { mWeight = weight; } + + // get/set position + const LLVector3& getPosition() const { return mPosition; } + void setPosition( const LLVector3& pos ) { llassert(mUsage & POS); mPosition = pos; } + + // get/set rotation + const LLQuaternion& getRotation() const { return mRotation; } + void setRotation( const LLQuaternion& rot ) { llassert(mUsage & ROT); mRotation = rot; } + + // get/set scale + const LLVector3& getScale() const { return mScale; } + void setScale( const LLVector3& scale ) { llassert(mUsage & SCALE); mScale = scale; } + + // get/set priority + LLJoint::JointPriority getPriority() const { return mPriority; } + void setPriority( LLJoint::JointPriority priority ) { mPriority = priority; } protected: - // Destructor - virtual ~LLJointState() - { - } - + // Destructor + virtual ~LLJointState() + { + } + }; #endif // LL_LLJOINTSTATE_H diff --git a/indra/llcharacter/llkeyframefallmotion.cpp b/indra/llcharacter/llkeyframefallmotion.cpp index e8bb2bf95d..ba00ee8984 100644 --- a/indra/llcharacter/llkeyframefallmotion.cpp +++ b/indra/llcharacter/llkeyframefallmotion.cpp @@ -1,25 +1,25 @@ -/** +/** * @file llkeyframefallmotion.cpp * @brief Implementation of LLKeyframeFallMotion class. * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -36,7 +36,7 @@ //----------------------------------------------------------------------------- // Macros //----------------------------------------------------------------------------- -#define GO_TO_KEY_POSE 1 +#define GO_TO_KEY_POSE 1 #define MIN_TRACK_SPEED 0.01f //----------------------------------------------------------------------------- @@ -45,8 +45,8 @@ //----------------------------------------------------------------------------- LLKeyframeFallMotion::LLKeyframeFallMotion(const LLUUID &id) : LLKeyframeMotion(id) { - mVelocityZ = 0.f; - mCharacter = NULL; + mVelocityZ = 0.f; + mCharacter = NULL; } @@ -64,28 +64,28 @@ LLKeyframeFallMotion::~LLKeyframeFallMotion() //----------------------------------------------------------------------------- LLMotion::LLMotionInitStatus LLKeyframeFallMotion::onInitialize(LLCharacter *character) { - // save character pointer for later use - mCharacter = character; - - // load keyframe data, setup pose and joint states - LLMotion::LLMotionInitStatus result = LLKeyframeMotion::onInitialize(character); - - if (result != LLMotion::STATUS_SUCCESS) - { - return result; - } - - for (U32 jm=0; jm<mJointMotionList->getNumJointMotions(); jm++) - { - if (!mJointStates[jm]->getJoint()) - continue; - if (mJointStates[jm]->getJoint()->getName() == std::string("mPelvis")) - { - mPelvisState = mJointStates[jm]; - } - } - - return result; + // save character pointer for later use + mCharacter = character; + + // load keyframe data, setup pose and joint states + LLMotion::LLMotionInitStatus result = LLKeyframeMotion::onInitialize(character); + + if (result != LLMotion::STATUS_SUCCESS) + { + return result; + } + + for (U32 jm=0; jm<mJointMotionList->getNumJointMotions(); jm++) + { + if (!mJointStates[jm]->getJoint()) + continue; + if (mJointStates[jm]->getJoint()->getName() == std::string("mPelvis")) + { + mPelvisState = mJointStates[jm]; + } + } + + return result; } //----------------------------------------------------------------------------- @@ -93,27 +93,27 @@ LLMotion::LLMotionInitStatus LLKeyframeFallMotion::onInitialize(LLCharacter *cha //----------------------------------------------------------------------------- BOOL LLKeyframeFallMotion::onActivate() { - LLVector3 ground_pos; - LLVector3 ground_normal; - LLQuaternion inverse_pelvis_rot; - LLVector3 fwd_axis(1.f, 0.f, 0.f); + LLVector3 ground_pos; + LLVector3 ground_normal; + LLQuaternion inverse_pelvis_rot; + LLVector3 fwd_axis(1.f, 0.f, 0.f); - mVelocityZ = -mCharacter->getCharacterVelocity().mV[VZ]; - mCharacter->getGround( mCharacter->getCharacterPosition(), ground_pos, ground_normal); - ground_normal.normVec(); + mVelocityZ = -mCharacter->getCharacterVelocity().mV[VZ]; + mCharacter->getGround( mCharacter->getCharacterPosition(), ground_pos, ground_normal); + ground_normal.normVec(); - inverse_pelvis_rot = mCharacter->getCharacterRotation(); - inverse_pelvis_rot.transQuat(); + inverse_pelvis_rot = mCharacter->getCharacterRotation(); + inverse_pelvis_rot.transQuat(); - // find ground normal in pelvis space - ground_normal = ground_normal * inverse_pelvis_rot; + // find ground normal in pelvis space + ground_normal = ground_normal * inverse_pelvis_rot; - // calculate new foward axis - fwd_axis = fwd_axis - (ground_normal * (ground_normal * fwd_axis)); - fwd_axis.normVec(); - mRotationToGroundNormal = LLQuaternion(fwd_axis, ground_normal % fwd_axis, ground_normal); + // calculate new foward axis + fwd_axis = fwd_axis - (ground_normal * (ground_normal * fwd_axis)); + fwd_axis.normVec(); + mRotationToGroundNormal = LLQuaternion(fwd_axis, ground_normal % fwd_axis, ground_normal); - return LLKeyframeMotion::onActivate(); + return LLKeyframeMotion::onActivate(); } //----------------------------------------------------------------------------- @@ -122,15 +122,15 @@ BOOL LLKeyframeFallMotion::onActivate() BOOL LLKeyframeFallMotion::onUpdate(F32 activeTime, U8* joint_mask) { LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR; - BOOL result = LLKeyframeMotion::onUpdate(activeTime, joint_mask); - F32 slerp_amt = clamp_rescale(activeTime / getDuration(), 0.5f, 0.75f, 0.f, 1.f); - - if (mPelvisState.notNull()) - { - mPelvisState->setRotation(mPelvisState->getRotation() * slerp(slerp_amt, mRotationToGroundNormal, LLQuaternion())); - } - - return result; + BOOL result = LLKeyframeMotion::onUpdate(activeTime, joint_mask); + F32 slerp_amt = clamp_rescale(activeTime / getDuration(), 0.5f, 0.75f, 0.f, 1.f); + + if (mPelvisState.notNull()) + { + mPelvisState->setRotation(mPelvisState->getRotation() * slerp(slerp_amt, mRotationToGroundNormal, LLQuaternion())); + } + + return result; } //----------------------------------------------------------------------------- @@ -138,13 +138,13 @@ BOOL LLKeyframeFallMotion::onUpdate(F32 activeTime, U8* joint_mask) //----------------------------------------------------------------------------- F32 LLKeyframeFallMotion::getEaseInDuration() { - if (mVelocityZ == 0.f) - { - // we've already hit the ground - return 0.4f; - } + if (mVelocityZ == 0.f) + { + // we've already hit the ground + return 0.4f; + } - return mCharacter->getPreferredPelvisHeight() / mVelocityZ; + return mCharacter->getPreferredPelvisHeight() / mVelocityZ; } // End diff --git a/indra/llcharacter/llkeyframefallmotion.h b/indra/llcharacter/llkeyframefallmotion.h index 7f0a2fdda2..b0136d302f 100644 --- a/indra/llcharacter/llkeyframefallmotion.h +++ b/indra/llcharacter/llkeyframefallmotion.h @@ -1,25 +1,25 @@ -/** +/** * @file llkeyframefallmotion.h * @brief Implementation of LLKeframeWalkMotion class. * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -37,41 +37,41 @@ // class LLKeyframeFallMotion //----------------------------------------------------------------------------- class LLKeyframeFallMotion : - public LLKeyframeMotion + public LLKeyframeMotion { public: - // Constructor - LLKeyframeFallMotion(const LLUUID &id); + // Constructor + LLKeyframeFallMotion(const LLUUID &id); - // Destructor - virtual ~LLKeyframeFallMotion(); + // Destructor + virtual ~LLKeyframeFallMotion(); public: - //------------------------------------------------------------------------- - // functions to support MotionController and MotionRegistry - //------------------------------------------------------------------------- + //------------------------------------------------------------------------- + // functions to support MotionController and MotionRegistry + //------------------------------------------------------------------------- - // static constructor - // all subclasses must implement such a function and register it - static LLMotion *create(const LLUUID &id) { return new LLKeyframeFallMotion(id); } + // static constructor + // all subclasses must implement such a function and register it + static LLMotion *create(const LLUUID &id) { return new LLKeyframeFallMotion(id); } public: - //------------------------------------------------------------------------- - // animation callbacks to be implemented by subclasses - //------------------------------------------------------------------------- - virtual LLMotionInitStatus onInitialize(LLCharacter *character); - virtual BOOL onActivate(); - virtual F32 getEaseInDuration(); - virtual BOOL onUpdate(F32 activeTime, U8* joint_mask); + //------------------------------------------------------------------------- + // animation callbacks to be implemented by subclasses + //------------------------------------------------------------------------- + virtual LLMotionInitStatus onInitialize(LLCharacter *character); + virtual BOOL onActivate(); + virtual F32 getEaseInDuration(); + virtual BOOL onUpdate(F32 activeTime, U8* joint_mask); protected: - //------------------------------------------------------------------------- - // Member Data - //------------------------------------------------------------------------- - LLCharacter* mCharacter; - F32 mVelocityZ; - LLPointer<LLJointState> mPelvisState; - LLQuaternion mRotationToGroundNormal; + //------------------------------------------------------------------------- + // Member Data + //------------------------------------------------------------------------- + LLCharacter* mCharacter; + F32 mVelocityZ; + LLPointer<LLJointState> mPelvisState; + LLQuaternion mRotationToGroundNormal; }; #endif // LL_LLKeyframeFallMotion_H diff --git a/indra/llcharacter/llkeyframemotion.cpp b/indra/llcharacter/llkeyframemotion.cpp index d95ec159f2..10d35c4527 100644 --- a/indra/llcharacter/llkeyframemotion.cpp +++ b/indra/llcharacter/llkeyframemotion.cpp @@ -1,25 +1,25 @@ -/** +/** * @file llkeyframemotion.cpp * @brief Implementation of LLKeyframeMotion class. * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -46,7 +46,7 @@ //----------------------------------------------------------------------------- // Static Definitions //----------------------------------------------------------------------------- -LLKeyframeDataCache::keyframe_data_map_t LLKeyframeDataCache::sKeyframeDataMap; +LLKeyframeDataCache::keyframe_data_map_t LLKeyframeDataCache::sKeyframeDataMap; //----------------------------------------------------------------------------- // Globals @@ -65,60 +65,60 @@ static F32 MAX_CONSTRAINTS = 10; // JointMotionList //----------------------------------------------------------------------------- LLKeyframeMotion::JointMotionList::JointMotionList() - : mDuration(0.f), - mLoop(FALSE), - mLoopInPoint(0.f), - mLoopOutPoint(0.f), - mEaseInDuration(0.f), - mEaseOutDuration(0.f), - mBasePriority(LLJoint::LOW_PRIORITY), - mHandPose(LLHandMotion::HAND_POSE_SPREAD), - mMaxPriority(LLJoint::LOW_PRIORITY) + : mDuration(0.f), + mLoop(FALSE), + mLoopInPoint(0.f), + mLoopOutPoint(0.f), + mEaseInDuration(0.f), + mEaseOutDuration(0.f), + mBasePriority(LLJoint::LOW_PRIORITY), + mHandPose(LLHandMotion::HAND_POSE_SPREAD), + mMaxPriority(LLJoint::LOW_PRIORITY) { } LLKeyframeMotion::JointMotionList::~JointMotionList() { - for_each(mConstraints.begin(), mConstraints.end(), DeletePointer()); - mConstraints.clear(); - for_each(mJointMotionArray.begin(), mJointMotionArray.end(), DeletePointer()); - mJointMotionArray.clear(); + for_each(mConstraints.begin(), mConstraints.end(), DeletePointer()); + mConstraints.clear(); + for_each(mJointMotionArray.begin(), mJointMotionArray.end(), DeletePointer()); + mJointMotionArray.clear(); } U32 LLKeyframeMotion::JointMotionList::dumpDiagInfo() { - S32 total_size = sizeof(JointMotionList); - - for (U32 i = 0; i < getNumJointMotions(); i++) - { - LLKeyframeMotion::JointMotion* joint_motion_p = mJointMotionArray[i]; - - LL_INFOS() << "\tJoint " << joint_motion_p->mJointName << LL_ENDL; - if (joint_motion_p->mUsage & LLJointState::SCALE) - { - LL_INFOS() << "\t" << joint_motion_p->mScaleCurve.mNumKeys << " scale keys at " - << joint_motion_p->mScaleCurve.mNumKeys * sizeof(ScaleKey) << " bytes" << LL_ENDL; - - total_size += joint_motion_p->mScaleCurve.mNumKeys * sizeof(ScaleKey); - } - if (joint_motion_p->mUsage & LLJointState::ROT) - { - LL_INFOS() << "\t" << joint_motion_p->mRotationCurve.mNumKeys << " rotation keys at " - << joint_motion_p->mRotationCurve.mNumKeys * sizeof(RotationKey) << " bytes" << LL_ENDL; - - total_size += joint_motion_p->mRotationCurve.mNumKeys * sizeof(RotationKey); - } - if (joint_motion_p->mUsage & LLJointState::POS) - { - LL_INFOS() << "\t" << joint_motion_p->mPositionCurve.mNumKeys << " position keys at " - << joint_motion_p->mPositionCurve.mNumKeys * sizeof(PositionKey) << " bytes" << LL_ENDL; - - total_size += joint_motion_p->mPositionCurve.mNumKeys * sizeof(PositionKey); - } - } - LL_INFOS() << "Size: " << total_size << " bytes" << LL_ENDL; - - return total_size; + S32 total_size = sizeof(JointMotionList); + + for (U32 i = 0; i < getNumJointMotions(); i++) + { + LLKeyframeMotion::JointMotion* joint_motion_p = mJointMotionArray[i]; + + LL_INFOS() << "\tJoint " << joint_motion_p->mJointName << LL_ENDL; + if (joint_motion_p->mUsage & LLJointState::SCALE) + { + LL_INFOS() << "\t" << joint_motion_p->mScaleCurve.mNumKeys << " scale keys at " + << joint_motion_p->mScaleCurve.mNumKeys * sizeof(ScaleKey) << " bytes" << LL_ENDL; + + total_size += joint_motion_p->mScaleCurve.mNumKeys * sizeof(ScaleKey); + } + if (joint_motion_p->mUsage & LLJointState::ROT) + { + LL_INFOS() << "\t" << joint_motion_p->mRotationCurve.mNumKeys << " rotation keys at " + << joint_motion_p->mRotationCurve.mNumKeys * sizeof(RotationKey) << " bytes" << LL_ENDL; + + total_size += joint_motion_p->mRotationCurve.mNumKeys * sizeof(RotationKey); + } + if (joint_motion_p->mUsage & LLJointState::POS) + { + LL_INFOS() << "\t" << joint_motion_p->mPositionCurve.mNumKeys << " position keys at " + << joint_motion_p->mPositionCurve.mNumKeys * sizeof(PositionKey) << " bytes" << LL_ENDL; + + total_size += joint_motion_p->mPositionCurve.mNumKeys * sizeof(PositionKey); + } + } + LL_INFOS() << "Size: " << total_size << " bytes" << LL_ENDL; + + return total_size; } //----------------------------------------------------------------------------- @@ -133,17 +133,17 @@ U32 LLKeyframeMotion::JointMotionList::dumpDiagInfo() //----------------------------------------------------------------------------- LLKeyframeMotion::ScaleCurve::ScaleCurve() { - mInterpolationType = LLKeyframeMotion::IT_LINEAR; - mNumKeys = 0; + mInterpolationType = LLKeyframeMotion::IT_LINEAR; + mNumKeys = 0; } //----------------------------------------------------------------------------- // ScaleCurve::~ScaleCurve() //----------------------------------------------------------------------------- -LLKeyframeMotion::ScaleCurve::~ScaleCurve() +LLKeyframeMotion::ScaleCurve::~ScaleCurve() { - mKeys.clear(); - mNumKeys = 0; + mKeys.clear(); + mNumKeys = 0; } //----------------------------------------------------------------------------- @@ -151,44 +151,44 @@ LLKeyframeMotion::ScaleCurve::~ScaleCurve() //----------------------------------------------------------------------------- LLVector3 LLKeyframeMotion::ScaleCurve::getValue(F32 time, F32 duration) { - LLVector3 value; - - if (mKeys.empty()) - { - value.clearVec(); - return value; - } - - key_map_t::iterator right = mKeys.lower_bound(time); - if (right == mKeys.end()) - { - // Past last key - --right; - value = right->second.mScale; - } - else if (right == mKeys.begin() || right->first == time) - { - // Before first key or exactly on a key - value = right->second.mScale; - } - else - { - // Between two keys - key_map_t::iterator left = right; --left; - F32 index_before = left->first; - F32 index_after = right->first; - ScaleKey& scale_before = left->second; - ScaleKey& scale_after = right->second; - if (right == mKeys.end()) - { - scale_after = mLoopInKey; - index_after = duration; - } - - F32 u = (time - index_before) / (index_after - index_before); - value = interp(u, scale_before, scale_after); - } - return value; + LLVector3 value; + + if (mKeys.empty()) + { + value.clearVec(); + return value; + } + + key_map_t::iterator right = mKeys.lower_bound(time); + if (right == mKeys.end()) + { + // Past last key + --right; + value = right->second.mScale; + } + else if (right == mKeys.begin() || right->first == time) + { + // Before first key or exactly on a key + value = right->second.mScale; + } + else + { + // Between two keys + key_map_t::iterator left = right; --left; + F32 index_before = left->first; + F32 index_after = right->first; + ScaleKey& scale_before = left->second; + ScaleKey& scale_after = right->second; + if (right == mKeys.end()) + { + scale_after = mLoopInKey; + index_after = duration; + } + + F32 u = (time - index_before) / (index_after - index_before); + value = interp(u, scale_before, scale_after); + } + return value; } //----------------------------------------------------------------------------- @@ -196,16 +196,16 @@ LLVector3 LLKeyframeMotion::ScaleCurve::getValue(F32 time, F32 duration) //----------------------------------------------------------------------------- LLVector3 LLKeyframeMotion::ScaleCurve::interp(F32 u, ScaleKey& before, ScaleKey& after) { - switch (mInterpolationType) - { - case IT_STEP: - return before.mScale; - - default: - case IT_LINEAR: - case IT_SPLINE: - return lerp(before.mScale, after.mScale, u); - } + switch (mInterpolationType) + { + case IT_STEP: + return before.mScale; + + default: + case IT_LINEAR: + case IT_SPLINE: + return lerp(before.mScale, after.mScale, u); + } } //----------------------------------------------------------------------------- @@ -213,8 +213,8 @@ LLVector3 LLKeyframeMotion::ScaleCurve::interp(F32 u, ScaleKey& before, ScaleKey //----------------------------------------------------------------------------- LLKeyframeMotion::RotationCurve::RotationCurve() { - mInterpolationType = LLKeyframeMotion::IT_LINEAR; - mNumKeys = 0; + mInterpolationType = LLKeyframeMotion::IT_LINEAR; + mNumKeys = 0; } //----------------------------------------------------------------------------- @@ -222,8 +222,8 @@ LLKeyframeMotion::RotationCurve::RotationCurve() //----------------------------------------------------------------------------- LLKeyframeMotion::RotationCurve::~RotationCurve() { - mKeys.clear(); - mNumKeys = 0; + mKeys.clear(); + mNumKeys = 0; } //----------------------------------------------------------------------------- @@ -231,44 +231,44 @@ LLKeyframeMotion::RotationCurve::~RotationCurve() //----------------------------------------------------------------------------- LLQuaternion LLKeyframeMotion::RotationCurve::getValue(F32 time, F32 duration) { - LLQuaternion value; - - if (mKeys.empty()) - { - value = LLQuaternion::DEFAULT; - return value; - } - - key_map_t::iterator right = mKeys.lower_bound(time); - if (right == mKeys.end()) - { - // Past last key - --right; - value = right->second.mRotation; - } - else if (right == mKeys.begin() || right->first == time) - { - // Before first key or exactly on a key - value = right->second.mRotation; - } - else - { - // Between two keys - key_map_t::iterator left = right; --left; - F32 index_before = left->first; - F32 index_after = right->first; - RotationKey& rot_before = left->second; - RotationKey& rot_after = right->second; - if (right == mKeys.end()) - { - rot_after = mLoopInKey; - index_after = duration; - } - - F32 u = (time - index_before) / (index_after - index_before); - value = interp(u, rot_before, rot_after); - } - return value; + LLQuaternion value; + + if (mKeys.empty()) + { + value = LLQuaternion::DEFAULT; + return value; + } + + key_map_t::iterator right = mKeys.lower_bound(time); + if (right == mKeys.end()) + { + // Past last key + --right; + value = right->second.mRotation; + } + else if (right == mKeys.begin() || right->first == time) + { + // Before first key or exactly on a key + value = right->second.mRotation; + } + else + { + // Between two keys + key_map_t::iterator left = right; --left; + F32 index_before = left->first; + F32 index_after = right->first; + RotationKey& rot_before = left->second; + RotationKey& rot_after = right->second; + if (right == mKeys.end()) + { + rot_after = mLoopInKey; + index_after = duration; + } + + F32 u = (time - index_before) / (index_after - index_before); + value = interp(u, rot_before, rot_after); + } + return value; } //----------------------------------------------------------------------------- @@ -276,16 +276,16 @@ LLQuaternion LLKeyframeMotion::RotationCurve::getValue(F32 time, F32 duration) //----------------------------------------------------------------------------- LLQuaternion LLKeyframeMotion::RotationCurve::interp(F32 u, RotationKey& before, RotationKey& after) { - switch (mInterpolationType) - { - case IT_STEP: - return before.mRotation; - - default: - case IT_LINEAR: - case IT_SPLINE: - return nlerp(u, before.mRotation, after.mRotation); - } + switch (mInterpolationType) + { + case IT_STEP: + return before.mRotation; + + default: + case IT_LINEAR: + case IT_SPLINE: + return nlerp(u, before.mRotation, after.mRotation); + } } @@ -294,8 +294,8 @@ LLQuaternion LLKeyframeMotion::RotationCurve::interp(F32 u, RotationKey& before, //----------------------------------------------------------------------------- LLKeyframeMotion::PositionCurve::PositionCurve() { - mInterpolationType = LLKeyframeMotion::IT_LINEAR; - mNumKeys = 0; + mInterpolationType = LLKeyframeMotion::IT_LINEAR; + mNumKeys = 0; } //----------------------------------------------------------------------------- @@ -303,8 +303,8 @@ LLKeyframeMotion::PositionCurve::PositionCurve() //----------------------------------------------------------------------------- LLKeyframeMotion::PositionCurve::~PositionCurve() { - mKeys.clear(); - mNumKeys = 0; + mKeys.clear(); + mNumKeys = 0; } //----------------------------------------------------------------------------- @@ -312,47 +312,47 @@ LLKeyframeMotion::PositionCurve::~PositionCurve() //----------------------------------------------------------------------------- LLVector3 LLKeyframeMotion::PositionCurve::getValue(F32 time, F32 duration) { - LLVector3 value; - - if (mKeys.empty()) - { - value.clearVec(); - return value; - } - - key_map_t::iterator right = mKeys.lower_bound(time); - if (right == mKeys.end()) - { - // Past last key - --right; - value = right->second.mPosition; - } - else if (right == mKeys.begin() || right->first == time) - { - // Before first key or exactly on a key - value = right->second.mPosition; - } - else - { - // Between two keys - key_map_t::iterator left = right; --left; - F32 index_before = left->first; - F32 index_after = right->first; - PositionKey& pos_before = left->second; - PositionKey& pos_after = right->second; - if (right == mKeys.end()) - { - pos_after = mLoopInKey; - index_after = duration; - } - - F32 u = (time - index_before) / (index_after - index_before); - value = interp(u, pos_before, pos_after); - } - - llassert(value.isFinite()); - - return value; + LLVector3 value; + + if (mKeys.empty()) + { + value.clearVec(); + return value; + } + + key_map_t::iterator right = mKeys.lower_bound(time); + if (right == mKeys.end()) + { + // Past last key + --right; + value = right->second.mPosition; + } + else if (right == mKeys.begin() || right->first == time) + { + // Before first key or exactly on a key + value = right->second.mPosition; + } + else + { + // Between two keys + key_map_t::iterator left = right; --left; + F32 index_before = left->first; + F32 index_after = right->first; + PositionKey& pos_before = left->second; + PositionKey& pos_after = right->second; + if (right == mKeys.end()) + { + pos_after = mLoopInKey; + index_after = duration; + } + + F32 u = (time - index_before) / (index_after - index_before); + value = interp(u, pos_before, pos_after); + } + + llassert(value.isFinite()); + + return value; } //----------------------------------------------------------------------------- @@ -360,15 +360,15 @@ LLVector3 LLKeyframeMotion::PositionCurve::getValue(F32 time, F32 duration) //----------------------------------------------------------------------------- LLVector3 LLKeyframeMotion::PositionCurve::interp(F32 u, PositionKey& before, PositionKey& after) { - switch (mInterpolationType) - { - case IT_STEP: - return before.mPosition; - default: - case IT_LINEAR: - case IT_SPLINE: - return lerp(before.mPosition, after.mPosition, u); - } + switch (mInterpolationType) + { + case IT_STEP: + return before.mPosition; + default: + case IT_LINEAR: + case IT_SPLINE: + return lerp(before.mPosition, after.mPosition, u); + } } @@ -383,38 +383,38 @@ LLVector3 LLKeyframeMotion::PositionCurve::interp(F32 u, PositionKey& before, Po //----------------------------------------------------------------------------- void LLKeyframeMotion::JointMotion::update(LLJointState* joint_state, F32 time, F32 duration) { - // this value being 0 is the cause of https://jira.lindenlab.com/browse/SL-22678 but I haven't - // managed to get a stack to see how it got here. Testing for 0 here will stop the crash. - if ( joint_state == NULL ) - { - return; - } - - U32 usage = joint_state->getUsage(); - - //------------------------------------------------------------------------- - // update scale component of joint state - //------------------------------------------------------------------------- - if ((usage & LLJointState::SCALE) && mScaleCurve.mNumKeys) - { - joint_state->setScale( mScaleCurve.getValue( time, duration ) ); - } - - //------------------------------------------------------------------------- - // update rotation component of joint state - //------------------------------------------------------------------------- - if ((usage & LLJointState::ROT) && mRotationCurve.mNumKeys) - { - joint_state->setRotation( mRotationCurve.getValue( time, duration ) ); - } - - //------------------------------------------------------------------------- - // update position component of joint state - //------------------------------------------------------------------------- - if ((usage & LLJointState::POS) && mPositionCurve.mNumKeys) - { - joint_state->setPosition( mPositionCurve.getValue( time, duration ) ); - } + // this value being 0 is the cause of https://jira.lindenlab.com/browse/SL-22678 but I haven't + // managed to get a stack to see how it got here. Testing for 0 here will stop the crash. + if ( joint_state == NULL ) + { + return; + } + + U32 usage = joint_state->getUsage(); + + //------------------------------------------------------------------------- + // update scale component of joint state + //------------------------------------------------------------------------- + if ((usage & LLJointState::SCALE) && mScaleCurve.mNumKeys) + { + joint_state->setScale( mScaleCurve.getValue( time, duration ) ); + } + + //------------------------------------------------------------------------- + // update rotation component of joint state + //------------------------------------------------------------------------- + if ((usage & LLJointState::ROT) && mRotationCurve.mNumKeys) + { + joint_state->setRotation( mRotationCurve.getValue( time, duration ) ); + } + + //------------------------------------------------------------------------- + // update position component of joint state + //------------------------------------------------------------------------- + if ((usage & LLJointState::POS) && mPositionCurve.mNumKeys) + { + joint_state->setPosition( mPositionCurve.getValue( time, duration ) ); + } } @@ -428,14 +428,14 @@ void LLKeyframeMotion::JointMotion::update(LLJointState* joint_state, F32 time, // LLKeyframeMotion() // Class Constructor //----------------------------------------------------------------------------- -LLKeyframeMotion::LLKeyframeMotion(const LLUUID &id) - : LLMotion(id), - mJointMotionList(NULL), - mPelvisp(NULL), - mLastSkeletonSerialNum(0), - mLastUpdateTime(0.f), - mLastLoopedTime(0.f), - mAssetStatus(ASSET_UNDEFINED) +LLKeyframeMotion::LLKeyframeMotion(const LLUUID &id) + : LLMotion(id), + mJointMotionList(NULL), + mPelvisp(NULL), + mLastSkeletonSerialNum(0), + mLastUpdateTime(0.f), + mLastLoopedTime(0.f), + mAssetStatus(ASSET_UNDEFINED) { } @@ -447,8 +447,8 @@ LLKeyframeMotion::LLKeyframeMotion(const LLUUID &id) //----------------------------------------------------------------------------- LLKeyframeMotion::~LLKeyframeMotion() { - for_each(mConstraints.begin(), mConstraints.end(), DeletePointer()); - mConstraints.clear(); + for_each(mConstraints.begin(), mConstraints.end(), DeletePointer()); + mConstraints.clear(); } //----------------------------------------------------------------------------- @@ -456,7 +456,7 @@ LLKeyframeMotion::~LLKeyframeMotion() //----------------------------------------------------------------------------- LLMotion *LLKeyframeMotion::create(const LLUUID &id) { - return new LLKeyframeMotion(id); + return new LLKeyframeMotion(id); } //----------------------------------------------------------------------------- @@ -464,8 +464,8 @@ LLMotion *LLKeyframeMotion::create(const LLUUID &id) //----------------------------------------------------------------------------- LLPointer<LLJointState>& LLKeyframeMotion::getJointState(U32 index) { - llassert_always (index < mJointStates.size()); - return mJointStates[index]; + llassert_always (index < mJointStates.size()); + return mJointStates[index]; } //----------------------------------------------------------------------------- @@ -473,12 +473,12 @@ LLPointer<LLJointState>& LLKeyframeMotion::getJointState(U32 index) //----------------------------------------------------------------------------- LLJoint* LLKeyframeMotion::getJoint(U32 index) { - llassert_always (index < mJointStates.size()); - LLJoint* joint = mJointStates[index]->getJoint(); - - //Commented out 06-28-11 by Aura. - //llassert_always (joint); - return joint; + llassert_always (index < mJointStates.size()); + LLJoint* joint = mJointStates[index]->getJoint(); + + //Commented out 06-28-11 by Aura. + //llassert_always (joint); + return joint; } //----------------------------------------------------------------------------- @@ -486,16 +486,16 @@ LLJoint* LLKeyframeMotion::getJoint(U32 index) //----------------------------------------------------------------------------- LLMotion::LLMotionInitStatus LLKeyframeMotion::onInitialize(LLCharacter *character) { - mCharacter = character; - - LLUUID* character_id; + mCharacter = character; + + LLUUID* character_id; - // asset already loaded? - switch(mAssetStatus) - { - case ASSET_NEEDS_FETCH: - // request asset - mAssetStatus = ASSET_FETCHED; + // asset already loaded? + switch(mAssetStatus) + { + case ASSET_NEEDS_FETCH: + // request asset + mAssetStatus = ASSET_FETCHED; if (mID.notNull()) { @@ -512,109 +512,109 @@ LLMotion::LLMotionInitStatus LLKeyframeMotion::onInitialize(LLCharacter *charact LL_INFOS("Animation") << "Attempted to fetch animation " << mName << " with null id for character " << mCharacter->getID() << LL_ENDL; } - return STATUS_HOLD; - case ASSET_FETCHED: - return STATUS_HOLD; - case ASSET_FETCH_FAILED: - return STATUS_FAILURE; - case ASSET_LOADED: - return STATUS_SUCCESS; - default: - // we don't know what state the asset is in yet, so keep going - // check keyframe cache first then file cache then asset request - break; - } - - LLKeyframeMotion::JointMotionList* joint_motion_list = LLKeyframeDataCache::getKeyframeData(getID()); - - if(joint_motion_list) - { - // motion already existed in cache, so grab it - mJointMotionList = joint_motion_list; - - mJointStates.reserve(mJointMotionList->getNumJointMotions()); - - // don't forget to allocate joint states - // set up joint states to point to character joints - for(U32 i = 0; i < mJointMotionList->getNumJointMotions(); i++) - { - JointMotion* joint_motion = mJointMotionList->getJointMotion(i); - if (LLJoint *joint = mCharacter->getJoint(joint_motion->mJointName)) - { - LLPointer<LLJointState> joint_state = new LLJointState; - mJointStates.push_back(joint_state); - joint_state->setJoint(joint); - joint_state->setUsage(joint_motion->mUsage); - joint_state->setPriority(joint_motion->mPriority); - } - else - { - // add dummy joint state with no associated joint - mJointStates.push_back(new LLJointState); - } - } - mAssetStatus = ASSET_LOADED; - setupPose(); - return STATUS_SUCCESS; - } - - //------------------------------------------------------------------------- - // Load named file by concatenating the character prefix with the motion name. - // Load data into a buffer to be parsed. - //------------------------------------------------------------------------- - U8 *anim_data; - S32 anim_file_size; - - BOOL success = FALSE; - LLFileSystem* anim_file = new LLFileSystem(mID, LLAssetType::AT_ANIMATION); - if (!anim_file || !anim_file->getSize()) - { - delete anim_file; - anim_file = NULL; - - // request asset over network on next call to load - mAssetStatus = ASSET_NEEDS_FETCH; - - return STATUS_HOLD; - } - else - { - anim_file_size = anim_file->getSize(); - anim_data = new(std::nothrow) U8[anim_file_size]; - if (anim_data) - { - success = anim_file->read(anim_data, anim_file_size); /*Flawfinder: ignore*/ - } - else - { - LL_WARNS() << "Failed to allocate buffer: " << anim_file_size << mID << LL_ENDL; - } - delete anim_file; - anim_file = NULL; - } - - if (!success) - { - LL_WARNS() << "Can't open animation file " << mID << LL_ENDL; - mAssetStatus = ASSET_FETCH_FAILED; - return STATUS_FAILURE; - } - - LL_DEBUGS() << "Loading keyframe data for: " << getName() << ":" << getID() << " (" << anim_file_size << " bytes)" << LL_ENDL; - - LLDataPackerBinaryBuffer dp(anim_data, anim_file_size); - - if (!deserialize(dp, getID())) - { - LL_WARNS() << "Failed to decode asset for animation " << getName() << ":" << getID() << LL_ENDL; - mAssetStatus = ASSET_FETCH_FAILED; - return STATUS_FAILURE; - } - - delete []anim_data; - - mAssetStatus = ASSET_LOADED; - return STATUS_SUCCESS; + return STATUS_HOLD; + case ASSET_FETCHED: + return STATUS_HOLD; + case ASSET_FETCH_FAILED: + return STATUS_FAILURE; + case ASSET_LOADED: + return STATUS_SUCCESS; + default: + // we don't know what state the asset is in yet, so keep going + // check keyframe cache first then file cache then asset request + break; + } + + LLKeyframeMotion::JointMotionList* joint_motion_list = LLKeyframeDataCache::getKeyframeData(getID()); + + if(joint_motion_list) + { + // motion already existed in cache, so grab it + mJointMotionList = joint_motion_list; + + mJointStates.reserve(mJointMotionList->getNumJointMotions()); + + // don't forget to allocate joint states + // set up joint states to point to character joints + for(U32 i = 0; i < mJointMotionList->getNumJointMotions(); i++) + { + JointMotion* joint_motion = mJointMotionList->getJointMotion(i); + if (LLJoint *joint = mCharacter->getJoint(joint_motion->mJointName)) + { + LLPointer<LLJointState> joint_state = new LLJointState; + mJointStates.push_back(joint_state); + joint_state->setJoint(joint); + joint_state->setUsage(joint_motion->mUsage); + joint_state->setPriority(joint_motion->mPriority); + } + else + { + // add dummy joint state with no associated joint + mJointStates.push_back(new LLJointState); + } + } + mAssetStatus = ASSET_LOADED; + setupPose(); + return STATUS_SUCCESS; + } + + //------------------------------------------------------------------------- + // Load named file by concatenating the character prefix with the motion name. + // Load data into a buffer to be parsed. + //------------------------------------------------------------------------- + U8 *anim_data; + S32 anim_file_size; + + BOOL success = FALSE; + LLFileSystem* anim_file = new LLFileSystem(mID, LLAssetType::AT_ANIMATION); + if (!anim_file || !anim_file->getSize()) + { + delete anim_file; + anim_file = NULL; + + // request asset over network on next call to load + mAssetStatus = ASSET_NEEDS_FETCH; + + return STATUS_HOLD; + } + else + { + anim_file_size = anim_file->getSize(); + anim_data = new(std::nothrow) U8[anim_file_size]; + if (anim_data) + { + success = anim_file->read(anim_data, anim_file_size); /*Flawfinder: ignore*/ + } + else + { + LL_WARNS() << "Failed to allocate buffer: " << anim_file_size << mID << LL_ENDL; + } + delete anim_file; + anim_file = NULL; + } + + if (!success) + { + LL_WARNS() << "Can't open animation file " << mID << LL_ENDL; + mAssetStatus = ASSET_FETCH_FAILED; + return STATUS_FAILURE; + } + + LL_DEBUGS() << "Loading keyframe data for: " << getName() << ":" << getID() << " (" << anim_file_size << " bytes)" << LL_ENDL; + + LLDataPackerBinaryBuffer dp(anim_data, anim_file_size); + + if (!deserialize(dp, getID())) + { + LL_WARNS() << "Failed to decode asset for animation " << getName() << ":" << getID() << LL_ENDL; + mAssetStatus = ASSET_FETCH_FAILED; + return STATUS_FAILURE; + } + + delete []anim_data; + + mAssetStatus = ASSET_LOADED; + return STATUS_SUCCESS; } //----------------------------------------------------------------------------- @@ -622,38 +622,38 @@ LLMotion::LLMotionInitStatus LLKeyframeMotion::onInitialize(LLCharacter *charact //----------------------------------------------------------------------------- BOOL LLKeyframeMotion::setupPose() { - // add all valid joint states to the pose - for (U32 jm=0; jm<mJointMotionList->getNumJointMotions(); jm++) - { - LLPointer<LLJointState> joint_state = getJointState(jm); - if ( joint_state->getJoint() ) - { - addJointState( joint_state ); - } - } - - // initialize joint constraints - for (JointConstraintSharedData* shared_constraintp : mJointMotionList->mConstraints) - { - JointConstraint* constraintp = new JointConstraint(shared_constraintp); - initializeConstraint(constraintp); - mConstraints.push_front(constraintp); - } - - if (mJointMotionList->mConstraints.size()) - { - mPelvisp = mCharacter->getJoint("mPelvis"); - if (!mPelvisp) - { - return FALSE; - } - } - - // setup loop keys - setLoopIn(mJointMotionList->mLoopInPoint); - setLoopOut(mJointMotionList->mLoopOutPoint); - - return TRUE; + // add all valid joint states to the pose + for (U32 jm=0; jm<mJointMotionList->getNumJointMotions(); jm++) + { + LLPointer<LLJointState> joint_state = getJointState(jm); + if ( joint_state->getJoint() ) + { + addJointState( joint_state ); + } + } + + // initialize joint constraints + for (JointConstraintSharedData* shared_constraintp : mJointMotionList->mConstraints) + { + JointConstraint* constraintp = new JointConstraint(shared_constraintp); + initializeConstraint(constraintp); + mConstraints.push_front(constraintp); + } + + if (mJointMotionList->mConstraints.size()) + { + mPelvisp = mCharacter->getJoint("mPelvis"); + if (!mPelvisp) + { + return FALSE; + } + } + + // setup loop keys + setLoopIn(mJointMotionList->mLoopInPoint); + setLoopOut(mJointMotionList->mLoopOutPoint); + + return TRUE; } //----------------------------------------------------------------------------- @@ -661,20 +661,20 @@ BOOL LLKeyframeMotion::setupPose() //----------------------------------------------------------------------------- BOOL LLKeyframeMotion::onActivate() { - // If the keyframe anim has an associated emote, trigger it. - if( mJointMotionList->mEmoteName.length() > 0 ) - { - LLUUID emote_anim_id = gAnimLibrary.stringToAnimState(mJointMotionList->mEmoteName); - // don't start emote if already active to avoid recursion - if (!mCharacter->isMotionActive(emote_anim_id)) - { - mCharacter->startMotion( emote_anim_id ); - } - } - - mLastLoopedTime = 0.f; - - return TRUE; + // If the keyframe anim has an associated emote, trigger it. + if( mJointMotionList->mEmoteName.length() > 0 ) + { + LLUUID emote_anim_id = gAnimLibrary.stringToAnimState(mJointMotionList->mEmoteName); + // don't start emote if already active to avoid recursion + if (!mCharacter->isMotionActive(emote_anim_id)) + { + mCharacter->startMotion( emote_anim_id ); + } + } + + mLastLoopedTime = 0.f; + + return TRUE; } //----------------------------------------------------------------------------- @@ -683,50 +683,50 @@ BOOL LLKeyframeMotion::onActivate() BOOL LLKeyframeMotion::onUpdate(F32 time, U8* joint_mask) { LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR; - // llassert(time >= 0.f); // This will fire - time = llmax(0.f, time); - - if (mJointMotionList->mLoop) - { - if (mJointMotionList->mDuration == 0.0f) - { - time = 0.f; - mLastLoopedTime = 0.0f; - } - else if (mStopped) - { - mLastLoopedTime = llmin(mJointMotionList->mDuration, mLastLoopedTime + time - mLastUpdateTime); - } - else if (time > mJointMotionList->mLoopOutPoint) - { - if ((mJointMotionList->mLoopOutPoint - mJointMotionList->mLoopInPoint) == 0.f) - { - mLastLoopedTime = mJointMotionList->mLoopOutPoint; - } - else - { - mLastLoopedTime = mJointMotionList->mLoopInPoint + - fmod(time - mJointMotionList->mLoopOutPoint, - mJointMotionList->mLoopOutPoint - mJointMotionList->mLoopInPoint); - } - } - else - { - mLastLoopedTime = time; - } - } - else - { - mLastLoopedTime = time; - } - - applyKeyframes(mLastLoopedTime); - - applyConstraints(mLastLoopedTime, joint_mask); - - mLastUpdateTime = time; - - return mLastLoopedTime <= mJointMotionList->mDuration; + // llassert(time >= 0.f); // This will fire + time = llmax(0.f, time); + + if (mJointMotionList->mLoop) + { + if (mJointMotionList->mDuration == 0.0f) + { + time = 0.f; + mLastLoopedTime = 0.0f; + } + else if (mStopped) + { + mLastLoopedTime = llmin(mJointMotionList->mDuration, mLastLoopedTime + time - mLastUpdateTime); + } + else if (time > mJointMotionList->mLoopOutPoint) + { + if ((mJointMotionList->mLoopOutPoint - mJointMotionList->mLoopInPoint) == 0.f) + { + mLastLoopedTime = mJointMotionList->mLoopOutPoint; + } + else + { + mLastLoopedTime = mJointMotionList->mLoopInPoint + + fmod(time - mJointMotionList->mLoopOutPoint, + mJointMotionList->mLoopOutPoint - mJointMotionList->mLoopInPoint); + } + } + else + { + mLastLoopedTime = time; + } + } + else + { + mLastLoopedTime = time; + } + + applyKeyframes(mLastLoopedTime); + + applyConstraints(mLastLoopedTime, joint_mask); + + mLastUpdateTime = time; + + return mLastLoopedTime <= mJointMotionList->mDuration; } //----------------------------------------------------------------------------- @@ -734,28 +734,28 @@ BOOL LLKeyframeMotion::onUpdate(F32 time, U8* joint_mask) //----------------------------------------------------------------------------- void LLKeyframeMotion::applyKeyframes(F32 time) { - llassert_always (mJointMotionList->getNumJointMotions() <= mJointStates.size()); - for (U32 i=0; i<mJointMotionList->getNumJointMotions(); i++) - { - mJointMotionList->getJointMotion(i)->update(mJointStates[i], - time, - mJointMotionList->mDuration ); - } - - LLJoint::JointPriority* pose_priority = (LLJoint::JointPriority* )mCharacter->getAnimationData("Hand Pose Priority"); - if (pose_priority) - { - if (mJointMotionList->mMaxPriority >= *pose_priority) - { - mCharacter->setAnimationData("Hand Pose", &mJointMotionList->mHandPose); - mCharacter->setAnimationData("Hand Pose Priority", &mJointMotionList->mMaxPriority); - } - } - else - { - mCharacter->setAnimationData("Hand Pose", &mJointMotionList->mHandPose); - mCharacter->setAnimationData("Hand Pose Priority", &mJointMotionList->mMaxPriority); - } + llassert_always (mJointMotionList->getNumJointMotions() <= mJointStates.size()); + for (U32 i=0; i<mJointMotionList->getNumJointMotions(); i++) + { + mJointMotionList->getJointMotion(i)->update(mJointStates[i], + time, + mJointMotionList->mDuration ); + } + + LLJoint::JointPriority* pose_priority = (LLJoint::JointPriority* )mCharacter->getAnimationData("Hand Pose Priority"); + if (pose_priority) + { + if (mJointMotionList->mMaxPriority >= *pose_priority) + { + mCharacter->setAnimationData("Hand Pose", &mJointMotionList->mHandPose); + mCharacter->setAnimationData("Hand Pose Priority", &mJointMotionList->mMaxPriority); + } + } + else + { + mCharacter->setAnimationData("Hand Pose", &mJointMotionList->mHandPose); + mCharacter->setAnimationData("Hand Pose Priority", &mJointMotionList->mMaxPriority); + } } //----------------------------------------------------------------------------- @@ -763,23 +763,23 @@ void LLKeyframeMotion::applyKeyframes(F32 time) //----------------------------------------------------------------------------- void LLKeyframeMotion::applyConstraints(F32 time, U8* joint_mask) { - //TODO: investigate replacing spring simulation with critically damped motion - - // re-init constraints if skeleton has changed - if (mCharacter->getSkeletonSerialNum() != mLastSkeletonSerialNum) - { - mLastSkeletonSerialNum = mCharacter->getSkeletonSerialNum(); - for (JointConstraint* constraintp : mConstraints) - { - initializeConstraint(constraintp); - } - } - - // apply constraints - for (JointConstraint* constraintp : mConstraints) - { - applyConstraint(constraintp, time, joint_mask); - } + //TODO: investigate replacing spring simulation with critically damped motion + + // re-init constraints if skeleton has changed + if (mCharacter->getSkeletonSerialNum() != mLastSkeletonSerialNum) + { + mLastSkeletonSerialNum = mCharacter->getSkeletonSerialNum(); + for (JointConstraint* constraintp : mConstraints) + { + initializeConstraint(constraintp); + } + } + + // apply constraints + for (JointConstraint* constraintp : mConstraints) + { + applyConstraint(constraintp, time, joint_mask); + } } //----------------------------------------------------------------------------- @@ -787,10 +787,10 @@ void LLKeyframeMotion::applyConstraints(F32 time, U8* joint_mask) //----------------------------------------------------------------------------- void LLKeyframeMotion::onDeactivate() { - for (JointConstraint* constraintp : mConstraints) - { - deactivateConstraint(constraintp); - } + for (JointConstraint* constraintp : mConstraints) + { + deactivateConstraint(constraintp); + } } //----------------------------------------------------------------------------- @@ -799,24 +799,24 @@ void LLKeyframeMotion::onDeactivate() // time is in seconds since character creation void LLKeyframeMotion::setStopTime(F32 time) { - LLMotion::setStopTime(time); - - if (mJointMotionList->mLoop && mJointMotionList->mLoopOutPoint != mJointMotionList->mDuration) - { - F32 start_loop_time = mActivationTimestamp + mJointMotionList->mLoopInPoint; - F32 loop_fraction_time; - if (mJointMotionList->mLoopOutPoint == mJointMotionList->mLoopInPoint) - { - loop_fraction_time = 0.f; - } - else - { - loop_fraction_time = fmod(time - start_loop_time, - mJointMotionList->mLoopOutPoint - mJointMotionList->mLoopInPoint); - } - mStopTimestamp = llmax(time, - (time - loop_fraction_time) + (mJointMotionList->mDuration - mJointMotionList->mLoopInPoint) - getEaseOutDuration()); - } + LLMotion::setStopTime(time); + + if (mJointMotionList->mLoop && mJointMotionList->mLoopOutPoint != mJointMotionList->mDuration) + { + F32 start_loop_time = mActivationTimestamp + mJointMotionList->mLoopInPoint; + F32 loop_fraction_time; + if (mJointMotionList->mLoopOutPoint == mJointMotionList->mLoopInPoint) + { + loop_fraction_time = 0.f; + } + else + { + loop_fraction_time = fmod(time - start_loop_time, + mJointMotionList->mLoopOutPoint - mJointMotionList->mLoopInPoint); + } + mStopTimestamp = llmax(time, + (time - loop_fraction_time) + (mJointMotionList->mDuration - mJointMotionList->mLoopInPoint) - getEaseOutDuration()); + } } //----------------------------------------------------------------------------- @@ -824,43 +824,43 @@ void LLKeyframeMotion::setStopTime(F32 time) //----------------------------------------------------------------------------- void LLKeyframeMotion::initializeConstraint(JointConstraint* constraint) { - JointConstraintSharedData *shared_data = constraint->mSharedData; - - S32 joint_num; - LLVector3 source_pos = mCharacter->getVolumePos(shared_data->mSourceConstraintVolume, shared_data->mSourceConstraintOffset); - LLJoint* cur_joint = getJoint(shared_data->mJointStateIndices[0]); - if ( !cur_joint ) - { - return; - } - - F32 source_pos_offset = dist_vec(source_pos, cur_joint->getWorldPosition()); - - constraint->mTotalLength = constraint->mJointLengths[0] = dist_vec(cur_joint->getParent()->getWorldPosition(), source_pos); - - // grab joint lengths - for (joint_num = 1; joint_num < shared_data->mChainLength; joint_num++) - { - cur_joint = getJointState(shared_data->mJointStateIndices[joint_num])->getJoint(); - if (!cur_joint) - { - return; - } - constraint->mJointLengths[joint_num] = dist_vec(cur_joint->getWorldPosition(), cur_joint->getParent()->getWorldPosition()); - constraint->mTotalLength += constraint->mJointLengths[joint_num]; - } - - // store fraction of total chain length so we know how to shear the entire chain towards the goal position - for (joint_num = 1; joint_num < shared_data->mChainLength; joint_num++) - { - constraint->mJointLengthFractions[joint_num] = constraint->mJointLengths[joint_num] / constraint->mTotalLength; - } - - // add last step in chain, from final joint to constraint position - constraint->mTotalLength += source_pos_offset; - - constraint->mSourceVolume = mCharacter->findCollisionVolume(shared_data->mSourceConstraintVolume); - constraint->mTargetVolume = mCharacter->findCollisionVolume(shared_data->mTargetConstraintVolume); + JointConstraintSharedData *shared_data = constraint->mSharedData; + + S32 joint_num; + LLVector3 source_pos = mCharacter->getVolumePos(shared_data->mSourceConstraintVolume, shared_data->mSourceConstraintOffset); + LLJoint* cur_joint = getJoint(shared_data->mJointStateIndices[0]); + if ( !cur_joint ) + { + return; + } + + F32 source_pos_offset = dist_vec(source_pos, cur_joint->getWorldPosition()); + + constraint->mTotalLength = constraint->mJointLengths[0] = dist_vec(cur_joint->getParent()->getWorldPosition(), source_pos); + + // grab joint lengths + for (joint_num = 1; joint_num < shared_data->mChainLength; joint_num++) + { + cur_joint = getJointState(shared_data->mJointStateIndices[joint_num])->getJoint(); + if (!cur_joint) + { + return; + } + constraint->mJointLengths[joint_num] = dist_vec(cur_joint->getWorldPosition(), cur_joint->getParent()->getWorldPosition()); + constraint->mTotalLength += constraint->mJointLengths[joint_num]; + } + + // store fraction of total chain length so we know how to shear the entire chain towards the goal position + for (joint_num = 1; joint_num < shared_data->mChainLength; joint_num++) + { + constraint->mJointLengthFractions[joint_num] = constraint->mJointLengths[joint_num] / constraint->mTotalLength; + } + + // add last step in chain, from final joint to constraint position + constraint->mTotalLength += source_pos_offset; + + constraint->mSourceVolume = mCharacter->findCollisionVolume(shared_data->mSourceConstraintVolume); + constraint->mTargetVolume = mCharacter->findCollisionVolume(shared_data->mTargetConstraintVolume); } //----------------------------------------------------------------------------- @@ -868,30 +868,30 @@ void LLKeyframeMotion::initializeConstraint(JointConstraint* constraint) //----------------------------------------------------------------------------- void LLKeyframeMotion::activateConstraint(JointConstraint* constraint) { - JointConstraintSharedData *shared_data = constraint->mSharedData; - constraint->mActive = TRUE; - S32 joint_num; - - // grab ground position if we need to - if (shared_data->mConstraintTargetType == CONSTRAINT_TARGET_TYPE_GROUND) - { - LLVector3 source_pos = mCharacter->getVolumePos(shared_data->mSourceConstraintVolume, shared_data->mSourceConstraintOffset); - LLVector3 ground_pos_agent; - mCharacter->getGround(source_pos, ground_pos_agent, constraint->mGroundNorm); - constraint->mGroundPos = mCharacter->getPosGlobalFromAgent(ground_pos_agent + shared_data->mTargetConstraintOffset); - } - - for (joint_num = 1; joint_num < shared_data->mChainLength; joint_num++) - { - LLJoint* cur_joint = getJoint(shared_data->mJointStateIndices[joint_num]); - if ( !cur_joint ) - { - return; - } - constraint->mPositions[joint_num] = (cur_joint->getWorldPosition() - mPelvisp->getWorldPosition()) * ~mPelvisp->getWorldRotation(); - } - - constraint->mWeight = 1.f; + JointConstraintSharedData *shared_data = constraint->mSharedData; + constraint->mActive = TRUE; + S32 joint_num; + + // grab ground position if we need to + if (shared_data->mConstraintTargetType == CONSTRAINT_TARGET_TYPE_GROUND) + { + LLVector3 source_pos = mCharacter->getVolumePos(shared_data->mSourceConstraintVolume, shared_data->mSourceConstraintOffset); + LLVector3 ground_pos_agent; + mCharacter->getGround(source_pos, ground_pos_agent, constraint->mGroundNorm); + constraint->mGroundPos = mCharacter->getPosGlobalFromAgent(ground_pos_agent + shared_data->mTargetConstraintOffset); + } + + for (joint_num = 1; joint_num < shared_data->mChainLength; joint_num++) + { + LLJoint* cur_joint = getJoint(shared_data->mJointStateIndices[joint_num]); + if ( !cur_joint ) + { + return; + } + constraint->mPositions[joint_num] = (cur_joint->getWorldPosition() - mPelvisp->getWorldPosition()) * ~mPelvisp->getWorldRotation(); + } + + constraint->mWeight = 1.f; } //----------------------------------------------------------------------------- @@ -899,19 +899,19 @@ void LLKeyframeMotion::activateConstraint(JointConstraint* constraint) //----------------------------------------------------------------------------- void LLKeyframeMotion::deactivateConstraint(JointConstraint *constraintp) { - if (constraintp->mSourceVolume) - { - constraintp->mSourceVolume->mUpdateXform = FALSE; - } - - if (constraintp->mSharedData->mConstraintTargetType != CONSTRAINT_TARGET_TYPE_GROUND) - { - if (constraintp->mTargetVolume) - { - constraintp->mTargetVolume->mUpdateXform = FALSE; - } - } - constraintp->mActive = FALSE; + if (constraintp->mSourceVolume) + { + constraintp->mSourceVolume->mUpdateXform = FALSE; + } + + if (constraintp->mSharedData->mConstraintTargetType != CONSTRAINT_TARGET_TYPE_GROUND) + { + if (constraintp->mTargetVolume) + { + constraintp->mTargetVolume->mUpdateXform = FALSE; + } + } + constraintp->mActive = FALSE; } //----------------------------------------------------------------------------- @@ -919,304 +919,304 @@ void LLKeyframeMotion::deactivateConstraint(JointConstraint *constraintp) //----------------------------------------------------------------------------- void LLKeyframeMotion::applyConstraint(JointConstraint* constraint, F32 time, U8* joint_mask) { - JointConstraintSharedData *shared_data = constraint->mSharedData; - if (!shared_data) return; - - LLVector3 positions[MAX_CHAIN_LENGTH]; - const F32* joint_lengths = constraint->mJointLengths; - LLVector3 velocities[MAX_CHAIN_LENGTH - 1]; - LLQuaternion old_rots[MAX_CHAIN_LENGTH]; - S32 joint_num; - - if (time < shared_data->mEaseInStartTime) - { - return; - } - - if (time > shared_data->mEaseOutStopTime) - { - if (constraint->mActive) - { - deactivateConstraint(constraint); - } - return; - } - - if (!constraint->mActive || time < shared_data->mEaseInStopTime) - { - activateConstraint(constraint); - } - - LLJoint* root_joint = getJoint(shared_data->mJointStateIndices[shared_data->mChainLength]); - if (! root_joint) - { - return; - } - - LLVector3 root_pos = root_joint->getWorldPosition(); -// LLQuaternion root_rot = - root_joint->getParent()->getWorldRotation(); -// LLQuaternion inv_root_rot = ~root_rot; - -// LLVector3 current_source_pos = mCharacter->getVolumePos(shared_data->mSourceConstraintVolume, shared_data->mSourceConstraintOffset); - - //apply underlying keyframe animation to get nominal "kinematic" joint positions - for (joint_num = 0; joint_num <= shared_data->mChainLength; joint_num++) - { - LLJoint* cur_joint = getJoint(shared_data->mJointStateIndices[joint_num]); - if (!cur_joint) - { - return; - } - - if (joint_mask[cur_joint->getJointNum()] >= (0xff >> (7 - getPriority()))) - { - // skip constraint - return; - } - old_rots[joint_num] = cur_joint->getRotation(); - cur_joint->setRotation(getJointState(shared_data->mJointStateIndices[joint_num])->getRotation()); - } - - - LLVector3 keyframe_source_pos = mCharacter->getVolumePos(shared_data->mSourceConstraintVolume, shared_data->mSourceConstraintOffset); - LLVector3 target_pos; - - switch(shared_data->mConstraintTargetType) - { - case CONSTRAINT_TARGET_TYPE_GROUND: - target_pos = mCharacter->getPosAgentFromGlobal(constraint->mGroundPos); -// LL_INFOS() << "Target Pos " << constraint->mGroundPos << " on " << mCharacter->findCollisionVolume(shared_data->mSourceConstraintVolume)->getName() << LL_ENDL; - break; - case CONSTRAINT_TARGET_TYPE_BODY: - target_pos = mCharacter->getVolumePos(shared_data->mTargetConstraintVolume, shared_data->mTargetConstraintOffset); - break; - default: - break; - } - - LLVector3 norm; - LLJoint *source_jointp = NULL; - LLJoint *target_jointp = NULL; - - if (shared_data->mConstraintType == CONSTRAINT_TYPE_PLANE) - { - switch(shared_data->mConstraintTargetType) - { - case CONSTRAINT_TARGET_TYPE_GROUND: - norm = constraint->mGroundNorm; - break; - case CONSTRAINT_TARGET_TYPE_BODY: - target_jointp = mCharacter->findCollisionVolume(shared_data->mTargetConstraintVolume); - if (target_jointp) - { - // *FIX: do proper normal calculation for stretched - // spheres (inverse transpose) - norm = target_pos - target_jointp->getWorldPosition(); - } - - if (norm.isExactlyZero()) - { - source_jointp = mCharacter->findCollisionVolume(shared_data->mSourceConstraintVolume); - norm = -1.f * shared_data->mSourceConstraintOffset; - if (source_jointp) - { - norm = norm * source_jointp->getWorldRotation(); - } - } - norm.normVec(); - break; - default: - norm.clearVec(); - break; - } - - target_pos = keyframe_source_pos + (norm * ((target_pos - keyframe_source_pos) * norm)); - } - - if (constraint->mSharedData->mChainLength != 0 && - dist_vec_squared(root_pos, target_pos) * 0.95f > constraint->mTotalLength * constraint->mTotalLength) - { - constraint->mWeight = LLSmoothInterpolation::lerp(constraint->mWeight, 0.f, 0.1f); - } - else - { - constraint->mWeight = LLSmoothInterpolation::lerp(constraint->mWeight, 1.f, 0.3f); - } - - F32 weight = constraint->mWeight * ((shared_data->mEaseOutStopTime == 0.f) ? 1.f : - llmin(clamp_rescale(time, shared_data->mEaseInStartTime, shared_data->mEaseInStopTime, 0.f, 1.f), - clamp_rescale(time, shared_data->mEaseOutStartTime, shared_data->mEaseOutStopTime, 1.f, 0.f))); - - LLVector3 source_to_target = target_pos - keyframe_source_pos; - - S32 max_iteration_count = ll_round(clamp_rescale( - mCharacter->getPixelArea(), - MAX_PIXEL_AREA_CONSTRAINTS, - MIN_PIXEL_AREA_CONSTRAINTS, - (F32)MAX_ITERATIONS, - (F32)MIN_ITERATIONS)); - - if (shared_data->mChainLength) - { - LLJoint* end_joint = getJoint(shared_data->mJointStateIndices[0]); - - if (!end_joint) - { - return; - } - - LLQuaternion end_rot = end_joint->getWorldRotation(); - - // slam start and end of chain to the proper positions (rest of chain stays put) - positions[0] = lerp(keyframe_source_pos, target_pos, weight); - positions[shared_data->mChainLength] = root_pos; - - // grab keyframe-specified positions of joints - for (joint_num = 1; joint_num < shared_data->mChainLength; joint_num++) - { - LLJoint* cur_joint = getJoint(shared_data->mJointStateIndices[joint_num]); - - if (!cur_joint) - { - return; - } - - LLVector3 kinematic_position = cur_joint->getWorldPosition() + - (source_to_target * constraint->mJointLengthFractions[joint_num]); - - // convert intermediate joint positions to world coordinates - positions[joint_num] = ( constraint->mPositions[joint_num] * mPelvisp->getWorldRotation()) + mPelvisp->getWorldPosition(); - F32 time_constant = 1.f / clamp_rescale(constraint->mFixupDistanceRMS, 0.f, 0.5f, 0.2f, 8.f); -// LL_INFOS() << "Interpolant " << LLSmoothInterpolation::getInterpolant(time_constant, FALSE) << " and fixup distance " << constraint->mFixupDistanceRMS << " on " << mCharacter->findCollisionVolume(shared_data->mSourceConstraintVolume)->getName() << LL_ENDL; - positions[joint_num] = lerp(positions[joint_num], kinematic_position, - LLSmoothInterpolation::getInterpolant(time_constant, FALSE)); - } - - S32 iteration_count; - for (iteration_count = 0; iteration_count < max_iteration_count; iteration_count++) - { - S32 num_joints_finished = 0; - for (joint_num = 1; joint_num < shared_data->mChainLength; joint_num++) - { - // constraint to child - LLVector3 acceleration = (positions[joint_num - 1] - positions[joint_num]) * - (dist_vec(positions[joint_num], positions[joint_num - 1]) - joint_lengths[joint_num - 1]) * JOINT_LENGTH_K; - // constraint to parent - acceleration += (positions[joint_num + 1] - positions[joint_num]) * - (dist_vec(positions[joint_num + 1], positions[joint_num]) - joint_lengths[joint_num]) * JOINT_LENGTH_K; - - if (acceleration.magVecSquared() < MIN_ACCELERATION_SQUARED) - { - num_joints_finished++; - } - - velocities[joint_num - 1] = velocities[joint_num - 1] * 0.7f; - positions[joint_num] += velocities[joint_num - 1] + (acceleration * 0.5f); - velocities[joint_num - 1] += acceleration; - } - - if ((iteration_count >= MIN_ITERATION_COUNT) && - (num_joints_finished == shared_data->mChainLength - 1)) - { -// LL_INFOS() << iteration_count << " iterations on " << -// mCharacter->findCollisionVolume(shared_data->mSourceConstraintVolume)->getName() << LL_ENDL; - break; - } - } - - for (joint_num = shared_data->mChainLength; joint_num > 0; joint_num--) - { - LLJoint* cur_joint = getJoint(shared_data->mJointStateIndices[joint_num]); - - if (!cur_joint) - { - return; - } - LLJoint* child_joint = getJoint(shared_data->mJointStateIndices[joint_num - 1]); - if (!child_joint) - { - return; - } - - LLQuaternion parent_rot = cur_joint->getParent()->getWorldRotation(); - - LLQuaternion cur_rot = cur_joint->getWorldRotation(); - LLQuaternion fixup_rot; - - LLVector3 target_at = positions[joint_num - 1] - positions[joint_num]; - LLVector3 current_at; - - // at bottom of chain, use point on collision volume, not joint position - if (joint_num == 1) - { - current_at = mCharacter->getVolumePos(shared_data->mSourceConstraintVolume, shared_data->mSourceConstraintOffset) - - cur_joint->getWorldPosition(); - } - else - { - current_at = child_joint->getPosition() * cur_rot; - } - fixup_rot.shortestArc(current_at, target_at); - - LLQuaternion target_rot = cur_rot * fixup_rot; - target_rot = target_rot * ~parent_rot; - - if (weight != 1.f) - { - LLQuaternion cur_rot = getJointState(shared_data->mJointStateIndices[joint_num])->getRotation(); - target_rot = nlerp(weight, cur_rot, target_rot); - } - - getJointState(shared_data->mJointStateIndices[joint_num])->setRotation(target_rot); - cur_joint->setRotation(target_rot); - } - - LLQuaternion end_local_rot = end_rot * ~end_joint->getParent()->getWorldRotation(); - - if (weight == 1.f) - { - getJointState(shared_data->mJointStateIndices[0])->setRotation(end_local_rot); - } - else - { - LLQuaternion cur_rot = getJointState(shared_data->mJointStateIndices[0])->getRotation(); - getJointState(shared_data->mJointStateIndices[0])->setRotation(nlerp(weight, cur_rot, end_local_rot)); - } - - // save simulated positions in pelvis-space and calculate total fixup distance - constraint->mFixupDistanceRMS = 0.f; - F32 delta_time = llmax(0.02f, llabs(time - mLastUpdateTime)); - for (joint_num = 1; joint_num < shared_data->mChainLength; joint_num++) - { - LLVector3 new_pos = (positions[joint_num] - mPelvisp->getWorldPosition()) * ~mPelvisp->getWorldRotation(); - constraint->mFixupDistanceRMS += dist_vec_squared(new_pos, constraint->mPositions[joint_num]) / delta_time; - constraint->mPositions[joint_num] = new_pos; - } - constraint->mFixupDistanceRMS *= 1.f / (constraint->mTotalLength * (F32)(shared_data->mChainLength - 1)); - constraint->mFixupDistanceRMS = (F32) sqrt(constraint->mFixupDistanceRMS); - - //reset old joint rots - for (joint_num = 0; joint_num <= shared_data->mChainLength; joint_num++) - { - LLJoint* cur_joint = getJoint(shared_data->mJointStateIndices[joint_num]); - if (!cur_joint) - { - return; - } - - cur_joint->setRotation(old_rots[joint_num]); - } - } - // simple positional constraint (pelvis only) - else if (getJointState(shared_data->mJointStateIndices[0])->getUsage() & LLJointState::POS) - { - LLVector3 delta = source_to_target * weight; - LLPointer<LLJointState> current_joint_state = getJointState(shared_data->mJointStateIndices[0]); - LLQuaternion parent_rot = current_joint_state->getJoint()->getParent()->getWorldRotation(); - delta = delta * ~parent_rot; - current_joint_state->setPosition(current_joint_state->getJoint()->getPosition() + delta); - } + JointConstraintSharedData *shared_data = constraint->mSharedData; + if (!shared_data) return; + + LLVector3 positions[MAX_CHAIN_LENGTH]; + const F32* joint_lengths = constraint->mJointLengths; + LLVector3 velocities[MAX_CHAIN_LENGTH - 1]; + LLQuaternion old_rots[MAX_CHAIN_LENGTH]; + S32 joint_num; + + if (time < shared_data->mEaseInStartTime) + { + return; + } + + if (time > shared_data->mEaseOutStopTime) + { + if (constraint->mActive) + { + deactivateConstraint(constraint); + } + return; + } + + if (!constraint->mActive || time < shared_data->mEaseInStopTime) + { + activateConstraint(constraint); + } + + LLJoint* root_joint = getJoint(shared_data->mJointStateIndices[shared_data->mChainLength]); + if (! root_joint) + { + return; + } + + LLVector3 root_pos = root_joint->getWorldPosition(); +// LLQuaternion root_rot = + root_joint->getParent()->getWorldRotation(); +// LLQuaternion inv_root_rot = ~root_rot; + +// LLVector3 current_source_pos = mCharacter->getVolumePos(shared_data->mSourceConstraintVolume, shared_data->mSourceConstraintOffset); + + //apply underlying keyframe animation to get nominal "kinematic" joint positions + for (joint_num = 0; joint_num <= shared_data->mChainLength; joint_num++) + { + LLJoint* cur_joint = getJoint(shared_data->mJointStateIndices[joint_num]); + if (!cur_joint) + { + return; + } + + if (joint_mask[cur_joint->getJointNum()] >= (0xff >> (7 - getPriority()))) + { + // skip constraint + return; + } + old_rots[joint_num] = cur_joint->getRotation(); + cur_joint->setRotation(getJointState(shared_data->mJointStateIndices[joint_num])->getRotation()); + } + + + LLVector3 keyframe_source_pos = mCharacter->getVolumePos(shared_data->mSourceConstraintVolume, shared_data->mSourceConstraintOffset); + LLVector3 target_pos; + + switch(shared_data->mConstraintTargetType) + { + case CONSTRAINT_TARGET_TYPE_GROUND: + target_pos = mCharacter->getPosAgentFromGlobal(constraint->mGroundPos); +// LL_INFOS() << "Target Pos " << constraint->mGroundPos << " on " << mCharacter->findCollisionVolume(shared_data->mSourceConstraintVolume)->getName() << LL_ENDL; + break; + case CONSTRAINT_TARGET_TYPE_BODY: + target_pos = mCharacter->getVolumePos(shared_data->mTargetConstraintVolume, shared_data->mTargetConstraintOffset); + break; + default: + break; + } + + LLVector3 norm; + LLJoint *source_jointp = NULL; + LLJoint *target_jointp = NULL; + + if (shared_data->mConstraintType == CONSTRAINT_TYPE_PLANE) + { + switch(shared_data->mConstraintTargetType) + { + case CONSTRAINT_TARGET_TYPE_GROUND: + norm = constraint->mGroundNorm; + break; + case CONSTRAINT_TARGET_TYPE_BODY: + target_jointp = mCharacter->findCollisionVolume(shared_data->mTargetConstraintVolume); + if (target_jointp) + { + // *FIX: do proper normal calculation for stretched + // spheres (inverse transpose) + norm = target_pos - target_jointp->getWorldPosition(); + } + + if (norm.isExactlyZero()) + { + source_jointp = mCharacter->findCollisionVolume(shared_data->mSourceConstraintVolume); + norm = -1.f * shared_data->mSourceConstraintOffset; + if (source_jointp) + { + norm = norm * source_jointp->getWorldRotation(); + } + } + norm.normVec(); + break; + default: + norm.clearVec(); + break; + } + + target_pos = keyframe_source_pos + (norm * ((target_pos - keyframe_source_pos) * norm)); + } + + if (constraint->mSharedData->mChainLength != 0 && + dist_vec_squared(root_pos, target_pos) * 0.95f > constraint->mTotalLength * constraint->mTotalLength) + { + constraint->mWeight = LLSmoothInterpolation::lerp(constraint->mWeight, 0.f, 0.1f); + } + else + { + constraint->mWeight = LLSmoothInterpolation::lerp(constraint->mWeight, 1.f, 0.3f); + } + + F32 weight = constraint->mWeight * ((shared_data->mEaseOutStopTime == 0.f) ? 1.f : + llmin(clamp_rescale(time, shared_data->mEaseInStartTime, shared_data->mEaseInStopTime, 0.f, 1.f), + clamp_rescale(time, shared_data->mEaseOutStartTime, shared_data->mEaseOutStopTime, 1.f, 0.f))); + + LLVector3 source_to_target = target_pos - keyframe_source_pos; + + S32 max_iteration_count = ll_round(clamp_rescale( + mCharacter->getPixelArea(), + MAX_PIXEL_AREA_CONSTRAINTS, + MIN_PIXEL_AREA_CONSTRAINTS, + (F32)MAX_ITERATIONS, + (F32)MIN_ITERATIONS)); + + if (shared_data->mChainLength) + { + LLJoint* end_joint = getJoint(shared_data->mJointStateIndices[0]); + + if (!end_joint) + { + return; + } + + LLQuaternion end_rot = end_joint->getWorldRotation(); + + // slam start and end of chain to the proper positions (rest of chain stays put) + positions[0] = lerp(keyframe_source_pos, target_pos, weight); + positions[shared_data->mChainLength] = root_pos; + + // grab keyframe-specified positions of joints + for (joint_num = 1; joint_num < shared_data->mChainLength; joint_num++) + { + LLJoint* cur_joint = getJoint(shared_data->mJointStateIndices[joint_num]); + + if (!cur_joint) + { + return; + } + + LLVector3 kinematic_position = cur_joint->getWorldPosition() + + (source_to_target * constraint->mJointLengthFractions[joint_num]); + + // convert intermediate joint positions to world coordinates + positions[joint_num] = ( constraint->mPositions[joint_num] * mPelvisp->getWorldRotation()) + mPelvisp->getWorldPosition(); + F32 time_constant = 1.f / clamp_rescale(constraint->mFixupDistanceRMS, 0.f, 0.5f, 0.2f, 8.f); +// LL_INFOS() << "Interpolant " << LLSmoothInterpolation::getInterpolant(time_constant, FALSE) << " and fixup distance " << constraint->mFixupDistanceRMS << " on " << mCharacter->findCollisionVolume(shared_data->mSourceConstraintVolume)->getName() << LL_ENDL; + positions[joint_num] = lerp(positions[joint_num], kinematic_position, + LLSmoothInterpolation::getInterpolant(time_constant, FALSE)); + } + + S32 iteration_count; + for (iteration_count = 0; iteration_count < max_iteration_count; iteration_count++) + { + S32 num_joints_finished = 0; + for (joint_num = 1; joint_num < shared_data->mChainLength; joint_num++) + { + // constraint to child + LLVector3 acceleration = (positions[joint_num - 1] - positions[joint_num]) * + (dist_vec(positions[joint_num], positions[joint_num - 1]) - joint_lengths[joint_num - 1]) * JOINT_LENGTH_K; + // constraint to parent + acceleration += (positions[joint_num + 1] - positions[joint_num]) * + (dist_vec(positions[joint_num + 1], positions[joint_num]) - joint_lengths[joint_num]) * JOINT_LENGTH_K; + + if (acceleration.magVecSquared() < MIN_ACCELERATION_SQUARED) + { + num_joints_finished++; + } + + velocities[joint_num - 1] = velocities[joint_num - 1] * 0.7f; + positions[joint_num] += velocities[joint_num - 1] + (acceleration * 0.5f); + velocities[joint_num - 1] += acceleration; + } + + if ((iteration_count >= MIN_ITERATION_COUNT) && + (num_joints_finished == shared_data->mChainLength - 1)) + { +// LL_INFOS() << iteration_count << " iterations on " << +// mCharacter->findCollisionVolume(shared_data->mSourceConstraintVolume)->getName() << LL_ENDL; + break; + } + } + + for (joint_num = shared_data->mChainLength; joint_num > 0; joint_num--) + { + LLJoint* cur_joint = getJoint(shared_data->mJointStateIndices[joint_num]); + + if (!cur_joint) + { + return; + } + LLJoint* child_joint = getJoint(shared_data->mJointStateIndices[joint_num - 1]); + if (!child_joint) + { + return; + } + + LLQuaternion parent_rot = cur_joint->getParent()->getWorldRotation(); + + LLQuaternion cur_rot = cur_joint->getWorldRotation(); + LLQuaternion fixup_rot; + + LLVector3 target_at = positions[joint_num - 1] - positions[joint_num]; + LLVector3 current_at; + + // at bottom of chain, use point on collision volume, not joint position + if (joint_num == 1) + { + current_at = mCharacter->getVolumePos(shared_data->mSourceConstraintVolume, shared_data->mSourceConstraintOffset) - + cur_joint->getWorldPosition(); + } + else + { + current_at = child_joint->getPosition() * cur_rot; + } + fixup_rot.shortestArc(current_at, target_at); + + LLQuaternion target_rot = cur_rot * fixup_rot; + target_rot = target_rot * ~parent_rot; + + if (weight != 1.f) + { + LLQuaternion cur_rot = getJointState(shared_data->mJointStateIndices[joint_num])->getRotation(); + target_rot = nlerp(weight, cur_rot, target_rot); + } + + getJointState(shared_data->mJointStateIndices[joint_num])->setRotation(target_rot); + cur_joint->setRotation(target_rot); + } + + LLQuaternion end_local_rot = end_rot * ~end_joint->getParent()->getWorldRotation(); + + if (weight == 1.f) + { + getJointState(shared_data->mJointStateIndices[0])->setRotation(end_local_rot); + } + else + { + LLQuaternion cur_rot = getJointState(shared_data->mJointStateIndices[0])->getRotation(); + getJointState(shared_data->mJointStateIndices[0])->setRotation(nlerp(weight, cur_rot, end_local_rot)); + } + + // save simulated positions in pelvis-space and calculate total fixup distance + constraint->mFixupDistanceRMS = 0.f; + F32 delta_time = llmax(0.02f, llabs(time - mLastUpdateTime)); + for (joint_num = 1; joint_num < shared_data->mChainLength; joint_num++) + { + LLVector3 new_pos = (positions[joint_num] - mPelvisp->getWorldPosition()) * ~mPelvisp->getWorldRotation(); + constraint->mFixupDistanceRMS += dist_vec_squared(new_pos, constraint->mPositions[joint_num]) / delta_time; + constraint->mPositions[joint_num] = new_pos; + } + constraint->mFixupDistanceRMS *= 1.f / (constraint->mTotalLength * (F32)(shared_data->mChainLength - 1)); + constraint->mFixupDistanceRMS = (F32) sqrt(constraint->mFixupDistanceRMS); + + //reset old joint rots + for (joint_num = 0; joint_num <= shared_data->mChainLength; joint_num++) + { + LLJoint* cur_joint = getJoint(shared_data->mJointStateIndices[joint_num]); + if (!cur_joint) + { + return; + } + + cur_joint->setRotation(old_rots[joint_num]); + } + } + // simple positional constraint (pelvis only) + else if (getJointState(shared_data->mJointStateIndices[0])->getUsage() & LLJointState::POS) + { + LLVector3 delta = source_to_target * weight; + LLPointer<LLJointState> current_joint_state = getJointState(shared_data->mJointStateIndices[0]); + LLQuaternion parent_rot = current_joint_state->getJoint()->getParent()->getWorldRotation(); + delta = delta * ~parent_rot; + current_joint_state->setPosition(current_joint_state->getJoint()->getPosition() + delta); + } } //----------------------------------------------------------------------------- @@ -1227,408 +1227,408 @@ void LLKeyframeMotion::applyConstraint(JointConstraint* constraint, F32 time, U8 //----------------------------------------------------------------------------- BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, bool allow_invalid_joints) { - BOOL old_version = FALSE; - std::unique_ptr<LLKeyframeMotion::JointMotionList> joint_motion_list(new LLKeyframeMotion::JointMotionList); - - //------------------------------------------------------------------------- - // get base priority - //------------------------------------------------------------------------- - S32 temp_priority; - U16 version; - U16 sub_version; - - if (!dp.unpackU16(version, "version")) - { - LL_WARNS() << "can't read version number for animation " << asset_id << LL_ENDL; - return FALSE; - } - - if (!dp.unpackU16(sub_version, "sub_version")) - { - LL_WARNS() << "can't read sub version number for animation " << asset_id << LL_ENDL; - return FALSE; - } - - if (version == 0 && sub_version == 1) - { - old_version = TRUE; - } - else if (version != KEYFRAME_MOTION_VERSION || sub_version != KEYFRAME_MOTION_SUBVERSION) - { + BOOL old_version = FALSE; + std::unique_ptr<LLKeyframeMotion::JointMotionList> joint_motion_list(new LLKeyframeMotion::JointMotionList); + + //------------------------------------------------------------------------- + // get base priority + //------------------------------------------------------------------------- + S32 temp_priority; + U16 version; + U16 sub_version; + + if (!dp.unpackU16(version, "version")) + { + LL_WARNS() << "can't read version number for animation " << asset_id << LL_ENDL; + return FALSE; + } + + if (!dp.unpackU16(sub_version, "sub_version")) + { + LL_WARNS() << "can't read sub version number for animation " << asset_id << LL_ENDL; + return FALSE; + } + + if (version == 0 && sub_version == 1) + { + old_version = TRUE; + } + else if (version != KEYFRAME_MOTION_VERSION || sub_version != KEYFRAME_MOTION_SUBVERSION) + { #if LL_RELEASE - LL_WARNS() << "Bad animation version " << version << "." << sub_version + LL_WARNS() << "Bad animation version " << version << "." << sub_version << " for animation " << asset_id << LL_ENDL; - return FALSE; + return FALSE; #else - LL_ERRS() << "Bad animation version " << version << "." << sub_version + LL_ERRS() << "Bad animation version " << version << "." << sub_version << " for animation " << asset_id << LL_ENDL; #endif - } + } - if (!dp.unpackS32(temp_priority, "base_priority")) - { - LL_WARNS() << "can't read animation base_priority" + if (!dp.unpackS32(temp_priority, "base_priority")) + { + LL_WARNS() << "can't read animation base_priority" << " for animation " << asset_id << LL_ENDL; - return FALSE; - } - joint_motion_list->mBasePriority = (LLJoint::JointPriority) temp_priority; - - if (joint_motion_list->mBasePriority >= LLJoint::ADDITIVE_PRIORITY) - { - joint_motion_list->mBasePriority = (LLJoint::JointPriority)((S32)LLJoint::ADDITIVE_PRIORITY-1); - joint_motion_list->mMaxPriority = joint_motion_list->mBasePriority; - } - else if (joint_motion_list->mBasePriority < LLJoint::USE_MOTION_PRIORITY) - { - LL_WARNS() << "bad animation base_priority " << joint_motion_list->mBasePriority + return FALSE; + } + joint_motion_list->mBasePriority = (LLJoint::JointPriority) temp_priority; + + if (joint_motion_list->mBasePriority >= LLJoint::ADDITIVE_PRIORITY) + { + joint_motion_list->mBasePriority = (LLJoint::JointPriority)((S32)LLJoint::ADDITIVE_PRIORITY-1); + joint_motion_list->mMaxPriority = joint_motion_list->mBasePriority; + } + else if (joint_motion_list->mBasePriority < LLJoint::USE_MOTION_PRIORITY) + { + LL_WARNS() << "bad animation base_priority " << joint_motion_list->mBasePriority << " for animation " << asset_id << LL_ENDL; - return FALSE; - } - - //------------------------------------------------------------------------- - // get duration - //------------------------------------------------------------------------- - if (!dp.unpackF32(joint_motion_list->mDuration, "duration")) - { - LL_WARNS() << "can't read duration" + return FALSE; + } + + //------------------------------------------------------------------------- + // get duration + //------------------------------------------------------------------------- + if (!dp.unpackF32(joint_motion_list->mDuration, "duration")) + { + LL_WARNS() << "can't read duration" << " for animation " << asset_id << LL_ENDL; - return FALSE; - } - - if (joint_motion_list->mDuration > MAX_ANIM_DURATION || - !llfinite(joint_motion_list->mDuration)) - { - LL_WARNS() << "invalid animation duration" + return FALSE; + } + + if (joint_motion_list->mDuration > MAX_ANIM_DURATION || + !llfinite(joint_motion_list->mDuration)) + { + LL_WARNS() << "invalid animation duration" << " for animation " << asset_id << LL_ENDL; - return FALSE; - } - - //------------------------------------------------------------------------- - // get emote (optional) - //------------------------------------------------------------------------- - if (!dp.unpackString(joint_motion_list->mEmoteName, "emote_name")) - { - LL_WARNS() << "can't read optional_emote_animation" + return FALSE; + } + + //------------------------------------------------------------------------- + // get emote (optional) + //------------------------------------------------------------------------- + if (!dp.unpackString(joint_motion_list->mEmoteName, "emote_name")) + { + LL_WARNS() << "can't read optional_emote_animation" << " for animation " << asset_id << LL_ENDL; - return FALSE; - } + return FALSE; + } - if(joint_motion_list->mEmoteName==mID.asString()) - { - LL_WARNS() << "Malformed animation mEmoteName==mID" + if(joint_motion_list->mEmoteName==mID.asString()) + { + LL_WARNS() << "Malformed animation mEmoteName==mID" << " for animation " << asset_id << LL_ENDL; - return FALSE; - } - - //------------------------------------------------------------------------- - // get loop - //------------------------------------------------------------------------- - if (!dp.unpackF32(joint_motion_list->mLoopInPoint, "loop_in_point") || - !llfinite(joint_motion_list->mLoopInPoint)) - { - LL_WARNS() << "can't read loop point" + return FALSE; + } + + //------------------------------------------------------------------------- + // get loop + //------------------------------------------------------------------------- + if (!dp.unpackF32(joint_motion_list->mLoopInPoint, "loop_in_point") || + !llfinite(joint_motion_list->mLoopInPoint)) + { + LL_WARNS() << "can't read loop point" << " for animation " << asset_id << LL_ENDL; - return FALSE; - } + return FALSE; + } - if (!dp.unpackF32(joint_motion_list->mLoopOutPoint, "loop_out_point") || - !llfinite(joint_motion_list->mLoopOutPoint)) - { - LL_WARNS() << "can't read loop point" + if (!dp.unpackF32(joint_motion_list->mLoopOutPoint, "loop_out_point") || + !llfinite(joint_motion_list->mLoopOutPoint)) + { + LL_WARNS() << "can't read loop point" << " for animation " << asset_id << LL_ENDL; - return FALSE; - } + return FALSE; + } - if (!dp.unpackS32(joint_motion_list->mLoop, "loop")) - { - LL_WARNS() << "can't read loop" + if (!dp.unpackS32(joint_motion_list->mLoop, "loop")) + { + LL_WARNS() << "can't read loop" << " for animation " << asset_id << LL_ENDL; - return FALSE; - } - - //SL-17206 hack to alter Female_land loop setting, while current behavior won't be changed serverside - LLUUID const female_land_anim("ca1baf4d-0a18-5a1f-0330-e4bd1e71f09e"); - LLUUID const formal_female_land_anim("6a9a173b-61fa-3ad5-01fa-a851cfc5f66a"); - if (female_land_anim == asset_id || formal_female_land_anim == asset_id) - { - LL_WARNS() << "Animation(" << asset_id << ") won't be looped." << LL_ENDL; - joint_motion_list->mLoop = FALSE; - } - - //------------------------------------------------------------------------- - // get easeIn and easeOut - //------------------------------------------------------------------------- - if (!dp.unpackF32(joint_motion_list->mEaseInDuration, "ease_in_duration") || - !llfinite(joint_motion_list->mEaseInDuration)) - { - LL_WARNS() << "can't read easeIn" + return FALSE; + } + + //SL-17206 hack to alter Female_land loop setting, while current behavior won't be changed serverside + LLUUID const female_land_anim("ca1baf4d-0a18-5a1f-0330-e4bd1e71f09e"); + LLUUID const formal_female_land_anim("6a9a173b-61fa-3ad5-01fa-a851cfc5f66a"); + if (female_land_anim == asset_id || formal_female_land_anim == asset_id) + { + LL_WARNS() << "Animation(" << asset_id << ") won't be looped." << LL_ENDL; + joint_motion_list->mLoop = FALSE; + } + + //------------------------------------------------------------------------- + // get easeIn and easeOut + //------------------------------------------------------------------------- + if (!dp.unpackF32(joint_motion_list->mEaseInDuration, "ease_in_duration") || + !llfinite(joint_motion_list->mEaseInDuration)) + { + LL_WARNS() << "can't read easeIn" << " for animation " << asset_id << LL_ENDL; - return FALSE; - } + return FALSE; + } - if (!dp.unpackF32(joint_motion_list->mEaseOutDuration, "ease_out_duration") || - !llfinite(joint_motion_list->mEaseOutDuration)) - { - LL_WARNS() << "can't read easeOut" + if (!dp.unpackF32(joint_motion_list->mEaseOutDuration, "ease_out_duration") || + !llfinite(joint_motion_list->mEaseOutDuration)) + { + LL_WARNS() << "can't read easeOut" << " for animation " << asset_id << LL_ENDL; - return FALSE; - } - - //------------------------------------------------------------------------- - // get hand pose - //------------------------------------------------------------------------- - U32 word; - if (!dp.unpackU32(word, "hand_pose")) - { - LL_WARNS() << "can't read hand pose" + return FALSE; + } + + //------------------------------------------------------------------------- + // get hand pose + //------------------------------------------------------------------------- + U32 word; + if (!dp.unpackU32(word, "hand_pose")) + { + LL_WARNS() << "can't read hand pose" << " for animation " << asset_id << LL_ENDL; - return FALSE; - } - - if(word > LLHandMotion::NUM_HAND_POSES) - { - LL_WARNS() << "invalid LLHandMotion::eHandPose index: " << word + return FALSE; + } + + if(word > LLHandMotion::NUM_HAND_POSES) + { + LL_WARNS() << "invalid LLHandMotion::eHandPose index: " << word << " for animation " << asset_id << LL_ENDL; - return FALSE; - } - - joint_motion_list->mHandPose = (LLHandMotion::eHandPose)word; - - //------------------------------------------------------------------------- - // get number of joint motions - //------------------------------------------------------------------------- - U32 num_motions = 0; + return FALSE; + } + + joint_motion_list->mHandPose = (LLHandMotion::eHandPose)word; + + //------------------------------------------------------------------------- + // get number of joint motions + //------------------------------------------------------------------------- + U32 num_motions = 0; S32 rotation_dupplicates = 0; S32 position_dupplicates = 0; - if (!dp.unpackU32(num_motions, "num_joints")) - { - LL_WARNS() << "can't read number of joints" + if (!dp.unpackU32(num_motions, "num_joints")) + { + LL_WARNS() << "can't read number of joints" << " for animation " << asset_id << LL_ENDL; - return FALSE; - } + return FALSE; + } - if (num_motions == 0) - { - LL_WARNS() << "no joints" + if (num_motions == 0) + { + LL_WARNS() << "no joints" << " for animation " << asset_id << LL_ENDL; - return FALSE; - } - else if (num_motions > LL_CHARACTER_MAX_ANIMATED_JOINTS) - { - LL_WARNS() << "too many joints" + return FALSE; + } + else if (num_motions > LL_CHARACTER_MAX_ANIMATED_JOINTS) + { + LL_WARNS() << "too many joints" << " for animation " << asset_id << LL_ENDL; - return FALSE; - } - - joint_motion_list->mJointMotionArray.clear(); - joint_motion_list->mJointMotionArray.reserve(num_motions); - mJointStates.clear(); - mJointStates.reserve(num_motions); - - //------------------------------------------------------------------------- - // initialize joint motions - //------------------------------------------------------------------------- - - for(U32 i=0; i<num_motions; ++i) - { - JointMotion* joint_motion = new JointMotion; - joint_motion_list->mJointMotionArray.push_back(joint_motion); - - std::string joint_name; - if (!dp.unpackString(joint_name, "joint_name")) - { - LL_WARNS() << "can't read joint name" + return FALSE; + } + + joint_motion_list->mJointMotionArray.clear(); + joint_motion_list->mJointMotionArray.reserve(num_motions); + mJointStates.clear(); + mJointStates.reserve(num_motions); + + //------------------------------------------------------------------------- + // initialize joint motions + //------------------------------------------------------------------------- + + for(U32 i=0; i<num_motions; ++i) + { + JointMotion* joint_motion = new JointMotion; + joint_motion_list->mJointMotionArray.push_back(joint_motion); + + std::string joint_name; + if (!dp.unpackString(joint_name, "joint_name")) + { + LL_WARNS() << "can't read joint name" << " for animation " << asset_id << LL_ENDL; - return FALSE; - } + return FALSE; + } - if (joint_name == "mScreen" || joint_name == "mRoot") - { - LL_WARNS() << "attempted to animate special " << joint_name << " joint" + if (joint_name == "mScreen" || joint_name == "mRoot") + { + LL_WARNS() << "attempted to animate special " << joint_name << " joint" << " for animation " << asset_id << LL_ENDL; - return FALSE; - } - - //--------------------------------------------------------------------- - // find the corresponding joint - //--------------------------------------------------------------------- - LLJoint *joint = mCharacter->getJoint( joint_name ); - if (joint) - { + return FALSE; + } + + //--------------------------------------------------------------------- + // find the corresponding joint + //--------------------------------------------------------------------- + LLJoint *joint = mCharacter->getJoint( joint_name ); + if (joint) + { S32 joint_num = joint->getJointNum(); - joint_name = joint->getName(); // canonical name in case this is an alias. -// LL_INFOS() << " joint: " << joint_name << LL_ENDL; + joint_name = joint->getName(); // canonical name in case this is an alias. +// LL_INFOS() << " joint: " << joint_name << LL_ENDL; if ((joint_num >= (S32)LL_CHARACTER_MAX_ANIMATED_JOINTS) || (joint_num < 0)) { - LL_WARNS() << "Joint will be omitted from animation: joint_num " << joint_num + LL_WARNS() << "Joint will be omitted from animation: joint_num " << joint_num << " is outside of legal range [0-" << LL_CHARACTER_MAX_ANIMATED_JOINTS << ") for joint " << joint->getName() << " for animation " << asset_id << LL_ENDL; joint = NULL; } - } - else - { - LL_WARNS() << "invalid joint name: " << joint_name + } + else + { + LL_WARNS() << "invalid joint name: " << joint_name << " for animation " << asset_id << LL_ENDL; - if (!allow_invalid_joints) - { - return FALSE; - } - } - - joint_motion->mJointName = joint_name; - - LLPointer<LLJointState> joint_state = new LLJointState; - mJointStates.push_back(joint_state); - joint_state->setJoint( joint ); // note: can accept NULL - joint_state->setUsage( 0 ); - - //--------------------------------------------------------------------- - // get joint priority - //--------------------------------------------------------------------- - S32 joint_priority; - if (!dp.unpackS32(joint_priority, "joint_priority")) - { - LL_WARNS() << "can't read joint priority." + if (!allow_invalid_joints) + { + return FALSE; + } + } + + joint_motion->mJointName = joint_name; + + LLPointer<LLJointState> joint_state = new LLJointState; + mJointStates.push_back(joint_state); + joint_state->setJoint( joint ); // note: can accept NULL + joint_state->setUsage( 0 ); + + //--------------------------------------------------------------------- + // get joint priority + //--------------------------------------------------------------------- + S32 joint_priority; + if (!dp.unpackS32(joint_priority, "joint_priority")) + { + LL_WARNS() << "can't read joint priority." << " for animation " << asset_id << LL_ENDL; - return FALSE; - } + return FALSE; + } - if (joint_priority < LLJoint::USE_MOTION_PRIORITY) - { - LL_WARNS() << "joint priority unknown - too low." + if (joint_priority < LLJoint::USE_MOTION_PRIORITY) + { + LL_WARNS() << "joint priority unknown - too low." << " for animation " << asset_id << LL_ENDL; - return FALSE; - } - - joint_motion->mPriority = (LLJoint::JointPriority)joint_priority; - if (joint_priority != LLJoint::USE_MOTION_PRIORITY && - joint_priority > joint_motion_list->mMaxPriority) - { - joint_motion_list->mMaxPriority = (LLJoint::JointPriority)joint_priority; - } - - joint_state->setPriority((LLJoint::JointPriority)joint_priority); - - //--------------------------------------------------------------------- - // scan rotation curve header - //--------------------------------------------------------------------- - if (!dp.unpackS32(joint_motion->mRotationCurve.mNumKeys, "num_rot_keys") || joint_motion->mRotationCurve.mNumKeys < 0) - { - LL_WARNS() << "can't read number of rotation keys" + return FALSE; + } + + joint_motion->mPriority = (LLJoint::JointPriority)joint_priority; + if (joint_priority != LLJoint::USE_MOTION_PRIORITY && + joint_priority > joint_motion_list->mMaxPriority) + { + joint_motion_list->mMaxPriority = (LLJoint::JointPriority)joint_priority; + } + + joint_state->setPriority((LLJoint::JointPriority)joint_priority); + + //--------------------------------------------------------------------- + // scan rotation curve header + //--------------------------------------------------------------------- + if (!dp.unpackS32(joint_motion->mRotationCurve.mNumKeys, "num_rot_keys") || joint_motion->mRotationCurve.mNumKeys < 0) + { + LL_WARNS() << "can't read number of rotation keys" << " for animation " << asset_id << LL_ENDL; - return FALSE; - } - - joint_motion->mRotationCurve.mInterpolationType = IT_LINEAR; - if (joint_motion->mRotationCurve.mNumKeys != 0) - { - joint_state->setUsage(joint_state->getUsage() | LLJointState::ROT ); - } - - //--------------------------------------------------------------------- - // scan rotation curve keys - //--------------------------------------------------------------------- - RotationCurve *rCurve = &joint_motion->mRotationCurve; - - for (S32 k = 0; k < joint_motion->mRotationCurve.mNumKeys; k++) - { - F32 time; - U16 time_short; - - if (old_version) - { - if (!dp.unpackF32(time, "time") || - !llfinite(time)) - { - LL_WARNS() << "can't read rotation key (" << k << ")" + return FALSE; + } + + joint_motion->mRotationCurve.mInterpolationType = IT_LINEAR; + if (joint_motion->mRotationCurve.mNumKeys != 0) + { + joint_state->setUsage(joint_state->getUsage() | LLJointState::ROT ); + } + + //--------------------------------------------------------------------- + // scan rotation curve keys + //--------------------------------------------------------------------- + RotationCurve *rCurve = &joint_motion->mRotationCurve; + + for (S32 k = 0; k < joint_motion->mRotationCurve.mNumKeys; k++) + { + F32 time; + U16 time_short; + + if (old_version) + { + if (!dp.unpackF32(time, "time") || + !llfinite(time)) + { + LL_WARNS() << "can't read rotation key (" << k << ")" << " for animation " << asset_id << LL_ENDL; - return FALSE; - } - - } - else - { - if (!dp.unpackU16(time_short, "time")) - { - LL_WARNS() << "can't read rotation key (" << k << ")" + return FALSE; + } + + } + else + { + if (!dp.unpackU16(time_short, "time")) + { + LL_WARNS() << "can't read rotation key (" << k << ")" << " for animation " << asset_id << LL_ENDL; - return FALSE; - } - - time = U16_to_F32(time_short, 0.f, joint_motion_list->mDuration); - - if (time < 0 || time > joint_motion_list->mDuration) - { - LL_WARNS() << "invalid frame time" + return FALSE; + } + + time = U16_to_F32(time_short, 0.f, joint_motion_list->mDuration); + + if (time < 0 || time > joint_motion_list->mDuration) + { + LL_WARNS() << "invalid frame time" << " for animation " << asset_id << LL_ENDL; - return FALSE; - } - } - - RotationKey rot_key; - rot_key.mTime = time; - LLVector3 rot_angles; - U16 x, y, z; - - if (old_version) - { - if (!dp.unpackVector3(rot_angles, "rot_angles")) - { - LL_WARNS() << "can't read rot_angles in rotation key (" << k << ")" << LL_ENDL; - return FALSE; - } - if (!rot_angles.isFinite()) - { - LL_WARNS() << "non-finite angle in rotation key (" << k << ")" << LL_ENDL; - return FALSE; - } - - LLQuaternion::Order ro = StringToOrder("ZYX"); - rot_key.mRotation = mayaQ(rot_angles.mV[VX], rot_angles.mV[VY], rot_angles.mV[VZ], ro); - } - else - { - if (!dp.unpackU16(x, "rot_angle_x")) - { - LL_WARNS() << "can't read rot_angle_x in rotation key (" << k << ")" << LL_ENDL; - return FALSE; - } - if (!dp.unpackU16(y, "rot_angle_y")) - { - LL_WARNS() << "can't read rot_angle_y in rotation key (" << k << ")" << LL_ENDL; - return FALSE; - } - if (!dp.unpackU16(z, "rot_angle_z")) - { - LL_WARNS() << "can't read rot_angle_z in rotation key (" << k << ")" << LL_ENDL; - return FALSE; - } - - LLVector3 rot_vec; - rot_vec.mV[VX] = U16_to_F32(x, -1.f, 1.f); - rot_vec.mV[VY] = U16_to_F32(y, -1.f, 1.f); - rot_vec.mV[VZ] = U16_to_F32(z, -1.f, 1.f); - - if(!rot_vec.isFinite()) - { - LL_WARNS() << "non-finite angle in rotation key (" << k << ")" - << " for animation " << asset_id << LL_ENDL; - return FALSE; - } - rot_key.mRotation.unpackFromVector3(rot_vec); - } - - if(!rot_key.mRotation.isFinite()) - { - LL_WARNS() << "non-finite angle in rotation key (" << k << ")" + return FALSE; + } + } + + RotationKey rot_key; + rot_key.mTime = time; + LLVector3 rot_angles; + U16 x, y, z; + + if (old_version) + { + if (!dp.unpackVector3(rot_angles, "rot_angles")) + { + LL_WARNS() << "can't read rot_angles in rotation key (" << k << ")" << LL_ENDL; + return FALSE; + } + if (!rot_angles.isFinite()) + { + LL_WARNS() << "non-finite angle in rotation key (" << k << ")" << LL_ENDL; + return FALSE; + } + + LLQuaternion::Order ro = StringToOrder("ZYX"); + rot_key.mRotation = mayaQ(rot_angles.mV[VX], rot_angles.mV[VY], rot_angles.mV[VZ], ro); + } + else + { + if (!dp.unpackU16(x, "rot_angle_x")) + { + LL_WARNS() << "can't read rot_angle_x in rotation key (" << k << ")" << LL_ENDL; + return FALSE; + } + if (!dp.unpackU16(y, "rot_angle_y")) + { + LL_WARNS() << "can't read rot_angle_y in rotation key (" << k << ")" << LL_ENDL; + return FALSE; + } + if (!dp.unpackU16(z, "rot_angle_z")) + { + LL_WARNS() << "can't read rot_angle_z in rotation key (" << k << ")" << LL_ENDL; + return FALSE; + } + + LLVector3 rot_vec; + rot_vec.mV[VX] = U16_to_F32(x, -1.f, 1.f); + rot_vec.mV[VY] = U16_to_F32(y, -1.f, 1.f); + rot_vec.mV[VZ] = U16_to_F32(z, -1.f, 1.f); + + if(!rot_vec.isFinite()) + { + LL_WARNS() << "non-finite angle in rotation key (" << k << ")" + << " for animation " << asset_id << LL_ENDL; + return FALSE; + } + rot_key.mRotation.unpackFromVector3(rot_vec); + } + + if(!rot_key.mRotation.isFinite()) + { + LL_WARNS() << "non-finite angle in rotation key (" << k << ")" << " for animation " << asset_id << LL_ENDL; - return FALSE; - } + return FALSE; + } - rCurve->mKeys[time] = rot_key; - } + rCurve->mKeys[time] = rot_key; + } if (joint_motion->mRotationCurve.mNumKeys > joint_motion->mRotationCurve.mKeys.size()) { @@ -1636,115 +1636,115 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo LL_INFOS() << "Motion: " << asset_id << " had dupplicate rotation keys that were removed" << LL_ENDL; } - //--------------------------------------------------------------------- - // scan position curve header - //--------------------------------------------------------------------- - if (!dp.unpackS32(joint_motion->mPositionCurve.mNumKeys, "num_pos_keys") || joint_motion->mPositionCurve.mNumKeys < 0) - { - LL_WARNS() << "can't read number of position keys" + //--------------------------------------------------------------------- + // scan position curve header + //--------------------------------------------------------------------- + if (!dp.unpackS32(joint_motion->mPositionCurve.mNumKeys, "num_pos_keys") || joint_motion->mPositionCurve.mNumKeys < 0) + { + LL_WARNS() << "can't read number of position keys" << " for animation " << asset_id << LL_ENDL; - return FALSE; - } - - joint_motion->mPositionCurve.mInterpolationType = IT_LINEAR; - if (joint_motion->mPositionCurve.mNumKeys != 0) - { - joint_state->setUsage(joint_state->getUsage() | LLJointState::POS ); - } - - //--------------------------------------------------------------------- - // scan position curve keys - //--------------------------------------------------------------------- - PositionCurve *pCurve = &joint_motion->mPositionCurve; - BOOL is_pelvis = joint_motion->mJointName == "mPelvis"; - for (S32 k = 0; k < joint_motion->mPositionCurve.mNumKeys; k++) - { - U16 time_short; - PositionKey pos_key; - - if (old_version) - { - if (!dp.unpackF32(pos_key.mTime, "time") || - !llfinite(pos_key.mTime)) - { - LL_WARNS() << "can't read position key (" << k << ")" + return FALSE; + } + + joint_motion->mPositionCurve.mInterpolationType = IT_LINEAR; + if (joint_motion->mPositionCurve.mNumKeys != 0) + { + joint_state->setUsage(joint_state->getUsage() | LLJointState::POS ); + } + + //--------------------------------------------------------------------- + // scan position curve keys + //--------------------------------------------------------------------- + PositionCurve *pCurve = &joint_motion->mPositionCurve; + BOOL is_pelvis = joint_motion->mJointName == "mPelvis"; + for (S32 k = 0; k < joint_motion->mPositionCurve.mNumKeys; k++) + { + U16 time_short; + PositionKey pos_key; + + if (old_version) + { + if (!dp.unpackF32(pos_key.mTime, "time") || + !llfinite(pos_key.mTime)) + { + LL_WARNS() << "can't read position key (" << k << ")" << " for animation " << asset_id << LL_ENDL; - return FALSE; - } - } - else - { - if (!dp.unpackU16(time_short, "time")) - { - LL_WARNS() << "can't read position key (" << k << ")" + return FALSE; + } + } + else + { + if (!dp.unpackU16(time_short, "time")) + { + LL_WARNS() << "can't read position key (" << k << ")" << " for animation " << asset_id << LL_ENDL; - return FALSE; - } - - pos_key.mTime = U16_to_F32(time_short, 0.f, joint_motion_list->mDuration); - } - - if (old_version) - { - if (!dp.unpackVector3(pos_key.mPosition, "pos")) - { - LL_WARNS() << "can't read pos in position key (" << k << ")" << LL_ENDL; - return FALSE; - } - + return FALSE; + } + + pos_key.mTime = U16_to_F32(time_short, 0.f, joint_motion_list->mDuration); + } + + if (old_version) + { + if (!dp.unpackVector3(pos_key.mPosition, "pos")) + { + LL_WARNS() << "can't read pos in position key (" << k << ")" << LL_ENDL; + return FALSE; + } + //MAINT-6162 pos_key.mPosition.mV[VX] = llclamp( pos_key.mPosition.mV[VX], -LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET); pos_key.mPosition.mV[VY] = llclamp( pos_key.mPosition.mV[VY], -LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET); pos_key.mPosition.mV[VZ] = llclamp( pos_key.mPosition.mV[VZ], -LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET); - - } - else - { - U16 x, y, z; - - if (!dp.unpackU16(x, "pos_x")) - { - LL_WARNS() << "can't read pos_x in position key (" << k << ")" << LL_ENDL; - return FALSE; - } - if (!dp.unpackU16(y, "pos_y")) - { - LL_WARNS() << "can't read pos_y in position key (" << k << ")" << LL_ENDL; - return FALSE; - } - if (!dp.unpackU16(z, "pos_z")) - { - LL_WARNS() << "can't read pos_z in position key (" << k << ")" << LL_ENDL; - return FALSE; - } - - pos_key.mPosition.mV[VX] = U16_to_F32(x, -LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET); - pos_key.mPosition.mV[VY] = U16_to_F32(y, -LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET); - pos_key.mPosition.mV[VZ] = U16_to_F32(z, -LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET); - } - - if(!pos_key.mPosition.isFinite()) - { - LL_WARNS() << "non-finite position in key" + + } + else + { + U16 x, y, z; + + if (!dp.unpackU16(x, "pos_x")) + { + LL_WARNS() << "can't read pos_x in position key (" << k << ")" << LL_ENDL; + return FALSE; + } + if (!dp.unpackU16(y, "pos_y")) + { + LL_WARNS() << "can't read pos_y in position key (" << k << ")" << LL_ENDL; + return FALSE; + } + if (!dp.unpackU16(z, "pos_z")) + { + LL_WARNS() << "can't read pos_z in position key (" << k << ")" << LL_ENDL; + return FALSE; + } + + pos_key.mPosition.mV[VX] = U16_to_F32(x, -LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET); + pos_key.mPosition.mV[VY] = U16_to_F32(y, -LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET); + pos_key.mPosition.mV[VZ] = U16_to_F32(z, -LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET); + } + + if(!pos_key.mPosition.isFinite()) + { + LL_WARNS() << "non-finite position in key" << " for animation " << asset_id << LL_ENDL; - return FALSE; - } - - pCurve->mKeys[pos_key.mTime] = pos_key; + return FALSE; + } - if (is_pelvis) - { - joint_motion_list->mPelvisBBox.addPoint(pos_key.mPosition); - } - } + pCurve->mKeys[pos_key.mTime] = pos_key; + + if (is_pelvis) + { + joint_motion_list->mPelvisBBox.addPoint(pos_key.mPosition); + } + } if (joint_motion->mPositionCurve.mNumKeys > joint_motion->mPositionCurve.mKeys.size()) { position_dupplicates++; } - joint_motion->mUsage = joint_state->getUsage(); - } + joint_motion->mUsage = joint_state->getUsage(); + } if (rotation_dupplicates > 0) { @@ -1756,243 +1756,243 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo LL_INFOS() << "Motion: " << asset_id << " had " << position_dupplicates << " dupplicate position keys that were removed" << LL_ENDL; } - //------------------------------------------------------------------------- - // get number of constraints - //------------------------------------------------------------------------- - S32 num_constraints = 0; - if (!dp.unpackS32(num_constraints, "num_constraints")) - { - LL_WARNS() << "can't read number of constraints" + //------------------------------------------------------------------------- + // get number of constraints + //------------------------------------------------------------------------- + S32 num_constraints = 0; + if (!dp.unpackS32(num_constraints, "num_constraints")) + { + LL_WARNS() << "can't read number of constraints" << " for animation " << asset_id << LL_ENDL; - return FALSE; - } + return FALSE; + } - if (num_constraints > MAX_CONSTRAINTS || num_constraints < 0) - { - LL_WARNS() << "Bad number of constraints... ignoring: " << num_constraints + if (num_constraints > MAX_CONSTRAINTS || num_constraints < 0) + { + LL_WARNS() << "Bad number of constraints... ignoring: " << num_constraints << " for animation " << asset_id << LL_ENDL; - } - else - { - //------------------------------------------------------------------------- - // get constraints - //------------------------------------------------------------------------- - std::string str; - for(S32 i = 0; i < num_constraints; ++i) - { - // read in constraint data - std::unique_ptr<JointConstraintSharedData> constraintp(new JointConstraintSharedData); - U8 byte = 0; - - if (!dp.unpackU8(byte, "chain_length")) - { - LL_WARNS() << "can't read constraint chain length" + } + else + { + //------------------------------------------------------------------------- + // get constraints + //------------------------------------------------------------------------- + std::string str; + for(S32 i = 0; i < num_constraints; ++i) + { + // read in constraint data + std::unique_ptr<JointConstraintSharedData> constraintp(new JointConstraintSharedData); + U8 byte = 0; + + if (!dp.unpackU8(byte, "chain_length")) + { + LL_WARNS() << "can't read constraint chain length" << " for animation " << asset_id << LL_ENDL; - return FALSE; - } - constraintp->mChainLength = (S32) byte; + return FALSE; + } + constraintp->mChainLength = (S32) byte; - if((U32)constraintp->mChainLength > joint_motion_list->getNumJointMotions()) - { - LL_WARNS() << "invalid constraint chain length" + if((U32)constraintp->mChainLength > joint_motion_list->getNumJointMotions()) + { + LL_WARNS() << "invalid constraint chain length" << " for animation " << asset_id << LL_ENDL; - return FALSE; - } + return FALSE; + } - if (!dp.unpackU8(byte, "constraint_type")) - { - LL_WARNS() << "can't read constraint type" + if (!dp.unpackU8(byte, "constraint_type")) + { + LL_WARNS() << "can't read constraint type" << " for animation " << asset_id << LL_ENDL; - return FALSE; - } - - if( byte >= NUM_CONSTRAINT_TYPES ) - { - LL_WARNS() << "invalid constraint type" + return FALSE; + } + + if( byte >= NUM_CONSTRAINT_TYPES ) + { + LL_WARNS() << "invalid constraint type" << " for animation " << asset_id << LL_ENDL; - return FALSE; - } - constraintp->mConstraintType = (EConstraintType)byte; - - const S32 BIN_DATA_LENGTH = 16; - U8 bin_data[BIN_DATA_LENGTH+1]; - if (!dp.unpackBinaryDataFixed(bin_data, BIN_DATA_LENGTH, "source_volume")) - { - LL_WARNS() << "can't read source volume name" + return FALSE; + } + constraintp->mConstraintType = (EConstraintType)byte; + + const S32 BIN_DATA_LENGTH = 16; + U8 bin_data[BIN_DATA_LENGTH+1]; + if (!dp.unpackBinaryDataFixed(bin_data, BIN_DATA_LENGTH, "source_volume")) + { + LL_WARNS() << "can't read source volume name" << " for animation " << asset_id << LL_ENDL; - return FALSE; - } - - bin_data[BIN_DATA_LENGTH] = 0; // Ensure null termination - str = (char*)bin_data; - constraintp->mSourceConstraintVolume = mCharacter->getCollisionVolumeID(str); - if (constraintp->mSourceConstraintVolume == -1) - { - LL_WARNS() << "not a valid source constraint volume " << str - << " for animation " << asset_id << LL_ENDL; - return FALSE; - } - - if (!dp.unpackVector3(constraintp->mSourceConstraintOffset, "source_offset")) - { - LL_WARNS() << "can't read constraint source offset" + return FALSE; + } + + bin_data[BIN_DATA_LENGTH] = 0; // Ensure null termination + str = (char*)bin_data; + constraintp->mSourceConstraintVolume = mCharacter->getCollisionVolumeID(str); + if (constraintp->mSourceConstraintVolume == -1) + { + LL_WARNS() << "not a valid source constraint volume " << str << " for animation " << asset_id << LL_ENDL; - return FALSE; - } - - if( !(constraintp->mSourceConstraintOffset.isFinite()) ) - { - LL_WARNS() << "non-finite constraint source offset" + return FALSE; + } + + if (!dp.unpackVector3(constraintp->mSourceConstraintOffset, "source_offset")) + { + LL_WARNS() << "can't read constraint source offset" << " for animation " << asset_id << LL_ENDL; - return FALSE; - } - - if (!dp.unpackBinaryDataFixed(bin_data, BIN_DATA_LENGTH, "target_volume")) - { - LL_WARNS() << "can't read target volume name" + return FALSE; + } + + if( !(constraintp->mSourceConstraintOffset.isFinite()) ) + { + LL_WARNS() << "non-finite constraint source offset" << " for animation " << asset_id << LL_ENDL; - return FALSE; - } - - bin_data[BIN_DATA_LENGTH] = 0; // Ensure null termination - str = (char*)bin_data; - if (str == "GROUND") - { - // constrain to ground - constraintp->mConstraintTargetType = CONSTRAINT_TARGET_TYPE_GROUND; - } - else - { - constraintp->mConstraintTargetType = CONSTRAINT_TARGET_TYPE_BODY; - constraintp->mTargetConstraintVolume = mCharacter->getCollisionVolumeID(str); - if (constraintp->mTargetConstraintVolume == -1) - { - LL_WARNS() << "not a valid target constraint volume " << str - << " for animation " << asset_id << LL_ENDL; - return FALSE; - } - } - - if (!dp.unpackVector3(constraintp->mTargetConstraintOffset, "target_offset")) - { - LL_WARNS() << "can't read constraint target offset" + return FALSE; + } + + if (!dp.unpackBinaryDataFixed(bin_data, BIN_DATA_LENGTH, "target_volume")) + { + LL_WARNS() << "can't read target volume name" << " for animation " << asset_id << LL_ENDL; - return FALSE; - } + return FALSE; + } - if( !(constraintp->mTargetConstraintOffset.isFinite()) ) - { - LL_WARNS() << "non-finite constraint target offset" + bin_data[BIN_DATA_LENGTH] = 0; // Ensure null termination + str = (char*)bin_data; + if (str == "GROUND") + { + // constrain to ground + constraintp->mConstraintTargetType = CONSTRAINT_TARGET_TYPE_GROUND; + } + else + { + constraintp->mConstraintTargetType = CONSTRAINT_TARGET_TYPE_BODY; + constraintp->mTargetConstraintVolume = mCharacter->getCollisionVolumeID(str); + if (constraintp->mTargetConstraintVolume == -1) + { + LL_WARNS() << "not a valid target constraint volume " << str + << " for animation " << asset_id << LL_ENDL; + return FALSE; + } + } + + if (!dp.unpackVector3(constraintp->mTargetConstraintOffset, "target_offset")) + { + LL_WARNS() << "can't read constraint target offset" << " for animation " << asset_id << LL_ENDL; - return FALSE; - } - - if (!dp.unpackVector3(constraintp->mTargetConstraintDir, "target_dir")) - { - LL_WARNS() << "can't read constraint target direction" + return FALSE; + } + + if( !(constraintp->mTargetConstraintOffset.isFinite()) ) + { + LL_WARNS() << "non-finite constraint target offset" << " for animation " << asset_id << LL_ENDL; - return FALSE; - } + return FALSE; + } + + if (!dp.unpackVector3(constraintp->mTargetConstraintDir, "target_dir")) + { + LL_WARNS() << "can't read constraint target direction" + << " for animation " << asset_id << LL_ENDL; + return FALSE; + } - if( !(constraintp->mTargetConstraintDir.isFinite()) ) - { - LL_WARNS() << "non-finite constraint target direction" + if( !(constraintp->mTargetConstraintDir.isFinite()) ) + { + LL_WARNS() << "non-finite constraint target direction" << " for animation " << asset_id << LL_ENDL; - return FALSE; - } - - if (!constraintp->mTargetConstraintDir.isExactlyZero()) - { - constraintp->mUseTargetOffset = TRUE; - // constraintp->mTargetConstraintDir *= constraintp->mSourceConstraintOffset.magVec(); - } - - if (!dp.unpackF32(constraintp->mEaseInStartTime, "ease_in_start") || !llfinite(constraintp->mEaseInStartTime)) - { - LL_WARNS() << "can't read constraint ease in start time" + return FALSE; + } + + if (!constraintp->mTargetConstraintDir.isExactlyZero()) + { + constraintp->mUseTargetOffset = TRUE; + // constraintp->mTargetConstraintDir *= constraintp->mSourceConstraintOffset.magVec(); + } + + if (!dp.unpackF32(constraintp->mEaseInStartTime, "ease_in_start") || !llfinite(constraintp->mEaseInStartTime)) + { + LL_WARNS() << "can't read constraint ease in start time" << " for animation " << asset_id << LL_ENDL; - return FALSE; - } + return FALSE; + } - if (!dp.unpackF32(constraintp->mEaseInStopTime, "ease_in_stop") || !llfinite(constraintp->mEaseInStopTime)) - { - LL_WARNS() << "can't read constraint ease in stop time" + if (!dp.unpackF32(constraintp->mEaseInStopTime, "ease_in_stop") || !llfinite(constraintp->mEaseInStopTime)) + { + LL_WARNS() << "can't read constraint ease in stop time" << " for animation " << asset_id << LL_ENDL; - return FALSE; - } + return FALSE; + } - if (!dp.unpackF32(constraintp->mEaseOutStartTime, "ease_out_start") || !llfinite(constraintp->mEaseOutStartTime)) - { - LL_WARNS() << "can't read constraint ease out start time" + if (!dp.unpackF32(constraintp->mEaseOutStartTime, "ease_out_start") || !llfinite(constraintp->mEaseOutStartTime)) + { + LL_WARNS() << "can't read constraint ease out start time" << " for animation " << asset_id << LL_ENDL; - return FALSE; - } + return FALSE; + } - if (!dp.unpackF32(constraintp->mEaseOutStopTime, "ease_out_stop") || !llfinite(constraintp->mEaseOutStopTime)) - { - LL_WARNS() << "can't read constraint ease out stop time" + if (!dp.unpackF32(constraintp->mEaseOutStopTime, "ease_out_stop") || !llfinite(constraintp->mEaseOutStopTime)) + { + LL_WARNS() << "can't read constraint ease out stop time" << " for animation " << asset_id << LL_ENDL; - return FALSE; - } - - LLJoint* joint = mCharacter->findCollisionVolume(constraintp->mSourceConstraintVolume); - // get joint to which this collision volume is attached - if (!joint) - { - return FALSE; - } - - constraintp->mJointStateIndices = new S32[constraintp->mChainLength + 1]; // note: mChainLength is size-limited - comes from a byte - - for (S32 i = 0; i < constraintp->mChainLength + 1; i++) - { - LLJoint* parent = joint->getParent(); - if (!parent) - { - LL_WARNS() << "Joint with no parent: " << joint->getName() + return FALSE; + } + + LLJoint* joint = mCharacter->findCollisionVolume(constraintp->mSourceConstraintVolume); + // get joint to which this collision volume is attached + if (!joint) + { + return FALSE; + } + + constraintp->mJointStateIndices = new S32[constraintp->mChainLength + 1]; // note: mChainLength is size-limited - comes from a byte + + for (S32 i = 0; i < constraintp->mChainLength + 1; i++) + { + LLJoint* parent = joint->getParent(); + if (!parent) + { + LL_WARNS() << "Joint with no parent: " << joint->getName() << " Emote: " << joint_motion_list->mEmoteName << " for animation " << asset_id << LL_ENDL; - return FALSE; - } - joint = parent; - constraintp->mJointStateIndices[i] = -1; - for (U32 j = 0; j < joint_motion_list->getNumJointMotions(); j++) - { - LLJoint* constraint_joint = getJoint(j); - - if ( !constraint_joint ) - { - LL_WARNS() << "Invalid joint " << j + return FALSE; + } + joint = parent; + constraintp->mJointStateIndices[i] = -1; + for (U32 j = 0; j < joint_motion_list->getNumJointMotions(); j++) + { + LLJoint* constraint_joint = getJoint(j); + + if ( !constraint_joint ) + { + LL_WARNS() << "Invalid joint " << j << " for animation " << asset_id << LL_ENDL; - return FALSE; - } - - if(constraint_joint == joint) - { - constraintp->mJointStateIndices[i] = (S32)j; - break; - } - } - if (constraintp->mJointStateIndices[i] < 0 ) - { - LL_WARNS() << "No joint index for constraint " << i + return FALSE; + } + + if(constraint_joint == joint) + { + constraintp->mJointStateIndices[i] = (S32)j; + break; + } + } + if (constraintp->mJointStateIndices[i] < 0 ) + { + LL_WARNS() << "No joint index for constraint " << i << " for animation " << asset_id << LL_ENDL; - return FALSE; - } - } + return FALSE; + } + } - joint_motion_list->mConstraints.push_front(constraintp.release()); - } - } + joint_motion_list->mConstraints.push_front(constraintp.release()); + } + } - // *FIX: support cleanup of old keyframe data + // *FIX: support cleanup of old keyframe data mJointMotionList = joint_motion_list.release(); // release from unique_ptr to member; - LLKeyframeDataCache::addKeyframeData(getID(), mJointMotionList); - mAssetStatus = ASSET_LOADED; + LLKeyframeDataCache::addKeyframeData(getID(), mJointMotionList); + mAssetStatus = ASSET_LOADED; - setupPose(); + setupPose(); - return TRUE; + return TRUE; } //----------------------------------------------------------------------------- @@ -2000,41 +2000,41 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo //----------------------------------------------------------------------------- BOOL LLKeyframeMotion::serialize(LLDataPacker& dp) const { - BOOL success = TRUE; - - LL_DEBUGS("BVH") << "serializing" << LL_ENDL; - - success &= dp.packU16(KEYFRAME_MOTION_VERSION, "version"); - success &= dp.packU16(KEYFRAME_MOTION_SUBVERSION, "sub_version"); - success &= dp.packS32(mJointMotionList->mBasePriority, "base_priority"); - success &= dp.packF32(mJointMotionList->mDuration, "duration"); - success &= dp.packString(mJointMotionList->mEmoteName, "emote_name"); - success &= dp.packF32(mJointMotionList->mLoopInPoint, "loop_in_point"); - success &= dp.packF32(mJointMotionList->mLoopOutPoint, "loop_out_point"); - success &= dp.packS32(mJointMotionList->mLoop, "loop"); - success &= dp.packF32(mJointMotionList->mEaseInDuration, "ease_in_duration"); - success &= dp.packF32(mJointMotionList->mEaseOutDuration, "ease_out_duration"); - success &= dp.packU32(mJointMotionList->mHandPose, "hand_pose"); - success &= dp.packU32(mJointMotionList->getNumJointMotions(), "num_joints"); + BOOL success = TRUE; + + LL_DEBUGS("BVH") << "serializing" << LL_ENDL; + + success &= dp.packU16(KEYFRAME_MOTION_VERSION, "version"); + success &= dp.packU16(KEYFRAME_MOTION_SUBVERSION, "sub_version"); + success &= dp.packS32(mJointMotionList->mBasePriority, "base_priority"); + success &= dp.packF32(mJointMotionList->mDuration, "duration"); + success &= dp.packString(mJointMotionList->mEmoteName, "emote_name"); + success &= dp.packF32(mJointMotionList->mLoopInPoint, "loop_in_point"); + success &= dp.packF32(mJointMotionList->mLoopOutPoint, "loop_out_point"); + success &= dp.packS32(mJointMotionList->mLoop, "loop"); + success &= dp.packF32(mJointMotionList->mEaseInDuration, "ease_in_duration"); + success &= dp.packF32(mJointMotionList->mEaseOutDuration, "ease_out_duration"); + success &= dp.packU32(mJointMotionList->mHandPose, "hand_pose"); + success &= dp.packU32(mJointMotionList->getNumJointMotions(), "num_joints"); LL_DEBUGS("BVH") << "version " << KEYFRAME_MOTION_VERSION << LL_ENDL; LL_DEBUGS("BVH") << "sub_version " << KEYFRAME_MOTION_SUBVERSION << LL_ENDL; LL_DEBUGS("BVH") << "base_priority " << mJointMotionList->mBasePriority << LL_ENDL; - LL_DEBUGS("BVH") << "duration " << mJointMotionList->mDuration << LL_ENDL; - LL_DEBUGS("BVH") << "emote_name " << mJointMotionList->mEmoteName << LL_ENDL; - LL_DEBUGS("BVH") << "loop_in_point " << mJointMotionList->mLoopInPoint << LL_ENDL; - LL_DEBUGS("BVH") << "loop_out_point " << mJointMotionList->mLoopOutPoint << LL_ENDL; - LL_DEBUGS("BVH") << "loop " << mJointMotionList->mLoop << LL_ENDL; - LL_DEBUGS("BVH") << "ease_in_duration " << mJointMotionList->mEaseInDuration << LL_ENDL; - LL_DEBUGS("BVH") << "ease_out_duration " << mJointMotionList->mEaseOutDuration << LL_ENDL; - LL_DEBUGS("BVH") << "hand_pose " << mJointMotionList->mHandPose << LL_ENDL; - LL_DEBUGS("BVH") << "num_joints " << mJointMotionList->getNumJointMotions() << LL_ENDL; - - for (U32 i = 0; i < mJointMotionList->getNumJointMotions(); i++) - { - JointMotion* joint_motionp = mJointMotionList->getJointMotion(i); - success &= dp.packString(joint_motionp->mJointName, "joint_name"); - success &= dp.packS32(joint_motionp->mPriority, "joint_priority"); + LL_DEBUGS("BVH") << "duration " << mJointMotionList->mDuration << LL_ENDL; + LL_DEBUGS("BVH") << "emote_name " << mJointMotionList->mEmoteName << LL_ENDL; + LL_DEBUGS("BVH") << "loop_in_point " << mJointMotionList->mLoopInPoint << LL_ENDL; + LL_DEBUGS("BVH") << "loop_out_point " << mJointMotionList->mLoopOutPoint << LL_ENDL; + LL_DEBUGS("BVH") << "loop " << mJointMotionList->mLoop << LL_ENDL; + LL_DEBUGS("BVH") << "ease_in_duration " << mJointMotionList->mEaseInDuration << LL_ENDL; + LL_DEBUGS("BVH") << "ease_out_duration " << mJointMotionList->mEaseOutDuration << LL_ENDL; + LL_DEBUGS("BVH") << "hand_pose " << mJointMotionList->mHandPose << LL_ENDL; + LL_DEBUGS("BVH") << "num_joints " << mJointMotionList->getNumJointMotions() << LL_ENDL; + + for (U32 i = 0; i < mJointMotionList->getNumJointMotions(); i++) + { + JointMotion* joint_motionp = mJointMotionList->getJointMotion(i); + success &= dp.packString(joint_motionp->mJointName, "joint_name"); + success &= dp.packS32(joint_motionp->mPriority, "joint_priority"); success &= dp.packS32(joint_motionp->mRotationCurve.mKeys.size(), "num_rot_keys"); LL_DEBUGS("BVH") << "Joint " << i @@ -2042,74 +2042,74 @@ BOOL LLKeyframeMotion::serialize(LLDataPacker& dp) const << " Rotation keys: " << joint_motionp->mRotationCurve.mKeys.size() << " Position keys: " << joint_motionp->mPositionCurve.mKeys.size() << LL_ENDL; for (RotationCurve::key_map_t::value_type& rot_pair : joint_motionp->mRotationCurve.mKeys) - { - RotationKey& rot_key = rot_pair.second; - U16 time_short = F32_to_U16(rot_key.mTime, 0.f, mJointMotionList->mDuration); - success &= dp.packU16(time_short, "time"); - - LLVector3 rot_angles = rot_key.mRotation.packToVector3(); - - U16 x, y, z; - rot_angles.quantize16(-1.f, 1.f, -1.f, 1.f); - x = F32_to_U16(rot_angles.mV[VX], -1.f, 1.f); - y = F32_to_U16(rot_angles.mV[VY], -1.f, 1.f); - z = F32_to_U16(rot_angles.mV[VZ], -1.f, 1.f); - success &= dp.packU16(x, "rot_angle_x"); - success &= dp.packU16(y, "rot_angle_y"); - success &= dp.packU16(z, "rot_angle_z"); - - LL_DEBUGS("BVH") << " rot: t " << rot_key.mTime << " angles " << rot_angles.mV[VX] <<","<< rot_angles.mV[VY] <<","<< rot_angles.mV[VZ] << LL_ENDL; - } - - success &= dp.packS32(joint_motionp->mPositionCurve.mKeys.size(), "num_pos_keys"); - for (PositionCurve::key_map_t::value_type& pos_pair : joint_motionp->mPositionCurve.mKeys) - { - PositionKey& pos_key = pos_pair.second; - U16 time_short = F32_to_U16(pos_key.mTime, 0.f, mJointMotionList->mDuration); - success &= dp.packU16(time_short, "time"); - - U16 x, y, z; - pos_key.mPosition.quantize16(-LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET, -LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET); - x = F32_to_U16(pos_key.mPosition.mV[VX], -LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET); - y = F32_to_U16(pos_key.mPosition.mV[VY], -LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET); - z = F32_to_U16(pos_key.mPosition.mV[VZ], -LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET); - success &= dp.packU16(x, "pos_x"); - success &= dp.packU16(y, "pos_y"); - success &= dp.packU16(z, "pos_z"); - - LL_DEBUGS("BVH") << " pos: t " << pos_key.mTime << " pos " << pos_key.mPosition.mV[VX] <<","<< pos_key.mPosition.mV[VY] <<","<< pos_key.mPosition.mV[VZ] << LL_ENDL; - } - } - - success &= dp.packS32(mJointMotionList->mConstraints.size(), "num_constraints"); + { + RotationKey& rot_key = rot_pair.second; + U16 time_short = F32_to_U16(rot_key.mTime, 0.f, mJointMotionList->mDuration); + success &= dp.packU16(time_short, "time"); + + LLVector3 rot_angles = rot_key.mRotation.packToVector3(); + + U16 x, y, z; + rot_angles.quantize16(-1.f, 1.f, -1.f, 1.f); + x = F32_to_U16(rot_angles.mV[VX], -1.f, 1.f); + y = F32_to_U16(rot_angles.mV[VY], -1.f, 1.f); + z = F32_to_U16(rot_angles.mV[VZ], -1.f, 1.f); + success &= dp.packU16(x, "rot_angle_x"); + success &= dp.packU16(y, "rot_angle_y"); + success &= dp.packU16(z, "rot_angle_z"); + + LL_DEBUGS("BVH") << " rot: t " << rot_key.mTime << " angles " << rot_angles.mV[VX] <<","<< rot_angles.mV[VY] <<","<< rot_angles.mV[VZ] << LL_ENDL; + } + + success &= dp.packS32(joint_motionp->mPositionCurve.mKeys.size(), "num_pos_keys"); + for (PositionCurve::key_map_t::value_type& pos_pair : joint_motionp->mPositionCurve.mKeys) + { + PositionKey& pos_key = pos_pair.second; + U16 time_short = F32_to_U16(pos_key.mTime, 0.f, mJointMotionList->mDuration); + success &= dp.packU16(time_short, "time"); + + U16 x, y, z; + pos_key.mPosition.quantize16(-LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET, -LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET); + x = F32_to_U16(pos_key.mPosition.mV[VX], -LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET); + y = F32_to_U16(pos_key.mPosition.mV[VY], -LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET); + z = F32_to_U16(pos_key.mPosition.mV[VZ], -LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET); + success &= dp.packU16(x, "pos_x"); + success &= dp.packU16(y, "pos_y"); + success &= dp.packU16(z, "pos_z"); + + LL_DEBUGS("BVH") << " pos: t " << pos_key.mTime << " pos " << pos_key.mPosition.mV[VX] <<","<< pos_key.mPosition.mV[VY] <<","<< pos_key.mPosition.mV[VZ] << LL_ENDL; + } + } + + success &= dp.packS32(mJointMotionList->mConstraints.size(), "num_constraints"); LL_DEBUGS("BVH") << "num_constraints " << mJointMotionList->mConstraints.size() << LL_ENDL; - for (JointConstraintSharedData* shared_constraintp : mJointMotionList->mConstraints) - { - success &= dp.packU8(shared_constraintp->mChainLength, "chain_length"); - success &= dp.packU8(shared_constraintp->mConstraintType, "constraint_type"); - char source_volume[16]; /* Flawfinder: ignore */ - snprintf(source_volume, sizeof(source_volume), "%s", /* Flawfinder: ignore */ - mCharacter->findCollisionVolume(shared_constraintp->mSourceConstraintVolume)->getName().c_str()); - - success &= dp.packBinaryDataFixed((U8*)source_volume, 16, "source_volume"); - success &= dp.packVector3(shared_constraintp->mSourceConstraintOffset, "source_offset"); - char target_volume[16]; /* Flawfinder: ignore */ - if (shared_constraintp->mConstraintTargetType == CONSTRAINT_TARGET_TYPE_GROUND) - { - snprintf(target_volume,sizeof(target_volume), "%s", "GROUND"); /* Flawfinder: ignore */ - } - else - { - snprintf(target_volume, sizeof(target_volume),"%s", /* Flawfinder: ignore */ - mCharacter->findCollisionVolume(shared_constraintp->mTargetConstraintVolume)->getName().c_str()); - } - success &= dp.packBinaryDataFixed((U8*)target_volume, 16, "target_volume"); - success &= dp.packVector3(shared_constraintp->mTargetConstraintOffset, "target_offset"); - success &= dp.packVector3(shared_constraintp->mTargetConstraintDir, "target_dir"); - success &= dp.packF32(shared_constraintp->mEaseInStartTime, "ease_in_start"); - success &= dp.packF32(shared_constraintp->mEaseInStopTime, "ease_in_stop"); - success &= dp.packF32(shared_constraintp->mEaseOutStartTime, "ease_out_start"); - success &= dp.packF32(shared_constraintp->mEaseOutStopTime, "ease_out_stop"); + for (JointConstraintSharedData* shared_constraintp : mJointMotionList->mConstraints) + { + success &= dp.packU8(shared_constraintp->mChainLength, "chain_length"); + success &= dp.packU8(shared_constraintp->mConstraintType, "constraint_type"); + char source_volume[16]; /* Flawfinder: ignore */ + snprintf(source_volume, sizeof(source_volume), "%s", /* Flawfinder: ignore */ + mCharacter->findCollisionVolume(shared_constraintp->mSourceConstraintVolume)->getName().c_str()); + + success &= dp.packBinaryDataFixed((U8*)source_volume, 16, "source_volume"); + success &= dp.packVector3(shared_constraintp->mSourceConstraintOffset, "source_offset"); + char target_volume[16]; /* Flawfinder: ignore */ + if (shared_constraintp->mConstraintTargetType == CONSTRAINT_TARGET_TYPE_GROUND) + { + snprintf(target_volume,sizeof(target_volume), "%s", "GROUND"); /* Flawfinder: ignore */ + } + else + { + snprintf(target_volume, sizeof(target_volume),"%s", /* Flawfinder: ignore */ + mCharacter->findCollisionVolume(shared_constraintp->mTargetConstraintVolume)->getName().c_str()); + } + success &= dp.packBinaryDataFixed((U8*)target_volume, 16, "target_volume"); + success &= dp.packVector3(shared_constraintp->mTargetConstraintOffset, "target_offset"); + success &= dp.packVector3(shared_constraintp->mTargetConstraintDir, "target_dir"); + success &= dp.packF32(shared_constraintp->mEaseInStartTime, "ease_in_start"); + success &= dp.packF32(shared_constraintp->mEaseInStopTime, "ease_in_stop"); + success &= dp.packF32(shared_constraintp->mEaseOutStartTime, "ease_out_start"); + success &= dp.packF32(shared_constraintp->mEaseOutStopTime, "ease_out_stop"); LL_DEBUGS("BVH") << " chain_length " << shared_constraintp->mChainLength << LL_ENDL; LL_DEBUGS("BVH") << " constraint_type " << (S32)shared_constraintp->mConstraintType << LL_ENDL; @@ -2122,21 +2122,21 @@ BOOL LLKeyframeMotion::serialize(LLDataPacker& dp) const LL_DEBUGS("BVH") << " ease_in_stop " << shared_constraintp->mEaseInStopTime << LL_ENDL; LL_DEBUGS("BVH") << " ease_out_start " << shared_constraintp->mEaseOutStartTime << LL_ENDL; LL_DEBUGS("BVH") << " ease_out_stop " << shared_constraintp->mEaseOutStopTime << LL_ENDL; - } + } - return success; + return success; } //----------------------------------------------------------------------------- // getFileSize() //----------------------------------------------------------------------------- -U32 LLKeyframeMotion::getFileSize() +U32 LLKeyframeMotion::getFileSize() { - // serialize into a dummy buffer to calculate required size - LLDataPackerBinaryBuffer dp; - serialize(dp); + // serialize into a dummy buffer to calculate required size + LLDataPackerBinaryBuffer dp; + serialize(dp); - return dp.getCurrentSize(); + return dp.getCurrentSize(); } //----------------------------------------------------------------------------- @@ -2144,7 +2144,7 @@ U32 LLKeyframeMotion::getFileSize() //----------------------------------------------------------------------------- bool LLKeyframeMotion::dumpToFile(const std::string& name) { - bool succ = false; + bool succ = false; if (isLoaded()) { std::string outfile_base; @@ -2162,22 +2162,22 @@ bool LLKeyframeMotion::dumpToFile(const std::string& name) outfile_base = id.asString(); } - if (gDirUtilp->getExtension(outfile_base).empty()) - { - outfile_base += ".anim"; - } - std::string outfilename; - if (gDirUtilp->getDirName(outfile_base).empty()) - { - outfilename = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,outfile_base); - } - else - { - outfilename = outfile_base; - } + if (gDirUtilp->getExtension(outfile_base).empty()) + { + outfile_base += ".anim"; + } + std::string outfilename; + if (gDirUtilp->getDirName(outfile_base).empty()) + { + outfilename = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,outfile_base); + } + else + { + outfilename = outfile_base; + } if (LLFile::isfile(outfilename)) { - LL_WARNS() << outfilename << " already exists, write failed" << LL_ENDL; + LL_WARNS() << outfilename << " already exists, write failed" << LL_ENDL; return false; } @@ -2193,12 +2193,12 @@ bool LLKeyframeMotion::dumpToFile(const std::string& name) if (outfile.getFileHandle()) { S32 wrote_bytes = outfile.write(buffer, file_size); - succ = (wrote_bytes == file_size); + succ = (wrote_bytes == file_size); } } delete [] buffer; } - return succ; + return succ; } //----------------------------------------------------------------------------- @@ -2206,7 +2206,7 @@ bool LLKeyframeMotion::dumpToFile(const std::string& name) //----------------------------------------------------------------------------- const LLBBoxLocal &LLKeyframeMotion::getPelvisBBox() { - return mJointMotionList->mPelvisBBox; + return mJointMotionList->mPelvisBBox; } //----------------------------------------------------------------------------- @@ -2214,22 +2214,22 @@ const LLBBoxLocal &LLKeyframeMotion::getPelvisBBox() //----------------------------------------------------------------------------- void LLKeyframeMotion::setPriority(S32 priority) { - if (mJointMotionList) - { - S32 priority_delta = priority - mJointMotionList->mBasePriority; - mJointMotionList->mBasePriority = (LLJoint::JointPriority)priority; - mJointMotionList->mMaxPriority = mJointMotionList->mBasePriority; - - for (U32 i = 0; i < mJointMotionList->getNumJointMotions(); i++) - { - JointMotion* joint_motion = mJointMotionList->getJointMotion(i); - joint_motion->mPriority = (LLJoint::JointPriority)llclamp( - (S32)joint_motion->mPriority + priority_delta, - (S32)LLJoint::LOW_PRIORITY, - (S32)LLJoint::HIGHEST_PRIORITY); - getJointState(i)->setPriority(joint_motion->mPriority); - } - } + if (mJointMotionList) + { + S32 priority_delta = priority - mJointMotionList->mBasePriority; + mJointMotionList->mBasePriority = (LLJoint::JointPriority)priority; + mJointMotionList->mMaxPriority = mJointMotionList->mBasePriority; + + for (U32 i = 0; i < mJointMotionList->getNumJointMotions(); i++) + { + JointMotion* joint_motion = mJointMotionList->getJointMotion(i); + joint_motion->mPriority = (LLJoint::JointPriority)llclamp( + (S32)joint_motion->mPriority + priority_delta, + (S32)LLJoint::LOW_PRIORITY, + (S32)LLJoint::HIGHEST_PRIORITY); + getJointState(i)->setPriority(joint_motion->mPriority); + } + } } //----------------------------------------------------------------------------- @@ -2237,15 +2237,15 @@ void LLKeyframeMotion::setPriority(S32 priority) //----------------------------------------------------------------------------- void LLKeyframeMotion::setEmote(const LLUUID& emote_id) { - const char* emote_name = gAnimLibrary.animStateToString(emote_id); - if (emote_name) - { - mJointMotionList->mEmoteName = emote_name; - } - else - { - mJointMotionList->mEmoteName = ""; - } + const char* emote_name = gAnimLibrary.animStateToString(emote_id); + if (emote_name) + { + mJointMotionList->mEmoteName = emote_name; + } + else + { + mJointMotionList->mEmoteName = ""; + } } //----------------------------------------------------------------------------- @@ -2253,10 +2253,10 @@ void LLKeyframeMotion::setEmote(const LLUUID& emote_id) //----------------------------------------------------------------------------- void LLKeyframeMotion::setEaseIn(F32 ease_in) { - if (mJointMotionList) - { - mJointMotionList->mEaseInDuration = llmax(ease_in, 0.f); - } + if (mJointMotionList) + { + mJointMotionList->mEaseInDuration = llmax(ease_in, 0.f); + } } //----------------------------------------------------------------------------- @@ -2264,10 +2264,10 @@ void LLKeyframeMotion::setEaseIn(F32 ease_in) //----------------------------------------------------------------------------- void LLKeyframeMotion::setEaseOut(F32 ease_in) { - if (mJointMotionList) - { - mJointMotionList->mEaseOutDuration = llmax(ease_in, 0.f); - } + if (mJointMotionList) + { + mJointMotionList->mEaseOutDuration = llmax(ease_in, 0.f); + } } @@ -2276,8 +2276,8 @@ void LLKeyframeMotion::setEaseOut(F32 ease_in) //----------------------------------------------------------------------------- void LLKeyframeMotion::flushKeyframeCache() { - // TODO: Make this safe to do -// LLKeyframeDataCache::clear(); + // TODO: Make this safe to do +// LLKeyframeDataCache::clear(); } //----------------------------------------------------------------------------- @@ -2285,11 +2285,11 @@ void LLKeyframeMotion::flushKeyframeCache() //----------------------------------------------------------------------------- void LLKeyframeMotion::setLoop(BOOL loop) { - if (mJointMotionList) - { - mJointMotionList->mLoop = loop; - mSendStopTimestamp = F32_MAX; - } + if (mJointMotionList) + { + mJointMotionList->mLoop = loop; + mSendStopTimestamp = F32_MAX; + } } @@ -2298,28 +2298,28 @@ void LLKeyframeMotion::setLoop(BOOL loop) //----------------------------------------------------------------------------- void LLKeyframeMotion::setLoopIn(F32 in_point) { - if (mJointMotionList) - { - mJointMotionList->mLoopInPoint = in_point; - - // set up loop keys - for (U32 i = 0; i < mJointMotionList->getNumJointMotions(); i++) - { - JointMotion* joint_motion = mJointMotionList->getJointMotion(i); - - PositionCurve* pos_curve = &joint_motion->mPositionCurve; - RotationCurve* rot_curve = &joint_motion->mRotationCurve; - ScaleCurve* scale_curve = &joint_motion->mScaleCurve; - - pos_curve->mLoopInKey.mTime = mJointMotionList->mLoopInPoint; - rot_curve->mLoopInKey.mTime = mJointMotionList->mLoopInPoint; - scale_curve->mLoopInKey.mTime = mJointMotionList->mLoopInPoint; - - pos_curve->mLoopInKey.mPosition = pos_curve->getValue(mJointMotionList->mLoopInPoint, mJointMotionList->mDuration); - rot_curve->mLoopInKey.mRotation = rot_curve->getValue(mJointMotionList->mLoopInPoint, mJointMotionList->mDuration); - scale_curve->mLoopInKey.mScale = scale_curve->getValue(mJointMotionList->mLoopInPoint, mJointMotionList->mDuration); - } - } + if (mJointMotionList) + { + mJointMotionList->mLoopInPoint = in_point; + + // set up loop keys + for (U32 i = 0; i < mJointMotionList->getNumJointMotions(); i++) + { + JointMotion* joint_motion = mJointMotionList->getJointMotion(i); + + PositionCurve* pos_curve = &joint_motion->mPositionCurve; + RotationCurve* rot_curve = &joint_motion->mRotationCurve; + ScaleCurve* scale_curve = &joint_motion->mScaleCurve; + + pos_curve->mLoopInKey.mTime = mJointMotionList->mLoopInPoint; + rot_curve->mLoopInKey.mTime = mJointMotionList->mLoopInPoint; + scale_curve->mLoopInKey.mTime = mJointMotionList->mLoopInPoint; + + pos_curve->mLoopInKey.mPosition = pos_curve->getValue(mJointMotionList->mLoopInPoint, mJointMotionList->mDuration); + rot_curve->mLoopInKey.mRotation = rot_curve->getValue(mJointMotionList->mLoopInPoint, mJointMotionList->mDuration); + scale_curve->mLoopInKey.mScale = scale_curve->getValue(mJointMotionList->mLoopInPoint, mJointMotionList->mDuration); + } + } } //----------------------------------------------------------------------------- @@ -2327,98 +2327,98 @@ void LLKeyframeMotion::setLoopIn(F32 in_point) //----------------------------------------------------------------------------- void LLKeyframeMotion::setLoopOut(F32 out_point) { - if (mJointMotionList) - { - mJointMotionList->mLoopOutPoint = out_point; - - // set up loop keys - for (U32 i = 0; i < mJointMotionList->getNumJointMotions(); i++) - { - JointMotion* joint_motion = mJointMotionList->getJointMotion(i); - - PositionCurve* pos_curve = &joint_motion->mPositionCurve; - RotationCurve* rot_curve = &joint_motion->mRotationCurve; - ScaleCurve* scale_curve = &joint_motion->mScaleCurve; - - pos_curve->mLoopOutKey.mTime = mJointMotionList->mLoopOutPoint; - rot_curve->mLoopOutKey.mTime = mJointMotionList->mLoopOutPoint; - scale_curve->mLoopOutKey.mTime = mJointMotionList->mLoopOutPoint; - - pos_curve->mLoopOutKey.mPosition = pos_curve->getValue(mJointMotionList->mLoopOutPoint, mJointMotionList->mDuration); - rot_curve->mLoopOutKey.mRotation = rot_curve->getValue(mJointMotionList->mLoopOutPoint, mJointMotionList->mDuration); - scale_curve->mLoopOutKey.mScale = scale_curve->getValue(mJointMotionList->mLoopOutPoint, mJointMotionList->mDuration); - } - } + if (mJointMotionList) + { + mJointMotionList->mLoopOutPoint = out_point; + + // set up loop keys + for (U32 i = 0; i < mJointMotionList->getNumJointMotions(); i++) + { + JointMotion* joint_motion = mJointMotionList->getJointMotion(i); + + PositionCurve* pos_curve = &joint_motion->mPositionCurve; + RotationCurve* rot_curve = &joint_motion->mRotationCurve; + ScaleCurve* scale_curve = &joint_motion->mScaleCurve; + + pos_curve->mLoopOutKey.mTime = mJointMotionList->mLoopOutPoint; + rot_curve->mLoopOutKey.mTime = mJointMotionList->mLoopOutPoint; + scale_curve->mLoopOutKey.mTime = mJointMotionList->mLoopOutPoint; + + pos_curve->mLoopOutKey.mPosition = pos_curve->getValue(mJointMotionList->mLoopOutPoint, mJointMotionList->mDuration); + rot_curve->mLoopOutKey.mRotation = rot_curve->getValue(mJointMotionList->mLoopOutPoint, mJointMotionList->mDuration); + scale_curve->mLoopOutKey.mScale = scale_curve->getValue(mJointMotionList->mLoopOutPoint, mJointMotionList->mDuration); + } + } } //----------------------------------------------------------------------------- // onLoadComplete() //----------------------------------------------------------------------------- void LLKeyframeMotion::onLoadComplete(const LLUUID& asset_uuid, - LLAssetType::EType type, - void* user_data, S32 status, LLExtStat ext_status) + LLAssetType::EType type, + void* user_data, S32 status, LLExtStat ext_status) { - LLUUID* id = (LLUUID*)user_data; - - std::vector<LLCharacter* >::iterator char_iter = LLCharacter::sInstances.begin(); - - while(char_iter != LLCharacter::sInstances.end() && - (*char_iter)->getID() != *id) - { - ++char_iter; - } - - delete id; - - if (char_iter == LLCharacter::sInstances.end()) - { - return; - } - - LLCharacter* character = *char_iter; - - // look for an existing instance of this motion - LLKeyframeMotion* motionp = static_cast<LLKeyframeMotion*> (character->findMotion(asset_uuid)); - if (motionp) - { - if (0 == status) - { - if (motionp->mAssetStatus == ASSET_LOADED) - { - // asset already loaded - return; - } - LLFileSystem file(asset_uuid, type, LLFileSystem::READ); - S32 size = file.getSize(); - - U8* buffer = new U8[size]; - file.read((U8*)buffer, size); /*Flawfinder: ignore*/ - - LL_DEBUGS("Animation") << "Loading keyframe data for: " << motionp->getName() << ":" << motionp->getID() << " (" << size << " bytes)" << LL_ENDL; - - LLDataPackerBinaryBuffer dp(buffer, size); - if (motionp->deserialize(dp, asset_uuid)) - { - motionp->mAssetStatus = ASSET_LOADED; - } - else - { - LL_WARNS() << "Failed to decode asset for animation " << motionp->getName() << ":" << motionp->getID() << LL_ENDL; - motionp->mAssetStatus = ASSET_FETCH_FAILED; - } - - delete[] buffer; - } - else - { - LL_WARNS() << "Failed to load asset for animation " << motionp->getName() << ":" << motionp->getID() << LL_ENDL; - motionp->mAssetStatus = ASSET_FETCH_FAILED; - } - } - else - { - LL_WARNS() << "No existing motion for asset data. UUID: " << asset_uuid << LL_ENDL; - } + LLUUID* id = (LLUUID*)user_data; + + std::vector<LLCharacter* >::iterator char_iter = LLCharacter::sInstances.begin(); + + while(char_iter != LLCharacter::sInstances.end() && + (*char_iter)->getID() != *id) + { + ++char_iter; + } + + delete id; + + if (char_iter == LLCharacter::sInstances.end()) + { + return; + } + + LLCharacter* character = *char_iter; + + // look for an existing instance of this motion + LLKeyframeMotion* motionp = static_cast<LLKeyframeMotion*> (character->findMotion(asset_uuid)); + if (motionp) + { + if (0 == status) + { + if (motionp->mAssetStatus == ASSET_LOADED) + { + // asset already loaded + return; + } + LLFileSystem file(asset_uuid, type, LLFileSystem::READ); + S32 size = file.getSize(); + + U8* buffer = new U8[size]; + file.read((U8*)buffer, size); /*Flawfinder: ignore*/ + + LL_DEBUGS("Animation") << "Loading keyframe data for: " << motionp->getName() << ":" << motionp->getID() << " (" << size << " bytes)" << LL_ENDL; + + LLDataPackerBinaryBuffer dp(buffer, size); + if (motionp->deserialize(dp, asset_uuid)) + { + motionp->mAssetStatus = ASSET_LOADED; + } + else + { + LL_WARNS() << "Failed to decode asset for animation " << motionp->getName() << ":" << motionp->getID() << LL_ENDL; + motionp->mAssetStatus = ASSET_FETCH_FAILED; + } + + delete[] buffer; + } + else + { + LL_WARNS() << "Failed to load asset for animation " << motionp->getName() << ":" << motionp->getID() << LL_ENDL; + motionp->mAssetStatus = ASSET_FETCH_FAILED; + } + } + else + { + LL_WARNS() << "No existing motion for asset data. UUID: " << asset_uuid << LL_ENDL; + } } //-------------------------------------------------------------------- @@ -2426,34 +2426,34 @@ void LLKeyframeMotion::onLoadComplete(const LLUUID& asset_uuid, //-------------------------------------------------------------------- void LLKeyframeDataCache::dumpDiagInfo() { - // keep track of totals - U32 total_size = 0; + // keep track of totals + U32 total_size = 0; - char buf[1024]; /* Flawfinder: ignore */ + char buf[1024]; /* Flawfinder: ignore */ - LL_INFOS() << "-----------------------------------------------------" << LL_ENDL; - LL_INFOS() << " Global Motion Table (DEBUG only)" << LL_ENDL; - LL_INFOS() << "-----------------------------------------------------" << LL_ENDL; + LL_INFOS() << "-----------------------------------------------------" << LL_ENDL; + LL_INFOS() << " Global Motion Table (DEBUG only)" << LL_ENDL; + LL_INFOS() << "-----------------------------------------------------" << LL_ENDL; - // print each loaded mesh, and it's memory usage - for (keyframe_data_map_t::value_type& data_pair : sKeyframeDataMap) - { - U32 joint_motion_kb; + // print each loaded mesh, and it's memory usage + for (keyframe_data_map_t::value_type& data_pair : sKeyframeDataMap) + { + U32 joint_motion_kb; - LLKeyframeMotion::JointMotionList *motion_list_p = data_pair.second; + LLKeyframeMotion::JointMotionList *motion_list_p = data_pair.second; - LL_INFOS() << "Motion: " << data_pair.first << LL_ENDL; + LL_INFOS() << "Motion: " << data_pair.first << LL_ENDL; - joint_motion_kb = motion_list_p->dumpDiagInfo(); + joint_motion_kb = motion_list_p->dumpDiagInfo(); - total_size += joint_motion_kb; - } + total_size += joint_motion_kb; + } - LL_INFOS() << "-----------------------------------------------------" << LL_ENDL; - LL_INFOS() << "Motions\tTotal Size" << LL_ENDL; - snprintf(buf, sizeof(buf), "%d\t\t%d bytes", (S32)sKeyframeDataMap.size(), total_size ); /* Flawfinder: ignore */ - LL_INFOS() << buf << LL_ENDL; - LL_INFOS() << "-----------------------------------------------------" << LL_ENDL; + LL_INFOS() << "-----------------------------------------------------" << LL_ENDL; + LL_INFOS() << "Motions\tTotal Size" << LL_ENDL; + snprintf(buf, sizeof(buf), "%d\t\t%d bytes", (S32)sKeyframeDataMap.size(), total_size ); /* Flawfinder: ignore */ + LL_INFOS() << buf << LL_ENDL; + LL_INFOS() << "-----------------------------------------------------" << LL_ENDL; } @@ -2462,7 +2462,7 @@ void LLKeyframeDataCache::dumpDiagInfo() //-------------------------------------------------------------------- void LLKeyframeDataCache::addKeyframeData(const LLUUID& id, LLKeyframeMotion::JointMotionList* joint_motion_listp) { - sKeyframeDataMap[id] = joint_motion_listp; + sKeyframeDataMap[id] = joint_motion_listp; } //-------------------------------------------------------------------- @@ -2470,12 +2470,12 @@ void LLKeyframeDataCache::addKeyframeData(const LLUUID& id, LLKeyframeMotion::Jo //-------------------------------------------------------------------- void LLKeyframeDataCache::removeKeyframeData(const LLUUID& id) { - keyframe_data_map_t::iterator found_data = sKeyframeDataMap.find(id); - if (found_data != sKeyframeDataMap.end()) - { - delete found_data->second; - sKeyframeDataMap.erase(found_data); - } + keyframe_data_map_t::iterator found_data = sKeyframeDataMap.find(id); + if (found_data != sKeyframeDataMap.end()) + { + delete found_data->second; + sKeyframeDataMap.erase(found_data); + } } //-------------------------------------------------------------------- @@ -2483,12 +2483,12 @@ void LLKeyframeDataCache::removeKeyframeData(const LLUUID& id) //-------------------------------------------------------------------- LLKeyframeMotion::JointMotionList* LLKeyframeDataCache::getKeyframeData(const LLUUID& id) { - keyframe_data_map_t::iterator found_data = sKeyframeDataMap.find(id); - if (found_data == sKeyframeDataMap.end()) - { - return NULL; - } - return found_data->second; + keyframe_data_map_t::iterator found_data = sKeyframeDataMap.find(id); + if (found_data == sKeyframeDataMap.end()) + { + return NULL; + } + return found_data->second; } //-------------------------------------------------------------------- @@ -2496,7 +2496,7 @@ LLKeyframeMotion::JointMotionList* LLKeyframeDataCache::getKeyframeData(const LL //-------------------------------------------------------------------- LLKeyframeDataCache::~LLKeyframeDataCache() { - clear(); + clear(); } //----------------------------------------------------------------------------- @@ -2504,27 +2504,27 @@ LLKeyframeDataCache::~LLKeyframeDataCache() //----------------------------------------------------------------------------- void LLKeyframeDataCache::clear() { - for_each(sKeyframeDataMap.begin(), sKeyframeDataMap.end(), DeletePairedPointer()); - sKeyframeDataMap.clear(); + for_each(sKeyframeDataMap.begin(), sKeyframeDataMap.end(), DeletePairedPointer()); + sKeyframeDataMap.clear(); } //----------------------------------------------------------------------------- // JointConstraint() //----------------------------------------------------------------------------- -LLKeyframeMotion::JointConstraint::JointConstraint(JointConstraintSharedData* shared_data) : mSharedData(shared_data) +LLKeyframeMotion::JointConstraint::JointConstraint(JointConstraintSharedData* shared_data) : mSharedData(shared_data) { - mWeight = 0.f; - mTotalLength = 0.f; - mActive = FALSE; - mSourceVolume = NULL; - mTargetVolume = NULL; - mFixupDistanceRMS = 0.f; - - for (S32 i=0; i<MAX_CHAIN_LENGTH; ++i) - { - mJointLengths[i] = 0.f; - mJointLengthFractions[i] = 0.f; - } + mWeight = 0.f; + mTotalLength = 0.f; + mActive = FALSE; + mSourceVolume = NULL; + mTargetVolume = NULL; + mFixupDistanceRMS = 0.f; + + for (S32 i=0; i<MAX_CHAIN_LENGTH; ++i) + { + mJointLengths[i] = 0.f; + mJointLengthFractions[i] = 0.f; + } } //----------------------------------------------------------------------------- diff --git a/indra/llcharacter/llkeyframemotion.h b/indra/llcharacter/llkeyframemotion.h index 96746f57c9..b1c4f5afb7 100644 --- a/indra/llcharacter/llkeyframemotion.h +++ b/indra/llcharacter/llkeyframemotion.h @@ -1,25 +1,25 @@ -/** +/** * @file llkeyframemotion.h * @brief Implementation of LLKeframeMotion class. * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -56,64 +56,64 @@ const S32 KEYFRAME_MOTION_SUBVERSION = 0; // class LLKeyframeMotion //----------------------------------------------------------------------------- class LLKeyframeMotion : - public LLMotion + public LLMotion { - friend class LLKeyframeDataCache; + friend class LLKeyframeDataCache; public: - // Constructor - LLKeyframeMotion(const LLUUID &id); + // Constructor + LLKeyframeMotion(const LLUUID &id); - // Destructor - virtual ~LLKeyframeMotion(); + // Destructor + virtual ~LLKeyframeMotion(); private: - // private helper functions to wrap some asserts - LLPointer<LLJointState>& getJointState(U32 index); - LLJoint* getJoint(U32 index ); - + // private helper functions to wrap some asserts + LLPointer<LLJointState>& getJointState(U32 index); + LLJoint* getJoint(U32 index ); + public: - //------------------------------------------------------------------------- - // functions to support MotionController and MotionRegistry - //------------------------------------------------------------------------- + //------------------------------------------------------------------------- + // functions to support MotionController and MotionRegistry + //------------------------------------------------------------------------- - // static constructor - // all subclasses must implement such a function and register it - static LLMotion *create(const LLUUID& id); + // static constructor + // all subclasses must implement such a function and register it + static LLMotion *create(const LLUUID& id); public: - //------------------------------------------------------------------------- - // animation callbacks to be implemented by subclasses - //------------------------------------------------------------------------- - - // motions must specify whether or not they loop - virtual BOOL getLoop() { - if (mJointMotionList) return mJointMotionList->mLoop; - else return FALSE; - } - - // motions must report their total duration - virtual F32 getDuration() { - if (mJointMotionList) return mJointMotionList->mDuration; - else return 0.f; - } - - // motions must report their "ease in" duration - virtual F32 getEaseInDuration() { - if (mJointMotionList) return mJointMotionList->mEaseInDuration; - else return 0.f; - } - - // motions must report their "ease out" duration. - virtual F32 getEaseOutDuration() { - if (mJointMotionList) return mJointMotionList->mEaseOutDuration; - else return 0.f; - } - - // motions must report their priority - virtual LLJoint::JointPriority getPriority() { - if (mJointMotionList) return mJointMotionList->mBasePriority; - else return LLJoint::LOW_PRIORITY; - } + //------------------------------------------------------------------------- + // animation callbacks to be implemented by subclasses + //------------------------------------------------------------------------- + + // motions must specify whether or not they loop + virtual BOOL getLoop() { + if (mJointMotionList) return mJointMotionList->mLoop; + else return FALSE; + } + + // motions must report their total duration + virtual F32 getDuration() { + if (mJointMotionList) return mJointMotionList->mDuration; + else return 0.f; + } + + // motions must report their "ease in" duration + virtual F32 getEaseInDuration() { + if (mJointMotionList) return mJointMotionList->mEaseInDuration; + else return 0.f; + } + + // motions must report their "ease out" duration. + virtual F32 getEaseOutDuration() { + if (mJointMotionList) return mJointMotionList->mEaseOutDuration; + else return 0.f; + } + + // motions must report their priority + virtual LLJoint::JointPriority getPriority() { + if (mJointMotionList) return mJointMotionList->mBasePriority; + else return LLJoint::LOW_PRIORITY; + } virtual S32 getNumJointMotions() { @@ -124,337 +124,337 @@ public: return 0; } - virtual LLMotionBlendType getBlendType() { return NORMAL_BLEND; } + virtual LLMotionBlendType getBlendType() { return NORMAL_BLEND; } - // called to determine when a motion should be activated/deactivated based on avatar pixel coverage - virtual F32 getMinPixelArea() { return MIN_REQUIRED_PIXEL_AREA_KEYFRAME; } + // called to determine when a motion should be activated/deactivated based on avatar pixel coverage + virtual F32 getMinPixelArea() { return MIN_REQUIRED_PIXEL_AREA_KEYFRAME; } - // run-time (post constructor) initialization, - // called after parameters have been set - // must return true to indicate success and be available for activation - virtual LLMotionInitStatus onInitialize(LLCharacter *character); + // run-time (post constructor) initialization, + // called after parameters have been set + // must return true to indicate success and be available for activation + virtual LLMotionInitStatus onInitialize(LLCharacter *character); - // called when a motion is activated - // must return TRUE to indicate success, or else - // it will be deactivated - virtual BOOL onActivate(); + // called when a motion is activated + // must return TRUE to indicate success, or else + // it will be deactivated + virtual BOOL onActivate(); - // called per time step - // must return TRUE while it is active, and - // must return FALSE when the motion is completed. - virtual BOOL onUpdate(F32 time, U8* joint_mask); + // called per time step + // must return TRUE while it is active, and + // must return FALSE when the motion is completed. + virtual BOOL onUpdate(F32 time, U8* joint_mask); - // called when a motion is deactivated - virtual void onDeactivate(); + // called when a motion is deactivated + virtual void onDeactivate(); - virtual void setStopTime(F32 time); + virtual void setStopTime(F32 time); - static void onLoadComplete(const LLUUID& asset_uuid, - LLAssetType::EType type, - void* user_data, S32 status, LLExtStat ext_status); + static void onLoadComplete(const LLUUID& asset_uuid, + LLAssetType::EType type, + void* user_data, S32 status, LLExtStat ext_status); public: - U32 getFileSize(); - BOOL serialize(LLDataPacker& dp) const; - BOOL deserialize(LLDataPacker& dp, const LLUUID& asset_id, bool allow_invalid_joints = true); - BOOL isLoaded() { return mJointMotionList != NULL; } - bool dumpToFile(const std::string& name); + U32 getFileSize(); + BOOL serialize(LLDataPacker& dp) const; + BOOL deserialize(LLDataPacker& dp, const LLUUID& asset_id, bool allow_invalid_joints = true); + BOOL isLoaded() { return mJointMotionList != NULL; } + bool dumpToFile(const std::string& name); + + // setters for modifying a keyframe animation + void setLoop(BOOL loop); - // setters for modifying a keyframe animation - void setLoop(BOOL loop); + F32 getLoopIn() { + return (mJointMotionList) ? mJointMotionList->mLoopInPoint : 0.f; + } - F32 getLoopIn() { - return (mJointMotionList) ? mJointMotionList->mLoopInPoint : 0.f; - } + F32 getLoopOut() { + return (mJointMotionList) ? mJointMotionList->mLoopOutPoint : 0.f; + } - F32 getLoopOut() { - return (mJointMotionList) ? mJointMotionList->mLoopOutPoint : 0.f; - } - - void setLoopIn(F32 in_point); + void setLoopIn(F32 in_point); - void setLoopOut(F32 out_point); + void setLoopOut(F32 out_point); - void setHandPose(LLHandMotion::eHandPose pose) { - if (mJointMotionList) mJointMotionList->mHandPose = pose; - } + void setHandPose(LLHandMotion::eHandPose pose) { + if (mJointMotionList) mJointMotionList->mHandPose = pose; + } - LLHandMotion::eHandPose getHandPose() { - return (mJointMotionList) ? mJointMotionList->mHandPose : LLHandMotion::HAND_POSE_RELAXED; - } + LLHandMotion::eHandPose getHandPose() { + return (mJointMotionList) ? mJointMotionList->mHandPose : LLHandMotion::HAND_POSE_RELAXED; + } - void setPriority(S32 priority); + void setPriority(S32 priority); - void setEmote(const LLUUID& emote_id); + void setEmote(const LLUUID& emote_id); - void setEaseIn(F32 ease_in); + void setEaseIn(F32 ease_in); - void setEaseOut(F32 ease_in); + void setEaseOut(F32 ease_in); - F32 getLastUpdateTime() { return mLastLoopedTime; } + F32 getLastUpdateTime() { return mLastLoopedTime; } - const LLBBoxLocal& getPelvisBBox(); + const LLBBoxLocal& getPelvisBBox(); - static void flushKeyframeCache(); + static void flushKeyframeCache(); protected: - //------------------------------------------------------------------------- - // JointConstraintSharedData - //------------------------------------------------------------------------- - class JointConstraintSharedData - { - public: - JointConstraintSharedData() : - mChainLength(0), - mEaseInStartTime(0.f), - mEaseInStopTime(0.f), - mEaseOutStartTime(0.f), - mEaseOutStopTime(0.f), - mUseTargetOffset(FALSE), - mConstraintType(CONSTRAINT_TYPE_POINT), - mConstraintTargetType(CONSTRAINT_TARGET_TYPE_BODY), - mSourceConstraintVolume(0), - mTargetConstraintVolume(0), - mJointStateIndices(NULL) - { }; - ~JointConstraintSharedData() { delete [] mJointStateIndices; } - - S32 mSourceConstraintVolume; - LLVector3 mSourceConstraintOffset; - S32 mTargetConstraintVolume; - LLVector3 mTargetConstraintOffset; - LLVector3 mTargetConstraintDir; - S32 mChainLength; - S32* mJointStateIndices; - F32 mEaseInStartTime; - F32 mEaseInStopTime; - F32 mEaseOutStartTime; - F32 mEaseOutStopTime; - BOOL mUseTargetOffset; - EConstraintType mConstraintType; - EConstraintTargetType mConstraintTargetType; - }; - - //----------------------------------------------------------------------------- - // JointConstraint() - //----------------------------------------------------------------------------- - class JointConstraint - { - public: - JointConstraint(JointConstraintSharedData* shared_data); - ~JointConstraint(); - - JointConstraintSharedData* mSharedData; - F32 mWeight; - F32 mTotalLength; - LLVector3 mPositions[MAX_CHAIN_LENGTH]; - F32 mJointLengths[MAX_CHAIN_LENGTH]; - F32 mJointLengthFractions[MAX_CHAIN_LENGTH]; - BOOL mActive; - LLVector3d mGroundPos; - LLVector3 mGroundNorm; - LLJoint* mSourceVolume; - LLJoint* mTargetVolume; - F32 mFixupDistanceRMS; - }; - - void applyKeyframes(F32 time); - - void applyConstraints(F32 time, U8* joint_mask); - - void activateConstraint(JointConstraint* constraintp); - - void initializeConstraint(JointConstraint* constraint); - - void deactivateConstraint(JointConstraint *constraintp); - - void applyConstraint(JointConstraint* constraintp, F32 time, U8* joint_mask); - - BOOL setupPose(); + //------------------------------------------------------------------------- + // JointConstraintSharedData + //------------------------------------------------------------------------- + class JointConstraintSharedData + { + public: + JointConstraintSharedData() : + mChainLength(0), + mEaseInStartTime(0.f), + mEaseInStopTime(0.f), + mEaseOutStartTime(0.f), + mEaseOutStopTime(0.f), + mUseTargetOffset(FALSE), + mConstraintType(CONSTRAINT_TYPE_POINT), + mConstraintTargetType(CONSTRAINT_TARGET_TYPE_BODY), + mSourceConstraintVolume(0), + mTargetConstraintVolume(0), + mJointStateIndices(NULL) + { }; + ~JointConstraintSharedData() { delete [] mJointStateIndices; } + + S32 mSourceConstraintVolume; + LLVector3 mSourceConstraintOffset; + S32 mTargetConstraintVolume; + LLVector3 mTargetConstraintOffset; + LLVector3 mTargetConstraintDir; + S32 mChainLength; + S32* mJointStateIndices; + F32 mEaseInStartTime; + F32 mEaseInStopTime; + F32 mEaseOutStartTime; + F32 mEaseOutStopTime; + BOOL mUseTargetOffset; + EConstraintType mConstraintType; + EConstraintTargetType mConstraintTargetType; + }; + + //----------------------------------------------------------------------------- + // JointConstraint() + //----------------------------------------------------------------------------- + class JointConstraint + { + public: + JointConstraint(JointConstraintSharedData* shared_data); + ~JointConstraint(); + + JointConstraintSharedData* mSharedData; + F32 mWeight; + F32 mTotalLength; + LLVector3 mPositions[MAX_CHAIN_LENGTH]; + F32 mJointLengths[MAX_CHAIN_LENGTH]; + F32 mJointLengthFractions[MAX_CHAIN_LENGTH]; + BOOL mActive; + LLVector3d mGroundPos; + LLVector3 mGroundNorm; + LLJoint* mSourceVolume; + LLJoint* mTargetVolume; + F32 mFixupDistanceRMS; + }; + + void applyKeyframes(F32 time); + + void applyConstraints(F32 time, U8* joint_mask); + + void activateConstraint(JointConstraint* constraintp); + + void initializeConstraint(JointConstraint* constraint); + + void deactivateConstraint(JointConstraint *constraintp); + + void applyConstraint(JointConstraint* constraintp, F32 time, U8* joint_mask); + + BOOL setupPose(); public: - enum AssetStatus { ASSET_LOADED, ASSET_FETCHED, ASSET_NEEDS_FETCH, ASSET_FETCH_FAILED, ASSET_UNDEFINED }; - - enum InterpolationType { IT_STEP, IT_LINEAR, IT_SPLINE }; - - //------------------------------------------------------------------------- - // ScaleKey - //------------------------------------------------------------------------- - class ScaleKey - { - public: - ScaleKey() { mTime = 0.0f; } - ScaleKey(F32 time, const LLVector3 &scale) { mTime = time; mScale = scale; } - - F32 mTime; - LLVector3 mScale; - }; - - //------------------------------------------------------------------------- - // RotationKey - //------------------------------------------------------------------------- - class RotationKey - { - public: - RotationKey() { mTime = 0.0f; } - RotationKey(F32 time, const LLQuaternion &rotation) { mTime = time; mRotation = rotation; } - - F32 mTime; - LLQuaternion mRotation; - }; - - //------------------------------------------------------------------------- - // PositionKey - //------------------------------------------------------------------------- - class PositionKey - { - public: - PositionKey() { mTime = 0.0f; } - PositionKey(F32 time, const LLVector3 &position) { mTime = time; mPosition = position; } - - F32 mTime; - LLVector3 mPosition; - }; - - //------------------------------------------------------------------------- - // ScaleCurve - //------------------------------------------------------------------------- - class ScaleCurve - { - public: - ScaleCurve(); - ~ScaleCurve(); - LLVector3 getValue(F32 time, F32 duration); - LLVector3 interp(F32 u, ScaleKey& before, ScaleKey& after); - - InterpolationType mInterpolationType; - S32 mNumKeys; - typedef std::map<F32, ScaleKey> key_map_t; - key_map_t mKeys; - ScaleKey mLoopInKey; - ScaleKey mLoopOutKey; - }; - - //------------------------------------------------------------------------- - // RotationCurve - //------------------------------------------------------------------------- - class RotationCurve - { - public: - RotationCurve(); - ~RotationCurve(); - LLQuaternion getValue(F32 time, F32 duration); - LLQuaternion interp(F32 u, RotationKey& before, RotationKey& after); - - InterpolationType mInterpolationType; - S32 mNumKeys; - typedef std::map<F32, RotationKey> key_map_t; - key_map_t mKeys; - RotationKey mLoopInKey; - RotationKey mLoopOutKey; - }; - - //------------------------------------------------------------------------- - // PositionCurve - //------------------------------------------------------------------------- - class PositionCurve - { - public: - PositionCurve(); - ~PositionCurve(); - LLVector3 getValue(F32 time, F32 duration); - LLVector3 interp(F32 u, PositionKey& before, PositionKey& after); - - InterpolationType mInterpolationType; - S32 mNumKeys; - typedef std::map<F32, PositionKey> key_map_t; - key_map_t mKeys; - PositionKey mLoopInKey; - PositionKey mLoopOutKey; - }; - - //------------------------------------------------------------------------- - // JointMotion - //------------------------------------------------------------------------- - class JointMotion - { - public: - PositionCurve mPositionCurve; - RotationCurve mRotationCurve; - ScaleCurve mScaleCurve; - std::string mJointName; - U32 mUsage; - LLJoint::JointPriority mPriority; - - void update(LLJointState* joint_state, F32 time, F32 duration); - }; - - //------------------------------------------------------------------------- - // JointMotionList - //------------------------------------------------------------------------- - class JointMotionList - { - public: - std::vector<JointMotion*> mJointMotionArray; - F32 mDuration; - BOOL mLoop; - F32 mLoopInPoint; - F32 mLoopOutPoint; - F32 mEaseInDuration; - F32 mEaseOutDuration; - LLJoint::JointPriority mBasePriority; - LLHandMotion::eHandPose mHandPose; - LLJoint::JointPriority mMaxPriority; - typedef std::list<JointConstraintSharedData*> constraint_list_t; - constraint_list_t mConstraints; - LLBBoxLocal mPelvisBBox; - // mEmoteName is a facial motion, but it's necessary to appear here so that it's cached. - // TODO: LLKeyframeDataCache::getKeyframeData should probably return a class containing - // JointMotionList and mEmoteName, see LLKeyframeMotion::onInitialize. - std::string mEmoteName; - public: - JointMotionList(); - ~JointMotionList(); - U32 dumpDiagInfo(); - JointMotion* getJointMotion(U32 index) const { llassert(index < mJointMotionArray.size()); return mJointMotionArray[index]; } - U32 getNumJointMotions() const { return mJointMotionArray.size(); } - }; + enum AssetStatus { ASSET_LOADED, ASSET_FETCHED, ASSET_NEEDS_FETCH, ASSET_FETCH_FAILED, ASSET_UNDEFINED }; + + enum InterpolationType { IT_STEP, IT_LINEAR, IT_SPLINE }; + + //------------------------------------------------------------------------- + // ScaleKey + //------------------------------------------------------------------------- + class ScaleKey + { + public: + ScaleKey() { mTime = 0.0f; } + ScaleKey(F32 time, const LLVector3 &scale) { mTime = time; mScale = scale; } + + F32 mTime; + LLVector3 mScale; + }; + + //------------------------------------------------------------------------- + // RotationKey + //------------------------------------------------------------------------- + class RotationKey + { + public: + RotationKey() { mTime = 0.0f; } + RotationKey(F32 time, const LLQuaternion &rotation) { mTime = time; mRotation = rotation; } + + F32 mTime; + LLQuaternion mRotation; + }; + + //------------------------------------------------------------------------- + // PositionKey + //------------------------------------------------------------------------- + class PositionKey + { + public: + PositionKey() { mTime = 0.0f; } + PositionKey(F32 time, const LLVector3 &position) { mTime = time; mPosition = position; } + + F32 mTime; + LLVector3 mPosition; + }; + + //------------------------------------------------------------------------- + // ScaleCurve + //------------------------------------------------------------------------- + class ScaleCurve + { + public: + ScaleCurve(); + ~ScaleCurve(); + LLVector3 getValue(F32 time, F32 duration); + LLVector3 interp(F32 u, ScaleKey& before, ScaleKey& after); + + InterpolationType mInterpolationType; + S32 mNumKeys; + typedef std::map<F32, ScaleKey> key_map_t; + key_map_t mKeys; + ScaleKey mLoopInKey; + ScaleKey mLoopOutKey; + }; + + //------------------------------------------------------------------------- + // RotationCurve + //------------------------------------------------------------------------- + class RotationCurve + { + public: + RotationCurve(); + ~RotationCurve(); + LLQuaternion getValue(F32 time, F32 duration); + LLQuaternion interp(F32 u, RotationKey& before, RotationKey& after); + + InterpolationType mInterpolationType; + S32 mNumKeys; + typedef std::map<F32, RotationKey> key_map_t; + key_map_t mKeys; + RotationKey mLoopInKey; + RotationKey mLoopOutKey; + }; + + //------------------------------------------------------------------------- + // PositionCurve + //------------------------------------------------------------------------- + class PositionCurve + { + public: + PositionCurve(); + ~PositionCurve(); + LLVector3 getValue(F32 time, F32 duration); + LLVector3 interp(F32 u, PositionKey& before, PositionKey& after); + + InterpolationType mInterpolationType; + S32 mNumKeys; + typedef std::map<F32, PositionKey> key_map_t; + key_map_t mKeys; + PositionKey mLoopInKey; + PositionKey mLoopOutKey; + }; + + //------------------------------------------------------------------------- + // JointMotion + //------------------------------------------------------------------------- + class JointMotion + { + public: + PositionCurve mPositionCurve; + RotationCurve mRotationCurve; + ScaleCurve mScaleCurve; + std::string mJointName; + U32 mUsage; + LLJoint::JointPriority mPriority; + + void update(LLJointState* joint_state, F32 time, F32 duration); + }; + + //------------------------------------------------------------------------- + // JointMotionList + //------------------------------------------------------------------------- + class JointMotionList + { + public: + std::vector<JointMotion*> mJointMotionArray; + F32 mDuration; + BOOL mLoop; + F32 mLoopInPoint; + F32 mLoopOutPoint; + F32 mEaseInDuration; + F32 mEaseOutDuration; + LLJoint::JointPriority mBasePriority; + LLHandMotion::eHandPose mHandPose; + LLJoint::JointPriority mMaxPriority; + typedef std::list<JointConstraintSharedData*> constraint_list_t; + constraint_list_t mConstraints; + LLBBoxLocal mPelvisBBox; + // mEmoteName is a facial motion, but it's necessary to appear here so that it's cached. + // TODO: LLKeyframeDataCache::getKeyframeData should probably return a class containing + // JointMotionList and mEmoteName, see LLKeyframeMotion::onInitialize. + std::string mEmoteName; + public: + JointMotionList(); + ~JointMotionList(); + U32 dumpDiagInfo(); + JointMotion* getJointMotion(U32 index) const { llassert(index < mJointMotionArray.size()); return mJointMotionArray[index]; } + U32 getNumJointMotions() const { return mJointMotionArray.size(); } + }; protected: - JointMotionList* mJointMotionList; - std::vector<LLPointer<LLJointState> > mJointStates; - LLJoint* mPelvisp; - LLCharacter* mCharacter; - typedef std::list<JointConstraint*> constraint_list_t; - constraint_list_t mConstraints; - U32 mLastSkeletonSerialNum; - F32 mLastUpdateTime; - F32 mLastLoopedTime; - AssetStatus mAssetStatus; + JointMotionList* mJointMotionList; + std::vector<LLPointer<LLJointState> > mJointStates; + LLJoint* mPelvisp; + LLCharacter* mCharacter; + typedef std::list<JointConstraint*> constraint_list_t; + constraint_list_t mConstraints; + U32 mLastSkeletonSerialNum; + F32 mLastUpdateTime; + F32 mLastLoopedTime; + AssetStatus mAssetStatus; public: - void setCharacter(LLCharacter* character) { mCharacter = character; } + void setCharacter(LLCharacter* character) { mCharacter = character; } }; class LLKeyframeDataCache { public: - // *FIX: implement this as an actual singleton member of LLKeyframeMotion - LLKeyframeDataCache(){}; - ~LLKeyframeDataCache(); + // *FIX: implement this as an actual singleton member of LLKeyframeMotion + LLKeyframeDataCache(){}; + ~LLKeyframeDataCache(); - typedef std::map<LLUUID, class LLKeyframeMotion::JointMotionList*> keyframe_data_map_t; - static keyframe_data_map_t sKeyframeDataMap; + typedef std::map<LLUUID, class LLKeyframeMotion::JointMotionList*> keyframe_data_map_t; + static keyframe_data_map_t sKeyframeDataMap; - static void addKeyframeData(const LLUUID& id, LLKeyframeMotion::JointMotionList*); - static LLKeyframeMotion::JointMotionList* getKeyframeData(const LLUUID& id); + static void addKeyframeData(const LLUUID& id, LLKeyframeMotion::JointMotionList*); + static LLKeyframeMotion::JointMotionList* getKeyframeData(const LLUUID& id); - static void removeKeyframeData(const LLUUID& id); + static void removeKeyframeData(const LLUUID& id); - //print out diagnostic info - static void dumpDiagInfo(); - static void clear(); + //print out diagnostic info + static void dumpDiagInfo(); + static void clear(); }; #endif // LL_LLKEYFRAMEMOTION_H diff --git a/indra/llcharacter/llkeyframemotionparam.cpp b/indra/llcharacter/llkeyframemotionparam.cpp index c80aabe294..3082d30897 100644 --- a/indra/llcharacter/llkeyframemotionparam.cpp +++ b/indra/llcharacter/llkeyframemotionparam.cpp @@ -1,25 +1,25 @@ -/** +/** * @file llkeyframemotionparam.cpp * @brief Implementation of LLKeyframeMotion class. * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -48,13 +48,13 @@ //----------------------------------------------------------------------------- LLKeyframeMotionParam::LLKeyframeMotionParam( const LLUUID &id) : LLMotion(id) { - mDefaultKeyframeMotion = NULL; - mCharacter = NULL; + mDefaultKeyframeMotion = NULL; + mCharacter = NULL; - mEaseInDuration = 0.f; - mEaseOutDuration = 0.f; - mDuration = 0.f; - mPriority = LLJoint::LOW_PRIORITY; + mEaseInDuration = 0.f; + mEaseOutDuration = 0.f; + mDuration = 0.f; + mPriority = LLJoint::LOW_PRIORITY; } @@ -64,16 +64,16 @@ LLKeyframeMotionParam::LLKeyframeMotionParam( const LLUUID &id) : LLMotion(id) //----------------------------------------------------------------------------- LLKeyframeMotionParam::~LLKeyframeMotionParam() { - for (motion_map_t::value_type& motion_pair : mParameterizedMotions) - { - motion_list_t& motionList = motion_pair.second; - for (const ParameterizedMotion& paramMotion : motionList) - { - delete paramMotion.mMotion; - } - motionList.clear(); - } - mParameterizedMotions.clear(); + for (motion_map_t::value_type& motion_pair : mParameterizedMotions) + { + motion_list_t& motionList = motion_pair.second; + for (const ParameterizedMotion& paramMotion : motionList) + { + delete paramMotion.mMotion; + } + motionList.clear(); + } + mParameterizedMotions.clear(); } //----------------------------------------------------------------------------- @@ -81,53 +81,53 @@ LLKeyframeMotionParam::~LLKeyframeMotionParam() //----------------------------------------------------------------------------- LLMotion::LLMotionInitStatus LLKeyframeMotionParam::onInitialize(LLCharacter *character) { - mCharacter = character; - - if (!loadMotions()) - { - return STATUS_FAILURE; - } - - for (motion_map_t::value_type& motion_pair : mParameterizedMotions) - { - motion_list_t& motionList = motion_pair.second; - for (const ParameterizedMotion& paramMotion : motionList) - { - LLMotion* motion = paramMotion.mMotion; - motion->onInitialize(character); - - if (motion->getDuration() > mEaseInDuration) - { - mEaseInDuration = motion->getEaseInDuration(); - } - - if (motion->getEaseOutDuration() > mEaseOutDuration) - { - mEaseOutDuration = motion->getEaseOutDuration(); - } - - if (motion->getDuration() > mDuration) - { - mDuration = motion->getDuration(); - } - - if (motion->getPriority() > mPriority) - { - mPriority = motion->getPriority(); - } - - LLPose *pose = motion->getPose(); - - mPoseBlender.addMotion(motion); - for (LLJointState *jsp = pose->getFirstJointState(); jsp; jsp = pose->getNextJointState()) - { - LLPose *blendedPose = mPoseBlender.getBlendedPose(); - blendedPose->addJointState(jsp); - } - } - } - - return STATUS_SUCCESS; + mCharacter = character; + + if (!loadMotions()) + { + return STATUS_FAILURE; + } + + for (motion_map_t::value_type& motion_pair : mParameterizedMotions) + { + motion_list_t& motionList = motion_pair.second; + for (const ParameterizedMotion& paramMotion : motionList) + { + LLMotion* motion = paramMotion.mMotion; + motion->onInitialize(character); + + if (motion->getDuration() > mEaseInDuration) + { + mEaseInDuration = motion->getEaseInDuration(); + } + + if (motion->getEaseOutDuration() > mEaseOutDuration) + { + mEaseOutDuration = motion->getEaseOutDuration(); + } + + if (motion->getDuration() > mDuration) + { + mDuration = motion->getDuration(); + } + + if (motion->getPriority() > mPriority) + { + mPriority = motion->getPriority(); + } + + LLPose *pose = motion->getPose(); + + mPoseBlender.addMotion(motion); + for (LLJointState *jsp = pose->getFirstJointState(); jsp; jsp = pose->getNextJointState()) + { + LLPose *blendedPose = mPoseBlender.getBlendedPose(); + blendedPose->addJointState(jsp); + } + } + } + + return STATUS_SUCCESS; } //----------------------------------------------------------------------------- @@ -135,15 +135,15 @@ LLMotion::LLMotionInitStatus LLKeyframeMotionParam::onInitialize(LLCharacter *ch //----------------------------------------------------------------------------- BOOL LLKeyframeMotionParam::onActivate() { - for (motion_map_t::value_type& motion_pair : mParameterizedMotions) - { - motion_list_t& motionList = motion_pair.second; - for (const ParameterizedMotion& paramMotion : motionList) - { - paramMotion.mMotion->activate(mActivationTimestamp); - } - } - return TRUE; + for (motion_map_t::value_type& motion_pair : mParameterizedMotions) + { + motion_list_t& motionList = motion_pair.second; + for (const ParameterizedMotion& paramMotion : motionList) + { + paramMotion.mMotion->activate(mActivationTimestamp); + } + } + return TRUE; } @@ -153,116 +153,116 @@ BOOL LLKeyframeMotionParam::onActivate() BOOL LLKeyframeMotionParam::onUpdate(F32 time, U8* joint_mask) { LL_PROFILE_ZONE_SCOPED; - F32 weightFactor = 1.f / (F32)mParameterizedMotions.size(); - - // zero out all pose weights - for (motion_map_t::value_type& motion_pair : mParameterizedMotions) - { - motion_list_t& motionList = motion_pair.second; - for (const ParameterizedMotion& paramMotion : motionList) - { -// LL_INFOS() << "Weight for pose " << paramMotion.mMotion->getName() << " is " << paramMotion.mMotion->getPose()->getWeight() << LL_ENDL; - paramMotion.mMotion->getPose()->setWeight(0.f); - } - } - - - for (motion_map_t::value_type& motion_pair : mParameterizedMotions) - { - const std::string& paramName = motion_pair.first; - F32* paramValue = (F32 *)mCharacter->getAnimationData(paramName); - if (NULL == paramValue) // unexpected, but... - { - LL_WARNS() << "paramValue == NULL" << LL_ENDL; - continue; - } - - // DANGER! Do not modify mParameterizedMotions while using these pointers! - const ParameterizedMotion* firstMotion = NULL; - const ParameterizedMotion* secondMotion = NULL; - - motion_list_t& motionList = motion_pair.second; - for (const ParameterizedMotion& paramMotion : motionList) - { - paramMotion.mMotion->onUpdate(time, joint_mask); - - F32 distToParam = paramMotion.mParam - *paramValue; - - if ( distToParam <= 0.f) - { - // keep track of the motion closest to the parameter value - firstMotion = ¶mMotion; - } - else - { - // we've passed the parameter value - // so store the first motion we find as the second one we want to blend... - if (firstMotion && !secondMotion ) - { - secondMotion = ¶mMotion; - } - //...or, if we've seen no other motion so far, make sure we blend to this only - else if (!firstMotion) - { - firstMotion = ¶mMotion; - secondMotion = ¶mMotion; - } - } - } - - LLPose *firstPose; - LLPose *secondPose; - - if (firstMotion) - firstPose = firstMotion->mMotion->getPose(); - else - firstPose = NULL; - - if (secondMotion) - secondPose = secondMotion->mMotion->getPose(); - else - secondPose = NULL; - - // now modify weight of the subanim (only if we are blending between two motions) - if (firstMotion && secondMotion) - { - if (firstMotion == secondMotion) - { - firstPose->setWeight(weightFactor); - } - else if (firstMotion->mParam == secondMotion->mParam) - { - firstPose->setWeight(0.5f * weightFactor); - secondPose->setWeight(0.5f * weightFactor); - } - else - { - F32 first_weight = 1.f - - ((llclamp(*paramValue - firstMotion->mParam, 0.f, (secondMotion->mParam - firstMotion->mParam))) / - (secondMotion->mParam - firstMotion->mParam)); - first_weight = llclamp(first_weight, 0.f, 1.f); - - F32 second_weight = 1.f - first_weight; - - firstPose->setWeight(first_weight * weightFactor); - secondPose->setWeight(second_weight * weightFactor); - -// LL_INFOS() << "Parameter " << *paramName << ": " << *paramValue << LL_ENDL; -// LL_INFOS() << "Weights " << firstPose->getWeight() << " " << secondPose->getWeight() << LL_ENDL; - } - } - else if (firstMotion && !secondMotion) - { - firstPose->setWeight(weightFactor); - } - } - - // blend poses - mPoseBlender.blendAndApply(); - - LL_INFOS() << "Param Motion weight " << mPoseBlender.getBlendedPose()->getWeight() << LL_ENDL; - - return TRUE; + F32 weightFactor = 1.f / (F32)mParameterizedMotions.size(); + + // zero out all pose weights + for (motion_map_t::value_type& motion_pair : mParameterizedMotions) + { + motion_list_t& motionList = motion_pair.second; + for (const ParameterizedMotion& paramMotion : motionList) + { +// LL_INFOS() << "Weight for pose " << paramMotion.mMotion->getName() << " is " << paramMotion.mMotion->getPose()->getWeight() << LL_ENDL; + paramMotion.mMotion->getPose()->setWeight(0.f); + } + } + + + for (motion_map_t::value_type& motion_pair : mParameterizedMotions) + { + const std::string& paramName = motion_pair.first; + F32* paramValue = (F32 *)mCharacter->getAnimationData(paramName); + if (NULL == paramValue) // unexpected, but... + { + LL_WARNS() << "paramValue == NULL" << LL_ENDL; + continue; + } + + // DANGER! Do not modify mParameterizedMotions while using these pointers! + const ParameterizedMotion* firstMotion = NULL; + const ParameterizedMotion* secondMotion = NULL; + + motion_list_t& motionList = motion_pair.second; + for (const ParameterizedMotion& paramMotion : motionList) + { + paramMotion.mMotion->onUpdate(time, joint_mask); + + F32 distToParam = paramMotion.mParam - *paramValue; + + if ( distToParam <= 0.f) + { + // keep track of the motion closest to the parameter value + firstMotion = ¶mMotion; + } + else + { + // we've passed the parameter value + // so store the first motion we find as the second one we want to blend... + if (firstMotion && !secondMotion ) + { + secondMotion = ¶mMotion; + } + //...or, if we've seen no other motion so far, make sure we blend to this only + else if (!firstMotion) + { + firstMotion = ¶mMotion; + secondMotion = ¶mMotion; + } + } + } + + LLPose *firstPose; + LLPose *secondPose; + + if (firstMotion) + firstPose = firstMotion->mMotion->getPose(); + else + firstPose = NULL; + + if (secondMotion) + secondPose = secondMotion->mMotion->getPose(); + else + secondPose = NULL; + + // now modify weight of the subanim (only if we are blending between two motions) + if (firstMotion && secondMotion) + { + if (firstMotion == secondMotion) + { + firstPose->setWeight(weightFactor); + } + else if (firstMotion->mParam == secondMotion->mParam) + { + firstPose->setWeight(0.5f * weightFactor); + secondPose->setWeight(0.5f * weightFactor); + } + else + { + F32 first_weight = 1.f - + ((llclamp(*paramValue - firstMotion->mParam, 0.f, (secondMotion->mParam - firstMotion->mParam))) / + (secondMotion->mParam - firstMotion->mParam)); + first_weight = llclamp(first_weight, 0.f, 1.f); + + F32 second_weight = 1.f - first_weight; + + firstPose->setWeight(first_weight * weightFactor); + secondPose->setWeight(second_weight * weightFactor); + +// LL_INFOS() << "Parameter " << *paramName << ": " << *paramValue << LL_ENDL; +// LL_INFOS() << "Weights " << firstPose->getWeight() << " " << secondPose->getWeight() << LL_ENDL; + } + } + else if (firstMotion && !secondMotion) + { + firstPose->setWeight(weightFactor); + } + } + + // blend poses + mPoseBlender.blendAndApply(); + + LL_INFOS() << "Param Motion weight " << mPoseBlender.getBlendedPose()->getWeight() << LL_ENDL; + + return TRUE; } //----------------------------------------------------------------------------- @@ -270,14 +270,14 @@ BOOL LLKeyframeMotionParam::onUpdate(F32 time, U8* joint_mask) //----------------------------------------------------------------------------- void LLKeyframeMotionParam::onDeactivate() { - for (motion_map_t::value_type& motion_pair : mParameterizedMotions) - { - motion_list_t& motionList = motion_pair.second; - for (const ParameterizedMotion& paramMotion : motionList) - { - paramMotion.mMotion->onDeactivate(); - } - } + for (motion_map_t::value_type& motion_pair : mParameterizedMotions) + { + motion_list_t& motionList = motion_pair.second; + for (const ParameterizedMotion& paramMotion : motionList) + { + paramMotion.mMotion->onDeactivate(); + } + } } //----------------------------------------------------------------------------- @@ -285,19 +285,19 @@ void LLKeyframeMotionParam::onDeactivate() //----------------------------------------------------------------------------- BOOL LLKeyframeMotionParam::addKeyframeMotion(char *name, const LLUUID &id, char *param, F32 value) { - LLMotion *newMotion = mCharacter->createMotion( id ); - - if (!newMotion) - { - return FALSE; - } - - newMotion->setName(name); - - // now add motion to this list - mParameterizedMotions[param].insert(ParameterizedMotion(newMotion, value)); - - return TRUE; + LLMotion *newMotion = mCharacter->createMotion( id ); + + if (!newMotion) + { + return FALSE; + } + + newMotion->setName(name); + + // now add motion to this list + mParameterizedMotions[param].insert(ParameterizedMotion(newMotion, value)); + + return TRUE; } @@ -306,17 +306,17 @@ BOOL LLKeyframeMotionParam::addKeyframeMotion(char *name, const LLUUID &id, char //----------------------------------------------------------------------------- void LLKeyframeMotionParam::setDefaultKeyframeMotion(char *name) { - for (motion_map_t::value_type& motion_pair : mParameterizedMotions) - { - motion_list_t& motionList = motion_pair.second; - for (const ParameterizedMotion& paramMotion : motionList) - { - if (paramMotion.mMotion->getName() == name) - { - mDefaultKeyframeMotion = paramMotion.mMotion; - } - } - } + for (motion_map_t::value_type& motion_pair : mParameterizedMotions) + { + motion_list_t& motionList = motion_pair.second; + for (const ParameterizedMotion& paramMotion : motionList) + { + if (paramMotion.mMotion->getName() == name) + { + mDefaultKeyframeMotion = paramMotion.mMotion; + } + } + } } //----------------------------------------------------------------------------- @@ -324,113 +324,113 @@ void LLKeyframeMotionParam::setDefaultKeyframeMotion(char *name) //----------------------------------------------------------------------------- BOOL LLKeyframeMotionParam::loadMotions() { - //------------------------------------------------------------------------- - // Load named file by concatenating the character prefix with the motion name. - // Load data into a buffer to be parsed. - //------------------------------------------------------------------------- - //std::string path = gDirUtilp->getExpandedFilename(LL_PATH_MOTIONS,mCharacter->getAnimationPrefix()) - // + "_" + getName() + ".llp"; - //RN: deprecated unused reference to "motion" directory - std::string path; - - - //------------------------------------------------------------------------- - // open the file - //------------------------------------------------------------------------- - S32 fileSize = 0; - LLAPRFile infile ; - infile.open(path, LL_APR_R, NULL, &fileSize); - apr_file_t* fp = infile.getFileHandle() ; - if (!fp || fileSize == 0) - { - LL_INFOS() << "ERROR: can't open: " << path << LL_ENDL; - return FALSE; - } - - // allocate a text buffer - std::vector<char> text(fileSize+1); - - //------------------------------------------------------------------------- - // load data from file into buffer - //------------------------------------------------------------------------- - bool error = false; - char *p = &text[0]; - while ( 1 ) - { - if (apr_file_eof(fp) == APR_EOF) - { - break; - } - if (apr_file_gets(p, 1024, fp) != APR_SUCCESS) - { - error = true; - break; - } - while ( *(++p) ) - ; - } - - //------------------------------------------------------------------------- - // close the file - //------------------------------------------------------------------------- - infile.close(); - - //------------------------------------------------------------------------- - // check for error - //------------------------------------------------------------------------- - llassert( p <= (&text[0] + fileSize) ); - - if ( error ) - { - LL_INFOS() << "ERROR: error while reading from " << path << LL_ENDL; - return FALSE; - } - - LL_INFOS() << "Loading parametric keyframe data for: " << getName() << LL_ENDL; - - //------------------------------------------------------------------------- - // parse the text and build keyframe data structures - //------------------------------------------------------------------------- - p = &text[0]; - S32 num; - char strA[80]; /* Flawfinder: ignore */ - char strB[80]; /* Flawfinder: ignore */ - F32 floatA = 0.0f; - - - //------------------------------------------------------------------------- - // get priority - //------------------------------------------------------------------------- - BOOL isFirstMotion = TRUE; - num = sscanf(p, "%79s %79s %f", strA, strB, &floatA); /* Flawfinder: ignore */ - - while(1) - { - if (num == 0 || num == EOF) break; - if ((num != 3)) - { - LL_INFOS() << "WARNING: can't read parametric motion" << LL_ENDL; - return FALSE; - } - - addKeyframeMotion(strA, gAnimLibrary.stringToAnimState(std::string(strA)), strB, floatA); - if (isFirstMotion) - { - isFirstMotion = FALSE; - setDefaultKeyframeMotion(strA); - } - - p = strstr(p, "\n"); - if (!p) - { - break; - } - - p++; - num = sscanf(p, "%79s %79s %f", strA, strB, &floatA); /* Flawfinder: ignore */ - } - - return TRUE; + //------------------------------------------------------------------------- + // Load named file by concatenating the character prefix with the motion name. + // Load data into a buffer to be parsed. + //------------------------------------------------------------------------- + //std::string path = gDirUtilp->getExpandedFilename(LL_PATH_MOTIONS,mCharacter->getAnimationPrefix()) + // + "_" + getName() + ".llp"; + //RN: deprecated unused reference to "motion" directory + std::string path; + + + //------------------------------------------------------------------------- + // open the file + //------------------------------------------------------------------------- + S32 fileSize = 0; + LLAPRFile infile ; + infile.open(path, LL_APR_R, NULL, &fileSize); + apr_file_t* fp = infile.getFileHandle() ; + if (!fp || fileSize == 0) + { + LL_INFOS() << "ERROR: can't open: " << path << LL_ENDL; + return FALSE; + } + + // allocate a text buffer + std::vector<char> text(fileSize+1); + + //------------------------------------------------------------------------- + // load data from file into buffer + //------------------------------------------------------------------------- + bool error = false; + char *p = &text[0]; + while ( 1 ) + { + if (apr_file_eof(fp) == APR_EOF) + { + break; + } + if (apr_file_gets(p, 1024, fp) != APR_SUCCESS) + { + error = true; + break; + } + while ( *(++p) ) + ; + } + + //------------------------------------------------------------------------- + // close the file + //------------------------------------------------------------------------- + infile.close(); + + //------------------------------------------------------------------------- + // check for error + //------------------------------------------------------------------------- + llassert( p <= (&text[0] + fileSize) ); + + if ( error ) + { + LL_INFOS() << "ERROR: error while reading from " << path << LL_ENDL; + return FALSE; + } + + LL_INFOS() << "Loading parametric keyframe data for: " << getName() << LL_ENDL; + + //------------------------------------------------------------------------- + // parse the text and build keyframe data structures + //------------------------------------------------------------------------- + p = &text[0]; + S32 num; + char strA[80]; /* Flawfinder: ignore */ + char strB[80]; /* Flawfinder: ignore */ + F32 floatA = 0.0f; + + + //------------------------------------------------------------------------- + // get priority + //------------------------------------------------------------------------- + BOOL isFirstMotion = TRUE; + num = sscanf(p, "%79s %79s %f", strA, strB, &floatA); /* Flawfinder: ignore */ + + while(1) + { + if (num == 0 || num == EOF) break; + if ((num != 3)) + { + LL_INFOS() << "WARNING: can't read parametric motion" << LL_ENDL; + return FALSE; + } + + addKeyframeMotion(strA, gAnimLibrary.stringToAnimState(std::string(strA)), strB, floatA); + if (isFirstMotion) + { + isFirstMotion = FALSE; + setDefaultKeyframeMotion(strA); + } + + p = strstr(p, "\n"); + if (!p) + { + break; + } + + p++; + num = sscanf(p, "%79s %79s %f", strA, strB, &floatA); /* Flawfinder: ignore */ + } + + return TRUE; } // End diff --git a/indra/llcharacter/llkeyframemotionparam.h b/indra/llcharacter/llkeyframemotionparam.h index 0fac3724d1..c906a25ceb 100644 --- a/indra/llcharacter/llkeyframemotionparam.h +++ b/indra/llcharacter/llkeyframemotionparam.h @@ -1,25 +1,25 @@ -/** +/** * @file llkeyframemotionparam.h * @brief Implementation of LLKeframeMotionParam class. * * $LicenseInfo:firstyear=2002&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -43,127 +43,127 @@ // class LLKeyframeMotionParam //----------------------------------------------------------------------------- class LLKeyframeMotionParam : - public LLMotion + public LLMotion { public: - // Constructor - LLKeyframeMotionParam(const LLUUID &id); + // Constructor + LLKeyframeMotionParam(const LLUUID &id); - // Destructor - virtual ~LLKeyframeMotionParam(); + // Destructor + virtual ~LLKeyframeMotionParam(); public: - //------------------------------------------------------------------------- - // functions to support MotionController and MotionRegistry - //------------------------------------------------------------------------- + //------------------------------------------------------------------------- + // functions to support MotionController and MotionRegistry + //------------------------------------------------------------------------- - // static constructor - // all subclasses must implement such a function and register it - static LLMotion *create(const LLUUID &id) { return new LLKeyframeMotionParam(id); } + // static constructor + // all subclasses must implement such a function and register it + static LLMotion *create(const LLUUID &id) { return new LLKeyframeMotionParam(id); } public: - //------------------------------------------------------------------------- - // animation callbacks to be implemented by subclasses - //------------------------------------------------------------------------- + //------------------------------------------------------------------------- + // animation callbacks to be implemented by subclasses + //------------------------------------------------------------------------- - // motions must specify whether or not they loop - virtual BOOL getLoop() { - return TRUE; - } + // motions must specify whether or not they loop + virtual BOOL getLoop() { + return TRUE; + } - // motions must report their total duration - virtual F32 getDuration() { - return mDuration; - } + // motions must report their total duration + virtual F32 getDuration() { + return mDuration; + } - // motions must report their "ease in" duration - virtual F32 getEaseInDuration() { - return mEaseInDuration; - } + // motions must report their "ease in" duration + virtual F32 getEaseInDuration() { + return mEaseInDuration; + } - // motions must report their "ease out" duration. - virtual F32 getEaseOutDuration() { - return mEaseOutDuration; - } + // motions must report their "ease out" duration. + virtual F32 getEaseOutDuration() { + return mEaseOutDuration; + } - // motions must report their priority - virtual LLJoint::JointPriority getPriority() { - return mPriority; - } + // motions must report their priority + virtual LLJoint::JointPriority getPriority() { + return mPriority; + } - virtual LLMotionBlendType getBlendType() { return NORMAL_BLEND; } + virtual LLMotionBlendType getBlendType() { return NORMAL_BLEND; } - // called to determine when a motion should be activated/deactivated based on avatar pixel coverage - virtual F32 getMinPixelArea() { return MIN_REQUIRED_PIXEL_AREA_KEYFRAME; } + // called to determine when a motion should be activated/deactivated based on avatar pixel coverage + virtual F32 getMinPixelArea() { return MIN_REQUIRED_PIXEL_AREA_KEYFRAME; } - // run-time (post constructor) initialization, - // called after parameters have been set - // must return true to indicate success and be available for activation - virtual LLMotionInitStatus onInitialize(LLCharacter *character); + // run-time (post constructor) initialization, + // called after parameters have been set + // must return true to indicate success and be available for activation + virtual LLMotionInitStatus onInitialize(LLCharacter *character); - // called when a motion is activated - // must return TRUE to indicate success, or else - // it will be deactivated - virtual BOOL onActivate(); + // called when a motion is activated + // must return TRUE to indicate success, or else + // it will be deactivated + virtual BOOL onActivate(); - // called per time step - // must return TRUE while it is active, and - // must return FALSE when the motion is completed. - virtual BOOL onUpdate(F32 time, U8* joint_mask); + // called per time step + // must return TRUE while it is active, and + // must return FALSE when the motion is completed. + virtual BOOL onUpdate(F32 time, U8* joint_mask); - // called when a motion is deactivated - virtual void onDeactivate(); + // called when a motion is deactivated + virtual void onDeactivate(); - virtual LLPose* getPose() { return mPoseBlender.getBlendedPose();} + virtual LLPose* getPose() { return mPoseBlender.getBlendedPose();} protected: - //------------------------------------------------------------------------- - // new functions defined by this subclass - //------------------------------------------------------------------------- - struct ParameterizedMotion - { - ParameterizedMotion(LLMotion* motion, F32 param) : mMotion(motion), mParam(param) {} - LLMotion* mMotion; - F32 mParam; - }; - - // add a motion and associated parameter triplet - BOOL addKeyframeMotion(char *name, const LLUUID &id, char *param, F32 value); - - // set default motion for LOD and retrieving blend constants - void setDefaultKeyframeMotion(char *); - - BOOL loadMotions(); + //------------------------------------------------------------------------- + // new functions defined by this subclass + //------------------------------------------------------------------------- + struct ParameterizedMotion + { + ParameterizedMotion(LLMotion* motion, F32 param) : mMotion(motion), mParam(param) {} + LLMotion* mMotion; + F32 mParam; + }; + + // add a motion and associated parameter triplet + BOOL addKeyframeMotion(char *name, const LLUUID &id, char *param, F32 value); + + // set default motion for LOD and retrieving blend constants + void setDefaultKeyframeMotion(char *); + + BOOL loadMotions(); protected: - //------------------------------------------------------------------------- - // Member Data - //------------------------------------------------------------------------- - - struct compare_motions - { - bool operator() (const ParameterizedMotion& a, const ParameterizedMotion& b) const - { - if (a.mParam != b.mParam) - return (a.mParam < b.mParam); - else - return a.mMotion < b.mMotion; - } - }; - - typedef std::set < ParameterizedMotion, compare_motions > motion_list_t; - typedef std::map <std::string, motion_list_t > motion_map_t; - motion_map_t mParameterizedMotions; - LLMotion* mDefaultKeyframeMotion; - LLCharacter* mCharacter; - LLPoseBlender mPoseBlender; - - F32 mEaseInDuration; - F32 mEaseOutDuration; - F32 mDuration; - LLJoint::JointPriority mPriority; - - LLUUID mTransactionID; + //------------------------------------------------------------------------- + // Member Data + //------------------------------------------------------------------------- + + struct compare_motions + { + bool operator() (const ParameterizedMotion& a, const ParameterizedMotion& b) const + { + if (a.mParam != b.mParam) + return (a.mParam < b.mParam); + else + return a.mMotion < b.mMotion; + } + }; + + typedef std::set < ParameterizedMotion, compare_motions > motion_list_t; + typedef std::map <std::string, motion_list_t > motion_map_t; + motion_map_t mParameterizedMotions; + LLMotion* mDefaultKeyframeMotion; + LLCharacter* mCharacter; + LLPoseBlender mPoseBlender; + + F32 mEaseInDuration; + F32 mEaseOutDuration; + F32 mDuration; + LLJoint::JointPriority mPriority; + + LLUUID mTransactionID; }; #endif // LL_LLKEYFRAMEMOTIONPARAM_H diff --git a/indra/llcharacter/llkeyframestandmotion.cpp b/indra/llcharacter/llkeyframestandmotion.cpp index 02c1d3cdbd..16f4cdc115 100644 --- a/indra/llcharacter/llkeyframestandmotion.cpp +++ b/indra/llcharacter/llkeyframestandmotion.cpp @@ -1,25 +1,25 @@ -/** +/** * @file llkeyframestandmotion.cpp * @brief Implementation of LLKeyframeStandMotion class. * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -35,7 +35,7 @@ //----------------------------------------------------------------------------- // Macros and consts //----------------------------------------------------------------------------- -#define GO_TO_KEY_POSE 1 +#define GO_TO_KEY_POSE 1 #define MIN_TRACK_SPEED 0.01f const F32 ROTATION_THRESHOLD = 0.6f; const F32 POSITION_THRESHOLD = 0.1f; @@ -46,30 +46,30 @@ const F32 POSITION_THRESHOLD = 0.1f; //----------------------------------------------------------------------------- LLKeyframeStandMotion::LLKeyframeStandMotion(const LLUUID &id) : LLKeyframeMotion(id) { - mFlipFeet = FALSE; - mCharacter = NULL; + mFlipFeet = FALSE; + mCharacter = NULL; - // create kinematic hierarchy - mPelvisJoint.addChild( &mHipLeftJoint ); - mHipLeftJoint.addChild( &mKneeLeftJoint ); - mKneeLeftJoint.addChild( &mAnkleLeftJoint ); - mPelvisJoint.addChild( &mHipRightJoint ); - mHipRightJoint.addChild( &mKneeRightJoint ); - mKneeRightJoint.addChild( &mAnkleRightJoint ); + // create kinematic hierarchy + mPelvisJoint.addChild( &mHipLeftJoint ); + mHipLeftJoint.addChild( &mKneeLeftJoint ); + mKneeLeftJoint.addChild( &mAnkleLeftJoint ); + mPelvisJoint.addChild( &mHipRightJoint ); + mHipRightJoint.addChild( &mKneeRightJoint ); + mKneeRightJoint.addChild( &mAnkleRightJoint ); - mPelvisState = NULL; + mPelvisState = NULL; - mHipLeftState = NULL; - mKneeLeftState = NULL; - mAnkleLeftState = NULL; + mHipLeftState = NULL; + mKneeLeftState = NULL; + mAnkleLeftState = NULL; - mHipRightState = NULL; - mKneeRightState = NULL; - mAnkleRightState = NULL; + mHipRightState = NULL; + mKneeRightState = NULL; + mAnkleRightState = NULL; - mTrackAnkles = TRUE; + mTrackAnkles = TRUE; - mFrameNum = 0; + mFrameNum = 0; } @@ -87,43 +87,43 @@ LLKeyframeStandMotion::~LLKeyframeStandMotion() //----------------------------------------------------------------------------- LLMotion::LLMotionInitStatus LLKeyframeStandMotion::onInitialize(LLCharacter *character) { - // save character pointer for later use - mCharacter = character; - - mFlipFeet = FALSE; - - // load keyframe data, setup pose and joint states - LLMotion::LLMotionInitStatus status = LLKeyframeMotion::onInitialize(character); - if ( status == STATUS_FAILURE ) - { - return status; - } - - // find the necessary joint states - LLPose *pose = getPose(); - mPelvisState = pose->findJointState("mPelvis"); - - mHipLeftState = pose->findJointState("mHipLeft"); - mKneeLeftState = pose->findJointState("mKneeLeft"); - mAnkleLeftState = pose->findJointState("mAnkleLeft"); - - mHipRightState = pose->findJointState("mHipRight"); - mKneeRightState = pose->findJointState("mKneeRight"); - mAnkleRightState = pose->findJointState("mAnkleRight"); - - if ( !mPelvisState || - !mHipLeftState || - !mKneeLeftState || - !mAnkleLeftState || - !mHipRightState || - !mKneeRightState || - !mAnkleRightState ) - { - LL_INFOS() << getName() << ": Can't find necessary joint states" << LL_ENDL; - return STATUS_FAILURE; - } - - return STATUS_SUCCESS; + // save character pointer for later use + mCharacter = character; + + mFlipFeet = FALSE; + + // load keyframe data, setup pose and joint states + LLMotion::LLMotionInitStatus status = LLKeyframeMotion::onInitialize(character); + if ( status == STATUS_FAILURE ) + { + return status; + } + + // find the necessary joint states + LLPose *pose = getPose(); + mPelvisState = pose->findJointState("mPelvis"); + + mHipLeftState = pose->findJointState("mHipLeft"); + mKneeLeftState = pose->findJointState("mKneeLeft"); + mAnkleLeftState = pose->findJointState("mAnkleLeft"); + + mHipRightState = pose->findJointState("mHipRight"); + mKneeRightState = pose->findJointState("mKneeRight"); + mAnkleRightState = pose->findJointState("mAnkleRight"); + + if ( !mPelvisState || + !mHipLeftState || + !mKneeLeftState || + !mAnkleLeftState || + !mHipRightState || + !mKneeRightState || + !mAnkleRightState ) + { + LL_INFOS() << getName() << ": Can't find necessary joint states" << LL_ENDL; + return STATUS_FAILURE; + } + + return STATUS_SUCCESS; } //----------------------------------------------------------------------------- @@ -131,20 +131,20 @@ LLMotion::LLMotionInitStatus LLKeyframeStandMotion::onInitialize(LLCharacter *ch //----------------------------------------------------------------------------- BOOL LLKeyframeStandMotion::onActivate() { - //------------------------------------------------------------------------- - // setup the IK solvers - //------------------------------------------------------------------------- - mIKLeft.setPoleVector( LLVector3(1.0f, 0.0f, 0.0f)); - mIKRight.setPoleVector( LLVector3(1.0f, 0.0f, 0.0f)); - mIKLeft.setBAxis( LLVector3(0.05f, 1.0f, 0.0f)); - mIKRight.setBAxis( LLVector3(-0.05f, 1.0f, 0.0f)); + //------------------------------------------------------------------------- + // setup the IK solvers + //------------------------------------------------------------------------- + mIKLeft.setPoleVector( LLVector3(1.0f, 0.0f, 0.0f)); + mIKRight.setPoleVector( LLVector3(1.0f, 0.0f, 0.0f)); + mIKLeft.setBAxis( LLVector3(0.05f, 1.0f, 0.0f)); + mIKRight.setBAxis( LLVector3(-0.05f, 1.0f, 0.0f)); - mLastGoodPelvisRotation.loadIdentity(); - mLastGoodPosition.clearVec(); + mLastGoodPelvisRotation.loadIdentity(); + mLastGoodPosition.clearVec(); - mFrameNum = 0; + mFrameNum = 0; - return LLKeyframeMotion::onActivate(); + return LLKeyframeMotion::onActivate(); } //----------------------------------------------------------------------------- @@ -152,7 +152,7 @@ BOOL LLKeyframeStandMotion::onActivate() //----------------------------------------------------------------------------- void LLKeyframeStandMotion::onDeactivate() { - LLKeyframeMotion::onDeactivate(); + LLKeyframeMotion::onDeactivate(); } //----------------------------------------------------------------------------- @@ -160,183 +160,183 @@ void LLKeyframeStandMotion::onDeactivate() //----------------------------------------------------------------------------- BOOL LLKeyframeStandMotion::onUpdate(F32 time, U8* joint_mask) { - //------------------------------------------------------------------------- - // let the base class update the cycle - //------------------------------------------------------------------------- - BOOL status = LLKeyframeMotion::onUpdate(time, joint_mask); - if (!status) - { - return FALSE; - } - - LLVector3 root_world_pos = mPelvisState->getJoint()->getParent()->getWorldPosition(); - - // have we received a valid world position for this avatar? - if (root_world_pos.isExactlyZero()) - { - return TRUE; - } - - //------------------------------------------------------------------------- - // Stop tracking (start locking) ankles once ease in is done. - // Setting this here ensures we track until we get valid foot position. - //------------------------------------------------------------------------- - if (dot(mPelvisState->getJoint()->getWorldRotation(), mLastGoodPelvisRotation) < ROTATION_THRESHOLD) - { - mLastGoodPelvisRotation = mPelvisState->getJoint()->getWorldRotation(); - mLastGoodPelvisRotation.normalize(); - mTrackAnkles = TRUE; - } - else if ((mCharacter->getCharacterPosition() - mLastGoodPosition).magVecSquared() > POSITION_THRESHOLD) - { - mLastGoodPosition = mCharacter->getCharacterPosition(); - mTrackAnkles = TRUE; - } - else if (mPose.getWeight() < 1.f) - { - mTrackAnkles = TRUE; - } - - - //------------------------------------------------------------------------- - // propagate joint positions to internal versions - //------------------------------------------------------------------------- + //------------------------------------------------------------------------- + // let the base class update the cycle + //------------------------------------------------------------------------- + BOOL status = LLKeyframeMotion::onUpdate(time, joint_mask); + if (!status) + { + return FALSE; + } + + LLVector3 root_world_pos = mPelvisState->getJoint()->getParent()->getWorldPosition(); + + // have we received a valid world position for this avatar? + if (root_world_pos.isExactlyZero()) + { + return TRUE; + } + + //------------------------------------------------------------------------- + // Stop tracking (start locking) ankles once ease in is done. + // Setting this here ensures we track until we get valid foot position. + //------------------------------------------------------------------------- + if (dot(mPelvisState->getJoint()->getWorldRotation(), mLastGoodPelvisRotation) < ROTATION_THRESHOLD) + { + mLastGoodPelvisRotation = mPelvisState->getJoint()->getWorldRotation(); + mLastGoodPelvisRotation.normalize(); + mTrackAnkles = TRUE; + } + else if ((mCharacter->getCharacterPosition() - mLastGoodPosition).magVecSquared() > POSITION_THRESHOLD) + { + mLastGoodPosition = mCharacter->getCharacterPosition(); + mTrackAnkles = TRUE; + } + else if (mPose.getWeight() < 1.f) + { + mTrackAnkles = TRUE; + } + + + //------------------------------------------------------------------------- + // propagate joint positions to internal versions + //------------------------------------------------------------------------- // SL-315 - mPelvisJoint.setPosition( - root_world_pos + - mPelvisState->getPosition() ); + mPelvisJoint.setPosition( + root_world_pos + + mPelvisState->getPosition() ); // SL-315 - mHipLeftJoint.setPosition( mHipLeftState->getJoint()->getPosition() ); - mKneeLeftJoint.setPosition( mKneeLeftState->getJoint()->getPosition() ); - mAnkleLeftJoint.setPosition( mAnkleLeftState->getJoint()->getPosition() ); + mHipLeftJoint.setPosition( mHipLeftState->getJoint()->getPosition() ); + mKneeLeftJoint.setPosition( mKneeLeftState->getJoint()->getPosition() ); + mAnkleLeftJoint.setPosition( mAnkleLeftState->getJoint()->getPosition() ); - mHipLeftJoint.setScale( mHipLeftState->getJoint()->getScale() ); - mKneeLeftJoint.setScale( mKneeLeftState->getJoint()->getScale() ); - mAnkleLeftJoint.setScale( mAnkleLeftState->getJoint()->getScale() ); + mHipLeftJoint.setScale( mHipLeftState->getJoint()->getScale() ); + mKneeLeftJoint.setScale( mKneeLeftState->getJoint()->getScale() ); + mAnkleLeftJoint.setScale( mAnkleLeftState->getJoint()->getScale() ); // SL-315 - mHipRightJoint.setPosition( mHipRightState->getJoint()->getPosition() ); - mKneeRightJoint.setPosition( mKneeRightState->getJoint()->getPosition() ); - mAnkleRightJoint.setPosition( mAnkleRightState->getJoint()->getPosition() ); - - mHipRightJoint.setScale( mHipRightState->getJoint()->getScale() ); - mKneeRightJoint.setScale( mKneeRightState->getJoint()->getScale() ); - mAnkleRightJoint.setScale( mAnkleRightState->getJoint()->getScale() ); - //------------------------------------------------------------------------- - // propagate joint rotations to internal versions - //------------------------------------------------------------------------- - mPelvisJoint.setRotation( mPelvisState->getJoint()->getWorldRotation() ); + mHipRightJoint.setPosition( mHipRightState->getJoint()->getPosition() ); + mKneeRightJoint.setPosition( mKneeRightState->getJoint()->getPosition() ); + mAnkleRightJoint.setPosition( mAnkleRightState->getJoint()->getPosition() ); + + mHipRightJoint.setScale( mHipRightState->getJoint()->getScale() ); + mKneeRightJoint.setScale( mKneeRightState->getJoint()->getScale() ); + mAnkleRightJoint.setScale( mAnkleRightState->getJoint()->getScale() ); + //------------------------------------------------------------------------- + // propagate joint rotations to internal versions + //------------------------------------------------------------------------- + mPelvisJoint.setRotation( mPelvisState->getJoint()->getWorldRotation() ); #if GO_TO_KEY_POSE - mHipLeftJoint.setRotation( mHipLeftState->getRotation() ); - mKneeLeftJoint.setRotation( mKneeLeftState->getRotation() ); - mAnkleLeftJoint.setRotation( mAnkleLeftState->getRotation() ); + mHipLeftJoint.setRotation( mHipLeftState->getRotation() ); + mKneeLeftJoint.setRotation( mKneeLeftState->getRotation() ); + mAnkleLeftJoint.setRotation( mAnkleLeftState->getRotation() ); - mHipRightJoint.setRotation( mHipRightState->getRotation() ); - mKneeRightJoint.setRotation( mKneeRightState->getRotation() ); - mAnkleRightJoint.setRotation( mAnkleRightState->getRotation() ); + mHipRightJoint.setRotation( mHipRightState->getRotation() ); + mKneeRightJoint.setRotation( mKneeRightState->getRotation() ); + mAnkleRightJoint.setRotation( mAnkleRightState->getRotation() ); #else - mHipLeftJoint.setRotation( mHipLeftState->getJoint()->getRotation() ); - mKneeLeftJoint.setRotation( mKneeLeftState->getJoint()->getRotation() ); - mAnkleLeftJoint.setRotation( mAnkleLeftState->getJoint()->getRotation() ); + mHipLeftJoint.setRotation( mHipLeftState->getJoint()->getRotation() ); + mKneeLeftJoint.setRotation( mKneeLeftState->getJoint()->getRotation() ); + mAnkleLeftJoint.setRotation( mAnkleLeftState->getJoint()->getRotation() ); - mHipRightJoint.setRotation( mHipRightState->getJoint()->getRotation() ); - mKneeRightJoint.setRotation( mKneeRightState->getJoint()->getRotation() ); - mAnkleRightJoint.setRotation( mAnkleRightState->getJoint()->getRotation() ); + mHipRightJoint.setRotation( mHipRightState->getJoint()->getRotation() ); + mKneeRightJoint.setRotation( mKneeRightState->getJoint()->getRotation() ); + mAnkleRightJoint.setRotation( mAnkleRightState->getJoint()->getRotation() ); #endif - // need to wait for underlying keyframe motion to affect the skeleton - if (mFrameNum == 2) - { - mIKLeft.setupJoints( &mHipLeftJoint, &mKneeLeftJoint, &mAnkleLeftJoint, &mTargetLeft ); - mIKRight.setupJoints( &mHipRightJoint, &mKneeRightJoint, &mAnkleRightJoint, &mTargetRight ); - } - else if (mFrameNum < 2) - { - mFrameNum++; - return TRUE; - } - - mFrameNum++; - - //------------------------------------------------------------------------- - // compute target position by projecting ankles to the ground - //------------------------------------------------------------------------- - if ( mTrackAnkles ) - { - mCharacter->getGround( mAnkleLeftJoint.getWorldPosition(), mPositionLeft, mNormalLeft); - mCharacter->getGround( mAnkleRightJoint.getWorldPosition(), mPositionRight, mNormalRight); + // need to wait for underlying keyframe motion to affect the skeleton + if (mFrameNum == 2) + { + mIKLeft.setupJoints( &mHipLeftJoint, &mKneeLeftJoint, &mAnkleLeftJoint, &mTargetLeft ); + mIKRight.setupJoints( &mHipRightJoint, &mKneeRightJoint, &mAnkleRightJoint, &mTargetRight ); + } + else if (mFrameNum < 2) + { + mFrameNum++; + return TRUE; + } + + mFrameNum++; + + //------------------------------------------------------------------------- + // compute target position by projecting ankles to the ground + //------------------------------------------------------------------------- + if ( mTrackAnkles ) + { + mCharacter->getGround( mAnkleLeftJoint.getWorldPosition(), mPositionLeft, mNormalLeft); + mCharacter->getGround( mAnkleRightJoint.getWorldPosition(), mPositionRight, mNormalRight); // SL-315 - mTargetLeft.setPosition( mPositionLeft ); - mTargetRight.setPosition( mPositionRight ); - } - - //------------------------------------------------------------------------- - // update solvers - //------------------------------------------------------------------------- - mIKLeft.solve(); - mIKRight.solve(); - - //------------------------------------------------------------------------- - // make ankle rotation conform to the ground - //------------------------------------------------------------------------- - if ( mTrackAnkles ) - { - LLVector4 dirLeft4 = mAnkleLeftJoint.getWorldMatrix().getFwdRow4(); - LLVector4 dirRight4 = mAnkleRightJoint.getWorldMatrix().getFwdRow4(); - LLVector3 dirLeft = vec4to3( dirLeft4 ); - LLVector3 dirRight = vec4to3( dirRight4 ); - - LLVector3 up; - LLVector3 dir; - LLVector3 left; - - up = mNormalLeft; - up.normVec(); - if (mFlipFeet) - { - up *= -1.0f; - } - dir = dirLeft; - dir.normVec(); - left = up % dir; - left.normVec(); - dir = left % up; - mRotationLeft = LLQuaternion( dir, left, up ); - - up = mNormalRight; - up.normVec(); - if (mFlipFeet) - { - up *= -1.0f; - } - dir = dirRight; - dir.normVec(); - left = up % dir; - left.normVec(); - dir = left % up; - mRotationRight = LLQuaternion( dir, left, up ); - } - mAnkleLeftJoint.setWorldRotation( mRotationLeft ); - mAnkleRightJoint.setWorldRotation( mRotationRight ); - - //------------------------------------------------------------------------- - // propagate joint rotations to joint states - //------------------------------------------------------------------------- - mHipLeftState->setRotation( mHipLeftJoint.getRotation() ); - mKneeLeftState->setRotation( mKneeLeftJoint.getRotation() ); - mAnkleLeftState->setRotation( mAnkleLeftJoint.getRotation() ); - - mHipRightState->setRotation( mHipRightJoint.getRotation() ); - mKneeRightState->setRotation( mKneeRightJoint.getRotation() ); - mAnkleRightState->setRotation( mAnkleRightJoint.getRotation() ); - - //LL_INFOS() << "Stand drift amount " << (mCharacter->getCharacterPosition() - mLastGoodPosition).magVec() << LL_ENDL; - -// LL_INFOS() << "DEBUG: " << speed << " : " << mTrackAnkles << LL_ENDL; - return TRUE; + mTargetLeft.setPosition( mPositionLeft ); + mTargetRight.setPosition( mPositionRight ); + } + + //------------------------------------------------------------------------- + // update solvers + //------------------------------------------------------------------------- + mIKLeft.solve(); + mIKRight.solve(); + + //------------------------------------------------------------------------- + // make ankle rotation conform to the ground + //------------------------------------------------------------------------- + if ( mTrackAnkles ) + { + LLVector4 dirLeft4 = mAnkleLeftJoint.getWorldMatrix().getFwdRow4(); + LLVector4 dirRight4 = mAnkleRightJoint.getWorldMatrix().getFwdRow4(); + LLVector3 dirLeft = vec4to3( dirLeft4 ); + LLVector3 dirRight = vec4to3( dirRight4 ); + + LLVector3 up; + LLVector3 dir; + LLVector3 left; + + up = mNormalLeft; + up.normVec(); + if (mFlipFeet) + { + up *= -1.0f; + } + dir = dirLeft; + dir.normVec(); + left = up % dir; + left.normVec(); + dir = left % up; + mRotationLeft = LLQuaternion( dir, left, up ); + + up = mNormalRight; + up.normVec(); + if (mFlipFeet) + { + up *= -1.0f; + } + dir = dirRight; + dir.normVec(); + left = up % dir; + left.normVec(); + dir = left % up; + mRotationRight = LLQuaternion( dir, left, up ); + } + mAnkleLeftJoint.setWorldRotation( mRotationLeft ); + mAnkleRightJoint.setWorldRotation( mRotationRight ); + + //------------------------------------------------------------------------- + // propagate joint rotations to joint states + //------------------------------------------------------------------------- + mHipLeftState->setRotation( mHipLeftJoint.getRotation() ); + mKneeLeftState->setRotation( mKneeLeftJoint.getRotation() ); + mAnkleLeftState->setRotation( mAnkleLeftJoint.getRotation() ); + + mHipRightState->setRotation( mHipRightJoint.getRotation() ); + mKneeRightState->setRotation( mKneeRightJoint.getRotation() ); + mAnkleRightState->setRotation( mAnkleRightJoint.getRotation() ); + + //LL_INFOS() << "Stand drift amount " << (mCharacter->getCharacterPosition() - mLastGoodPosition).magVec() << LL_ENDL; + +// LL_INFOS() << "DEBUG: " << speed << " : " << mTrackAnkles << LL_ENDL; + return TRUE; } // End diff --git a/indra/llcharacter/llkeyframestandmotion.h b/indra/llcharacter/llkeyframestandmotion.h index 1aa5b187ba..2e3634828f 100644 --- a/indra/llcharacter/llkeyframestandmotion.h +++ b/indra/llcharacter/llkeyframestandmotion.h @@ -1,25 +1,25 @@ -/** +/** * @file llkeyframestandmotion.h * @brief Implementation of LLKeyframeStandMotion class. * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -39,79 +39,79 @@ //----------------------------------------------------------------------------- LL_ALIGN_PREFIX(16) class LLKeyframeStandMotion : - public LLKeyframeMotion + public LLKeyframeMotion { LL_ALIGN_NEW public: - // Constructor - LLKeyframeStandMotion(const LLUUID &id); + // Constructor + LLKeyframeStandMotion(const LLUUID &id); - // Destructor - virtual ~LLKeyframeStandMotion(); + // Destructor + virtual ~LLKeyframeStandMotion(); public: - //------------------------------------------------------------------------- - // functions to support MotionController and MotionRegistry - //------------------------------------------------------------------------- + //------------------------------------------------------------------------- + // functions to support MotionController and MotionRegistry + //------------------------------------------------------------------------- - // static constructor - // all subclasses must implement such a function and register it - static LLMotion *create(const LLUUID &id) { return new LLKeyframeStandMotion(id); } + // static constructor + // all subclasses must implement such a function and register it + static LLMotion *create(const LLUUID &id) { return new LLKeyframeStandMotion(id); } public: - //------------------------------------------------------------------------- - // animation callbacks to be implemented by subclasses - //------------------------------------------------------------------------- - virtual LLMotionInitStatus onInitialize(LLCharacter *character); - virtual BOOL onActivate(); - void onDeactivate(); - virtual BOOL onUpdate(F32 time, U8* joint_mask); + //------------------------------------------------------------------------- + // animation callbacks to be implemented by subclasses + //------------------------------------------------------------------------- + virtual LLMotionInitStatus onInitialize(LLCharacter *character); + virtual BOOL onActivate(); + void onDeactivate(); + virtual BOOL onUpdate(F32 time, U8* joint_mask); public: - //------------------------------------------------------------------------- - // Member Data - //------------------------------------------------------------------------- - LLJoint mPelvisJoint; + //------------------------------------------------------------------------- + // Member Data + //------------------------------------------------------------------------- + LLJoint mPelvisJoint; - LLJoint mHipLeftJoint; - LLJoint mKneeLeftJoint; - LLJoint mAnkleLeftJoint; - LLJoint mTargetLeft; + LLJoint mHipLeftJoint; + LLJoint mKneeLeftJoint; + LLJoint mAnkleLeftJoint; + LLJoint mTargetLeft; - LLJoint mHipRightJoint; - LLJoint mKneeRightJoint; - LLJoint mAnkleRightJoint; - LLJoint mTargetRight; + LLJoint mHipRightJoint; + LLJoint mKneeRightJoint; + LLJoint mAnkleRightJoint; + LLJoint mTargetRight; - LLCharacter *mCharacter; + LLCharacter *mCharacter; - BOOL mFlipFeet; + BOOL mFlipFeet; - LLPointer<LLJointState> mPelvisState; + LLPointer<LLJointState> mPelvisState; - LLPointer<LLJointState> mHipLeftState; - LLPointer<LLJointState> mKneeLeftState; - LLPointer<LLJointState> mAnkleLeftState; + LLPointer<LLJointState> mHipLeftState; + LLPointer<LLJointState> mKneeLeftState; + LLPointer<LLJointState> mAnkleLeftState; - LLPointer<LLJointState> mHipRightState; - LLPointer<LLJointState> mKneeRightState; - LLPointer<LLJointState> mAnkleRightState; + LLPointer<LLJointState> mHipRightState; + LLPointer<LLJointState> mKneeRightState; + LLPointer<LLJointState> mAnkleRightState; - LLJointSolverRP3 mIKLeft; - LLJointSolverRP3 mIKRight; + LLJointSolverRP3 mIKLeft; + LLJointSolverRP3 mIKRight; - LLVector3 mPositionLeft; - LLVector3 mPositionRight; - LLVector3 mNormalLeft; - LLVector3 mNormalRight; - LLQuaternion mRotationLeft; - LLQuaternion mRotationRight; + LLVector3 mPositionLeft; + LLVector3 mPositionRight; + LLVector3 mNormalLeft; + LLVector3 mNormalRight; + LLQuaternion mRotationLeft; + LLQuaternion mRotationRight; - LLQuaternion mLastGoodPelvisRotation; - LLVector3 mLastGoodPosition; - BOOL mTrackAnkles; + LLQuaternion mLastGoodPelvisRotation; + LLVector3 mLastGoodPosition; + BOOL mTrackAnkles; - S32 mFrameNum; + S32 mFrameNum; } LL_ALIGN_POSTFIX(16); #endif // LL_LLKEYFRAMESTANDMOTION_H diff --git a/indra/llcharacter/llkeyframewalkmotion.cpp b/indra/llcharacter/llkeyframewalkmotion.cpp index 298b37e60c..132fb85785 100644 --- a/indra/llcharacter/llkeyframewalkmotion.cpp +++ b/indra/llcharacter/llkeyframewalkmotion.cpp @@ -1,25 +1,25 @@ -/** +/** * @file llkeyframewalkmotion.cpp * @brief Implementation of LLKeyframeWalkMotion class. * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -38,22 +38,22 @@ //----------------------------------------------------------------------------- // Macros //----------------------------------------------------------------------------- -const F32 MAX_WALK_PLAYBACK_SPEED = 8.f; // max m/s for which we adjust walk cycle speed +const F32 MAX_WALK_PLAYBACK_SPEED = 8.f; // max m/s for which we adjust walk cycle speed -const F32 MIN_WALK_SPEED = 0.1f; // minimum speed at which we use velocity for down foot detection -const F32 TIME_EPSILON = 0.001f; // minumum frame time -const F32 MAX_TIME_DELTA = 2.f; // max two seconds a frame for calculating interpolation -F32 SPEED_ADJUST_MAX_SEC = 2.f; // maximum adjustment to walk animation playback speed for a second -F32 ANIM_SPEED_MAX = 1.5f; // absolute upper limit on animation speed +const F32 MIN_WALK_SPEED = 0.1f; // minimum speed at which we use velocity for down foot detection +const F32 TIME_EPSILON = 0.001f; // minumum frame time +const F32 MAX_TIME_DELTA = 2.f; // max two seconds a frame for calculating interpolation +F32 SPEED_ADJUST_MAX_SEC = 2.f; // maximum adjustment to walk animation playback speed for a second +F32 ANIM_SPEED_MAX = 1.5f; // absolute upper limit on animation speed const F32 MAX_ROLL = 0.6f; -const F32 SPEED_ADJUST_TIME_CONSTANT = 0.1f; // time constant for speed adjustment interpolation +const F32 SPEED_ADJUST_TIME_CONSTANT = 0.1f; // time constant for speed adjustment interpolation //----------------------------------------------------------------------------- // LLKeyframeWalkMotion() // Class Constructor //----------------------------------------------------------------------------- LLKeyframeWalkMotion::LLKeyframeWalkMotion(const LLUUID &id) -: LLKeyframeMotion(id), +: LLKeyframeMotion(id), mCharacter(NULL), mCyclePhase(0.0f), mRealTimeLast(0.0f), @@ -75,9 +75,9 @@ LLKeyframeWalkMotion::~LLKeyframeWalkMotion() //----------------------------------------------------------------------------- LLMotion::LLMotionInitStatus LLKeyframeWalkMotion::onInitialize(LLCharacter *character) { - mCharacter = character; + mCharacter = character; - return LLKeyframeMotion::onInitialize(character); + return LLKeyframeMotion::onInitialize(character); } //----------------------------------------------------------------------------- @@ -85,10 +85,10 @@ LLMotion::LLMotionInitStatus LLKeyframeWalkMotion::onInitialize(LLCharacter *cha //----------------------------------------------------------------------------- BOOL LLKeyframeWalkMotion::onActivate() { - mRealTimeLast = 0.0f; - mAdjTimeLast = 0.0f; + mRealTimeLast = 0.0f; + mAdjTimeLast = 0.0f; - return LLKeyframeMotion::onActivate(); + return LLKeyframeMotion::onActivate(); } //----------------------------------------------------------------------------- @@ -96,8 +96,8 @@ BOOL LLKeyframeWalkMotion::onActivate() //----------------------------------------------------------------------------- void LLKeyframeWalkMotion::onDeactivate() { - mCharacter->removeAnimationData("Down Foot"); - LLKeyframeMotion::onDeactivate(); + mCharacter->removeAnimationData("Down Foot"); + LLKeyframeMotion::onDeactivate(); } //----------------------------------------------------------------------------- @@ -106,27 +106,27 @@ void LLKeyframeWalkMotion::onDeactivate() BOOL LLKeyframeWalkMotion::onUpdate(F32 time, U8* joint_mask) { LL_PROFILE_ZONE_SCOPED; - // compute time since last update - F32 deltaTime = time - mRealTimeLast; + // compute time since last update + F32 deltaTime = time - mRealTimeLast; - void* speed_ptr = mCharacter->getAnimationData("Walk Speed"); - F32 speed = (speed_ptr) ? *((F32 *)speed_ptr) : 1.f; + void* speed_ptr = mCharacter->getAnimationData("Walk Speed"); + F32 speed = (speed_ptr) ? *((F32 *)speed_ptr) : 1.f; - // adjust the passage of time accordingly - F32 adjusted_time = mAdjTimeLast + (deltaTime * speed); + // adjust the passage of time accordingly + F32 adjusted_time = mAdjTimeLast + (deltaTime * speed); - // save time for next update - mRealTimeLast = time; - mAdjTimeLast = adjusted_time; + // save time for next update + mRealTimeLast = time; + mAdjTimeLast = adjusted_time; - // handle wrap around - if (adjusted_time < 0.0f) - { - adjusted_time = getDuration() + fmod(adjusted_time, getDuration()); - } + // handle wrap around + if (adjusted_time < 0.0f) + { + adjusted_time = getDuration() + fmod(adjusted_time, getDuration()); + } - // let the base class update the cycle - return LLKeyframeMotion::onUpdate( adjusted_time, joint_mask ); + // let the base class update the cycle + return LLKeyframeMotion::onUpdate( adjusted_time, joint_mask ); } // End @@ -137,15 +137,15 @@ BOOL LLKeyframeWalkMotion::onUpdate(F32 time, U8* joint_mask) // Class Constructor //----------------------------------------------------------------------------- LLWalkAdjustMotion::LLWalkAdjustMotion(const LLUUID &id) : - LLMotion(id), - mLastTime(0.f), - mAnimSpeed(0.f), - mAdjustedSpeed(0.f), - mRelativeDir(0.f), - mAnkleOffset(0.f) + LLMotion(id), + mLastTime(0.f), + mAnimSpeed(0.f), + mAdjustedSpeed(0.f), + mRelativeDir(0.f), + mAnkleOffset(0.f) { - mName = "walk_adjust"; - mPelvisState = new LLJointState; + mName = "walk_adjust"; + mPelvisState = new LLJointState; } //----------------------------------------------------------------------------- @@ -153,22 +153,22 @@ LLWalkAdjustMotion::LLWalkAdjustMotion(const LLUUID &id) : //----------------------------------------------------------------------------- LLMotion::LLMotionInitStatus LLWalkAdjustMotion::onInitialize(LLCharacter *character) { - mCharacter = character; - mLeftAnkleJoint = mCharacter->getJoint("mAnkleLeft"); - mRightAnkleJoint = mCharacter->getJoint("mAnkleRight"); - - mPelvisJoint = mCharacter->getJoint("mPelvis"); - mPelvisState->setJoint( mPelvisJoint ); - if ( !mPelvisJoint ) - { - LL_WARNS() << getName() << ": Can't get pelvis joint." << LL_ENDL; - return STATUS_FAILURE; - } - - mPelvisState->setUsage(LLJointState::POS); - addJointState( mPelvisState ); - - return STATUS_SUCCESS; + mCharacter = character; + mLeftAnkleJoint = mCharacter->getJoint("mAnkleLeft"); + mRightAnkleJoint = mCharacter->getJoint("mAnkleRight"); + + mPelvisJoint = mCharacter->getJoint("mPelvis"); + mPelvisState->setJoint( mPelvisJoint ); + if ( !mPelvisJoint ) + { + LL_WARNS() << getName() << ": Can't get pelvis joint." << LL_ENDL; + return STATUS_FAILURE; + } + + mPelvisState->setUsage(LLJointState::POS); + addJointState( mPelvisState ); + + return STATUS_SUCCESS; } //----------------------------------------------------------------------------- @@ -176,22 +176,22 @@ LLMotion::LLMotionInitStatus LLWalkAdjustMotion::onInitialize(LLCharacter *chara //----------------------------------------------------------------------------- BOOL LLWalkAdjustMotion::onActivate() { - mAnimSpeed = 0.f; - mAdjustedSpeed = 0.f; - mRelativeDir = 1.f; - mPelvisState->setPosition(LLVector3::zero); - // store ankle positions for next frame - mLastLeftFootGlobalPos = mCharacter->getPosGlobalFromAgent(mLeftAnkleJoint->getWorldPosition()); - mLastLeftFootGlobalPos.mdV[VZ] = 0.0; - - mLastRightFootGlobalPos = mCharacter->getPosGlobalFromAgent(mRightAnkleJoint->getWorldPosition()); - mLastRightFootGlobalPos.mdV[VZ] = 0.0; - - F32 leftAnkleOffset = (mLeftAnkleJoint->getWorldPosition() - mCharacter->getCharacterPosition()).magVec(); - F32 rightAnkleOffset = (mRightAnkleJoint->getWorldPosition() - mCharacter->getCharacterPosition()).magVec(); - mAnkleOffset = llmax(leftAnkleOffset, rightAnkleOffset); - - return TRUE; + mAnimSpeed = 0.f; + mAdjustedSpeed = 0.f; + mRelativeDir = 1.f; + mPelvisState->setPosition(LLVector3::zero); + // store ankle positions for next frame + mLastLeftFootGlobalPos = mCharacter->getPosGlobalFromAgent(mLeftAnkleJoint->getWorldPosition()); + mLastLeftFootGlobalPos.mdV[VZ] = 0.0; + + mLastRightFootGlobalPos = mCharacter->getPosGlobalFromAgent(mRightAnkleJoint->getWorldPosition()); + mLastRightFootGlobalPos.mdV[VZ] = 0.0; + + F32 leftAnkleOffset = (mLeftAnkleJoint->getWorldPosition() - mCharacter->getCharacterPosition()).magVec(); + F32 rightAnkleOffset = (mRightAnkleJoint->getWorldPosition() - mCharacter->getCharacterPosition()).magVec(); + mAnkleOffset = llmax(leftAnkleOffset, rightAnkleOffset); + + return TRUE; } //----------------------------------------------------------------------------- @@ -200,122 +200,122 @@ BOOL LLWalkAdjustMotion::onActivate() BOOL LLWalkAdjustMotion::onUpdate(F32 time, U8* joint_mask) { LL_PROFILE_ZONE_SCOPED; - // delta_time is guaranteed to be non zero - F32 delta_time = llclamp(time - mLastTime, TIME_EPSILON, MAX_TIME_DELTA); - mLastTime = time; - - // find the avatar motion vector in the XY plane - LLVector3 avatar_velocity = mCharacter->getCharacterVelocity() * mCharacter->getTimeDilation(); - avatar_velocity.mV[VZ] = 0.f; - - F32 speed = llclamp(avatar_velocity.magVec(), 0.f, MAX_WALK_PLAYBACK_SPEED); - - // grab avatar->world transforms - LLQuaternion avatar_to_world_rot = mCharacter->getRootJoint()->getWorldRotation(); - - LLQuaternion world_to_avatar_rot(avatar_to_world_rot); - world_to_avatar_rot.conjugate(); - - LLVector3 foot_slip_vector; - - // find foot drift along velocity vector - if (speed > MIN_WALK_SPEED) - { // walking/running - - // calculate world-space foot drift - // use global coordinates to seamlessly handle region crossings - LLVector3d leftFootGlobalPosition = mCharacter->getPosGlobalFromAgent(mLeftAnkleJoint->getWorldPosition()); - leftFootGlobalPosition.mdV[VZ] = 0.0; - LLVector3 leftFootDelta(leftFootGlobalPosition - mLastLeftFootGlobalPos); - mLastLeftFootGlobalPos = leftFootGlobalPosition; - - LLVector3d rightFootGlobalPosition = mCharacter->getPosGlobalFromAgent(mRightAnkleJoint->getWorldPosition()); - rightFootGlobalPosition.mdV[VZ] = 0.0; - LLVector3 rightFootDelta(rightFootGlobalPosition - mLastRightFootGlobalPos); - mLastRightFootGlobalPos = rightFootGlobalPosition; - - // get foot drift along avatar direction of motion - F32 left_foot_slip_amt = leftFootDelta * avatar_velocity; - F32 right_foot_slip_amt = rightFootDelta * avatar_velocity; - - // if right foot is pushing back faster than left foot... - if (right_foot_slip_amt < left_foot_slip_amt) - { //...use it to calculate optimal animation speed - foot_slip_vector = rightFootDelta; - } - else - { // otherwise use the left foot - foot_slip_vector = leftFootDelta; - } - - // calculate ideal pelvis offset so that foot is glued to ground and damp towards it - // this will soak up transient slippage - // - // FIXME: this interacts poorly with speed adjustment - // mPelvisOffset compensates for foot drift by moving the avatar pelvis in the opposite - // direction of the drift, up to a certain limited distance - // but this will cause the animation playback rate calculation below to - // kick in too slowly and sometimes start playing the animation in reverse. - - //mPelvisOffset -= PELVIS_COMPENSATION_WIEGHT * (foot_slip_vector * world_to_avatar_rot);//lerp(LLVector3::zero, -1.f * (foot_slip_vector * world_to_avatar_rot), LLSmoothInterpolation::getInterpolant(0.1f)); - - ////F32 drift_comp_max = DRIFT_COMP_MAX_TOTAL * (llclamp(speed, 0.f, DRIFT_COMP_MAX_SPEED) / DRIFT_COMP_MAX_SPEED); - //F32 drift_comp_max = DRIFT_COMP_MAX_TOTAL; - - //// clamp pelvis offset to a 90 degree arc behind the nominal position - //// NB: this is an ADDITIVE amount that is accumulated every frame, so clamping it alone won't do the trick - //// must clamp with absolute position of pelvis in mind - //LLVector3 currentPelvisPos = mPelvisState->getJoint()->getPosition(); - //mPelvisOffset.mV[VX] = llclamp( mPelvisOffset.mV[VX], -drift_comp_max, drift_comp_max ); - //mPelvisOffset.mV[VY] = llclamp( mPelvisOffset.mV[VY], -drift_comp_max, drift_comp_max ); - //mPelvisOffset.mV[VZ] = 0.f; - // - //mLastRightFootGlobalPos += LLVector3d(mPelvisOffset * avatar_to_world_rot); - //mLastLeftFootGlobalPos += LLVector3d(mPelvisOffset * avatar_to_world_rot); - - //foot_slip_vector -= mPelvisOffset; - - LLVector3 avatar_movement_dir = avatar_velocity; - avatar_movement_dir.normalize(); - - // planted foot speed is avatar velocity - foot slip amount along avatar movement direction - F32 foot_speed = speed - ((foot_slip_vector * avatar_movement_dir) / delta_time); - - // multiply animation playback rate so that foot speed matches avatar speed - F32 min_speed_multiplier = clamp_rescale(speed, 0.f, 1.f, 0.f, 0.1f); - F32 desired_speed_multiplier = llclamp(speed / foot_speed, min_speed_multiplier, ANIM_SPEED_MAX); - - // blend towards new speed adjustment value - F32 new_speed_adjust = LLSmoothInterpolation::lerp(mAdjustedSpeed, desired_speed_multiplier, SPEED_ADJUST_TIME_CONSTANT); - - // limit that rate at which the speed adjustment changes - F32 speedDelta = llclamp(new_speed_adjust - mAdjustedSpeed, -SPEED_ADJUST_MAX_SEC * delta_time, SPEED_ADJUST_MAX_SEC * delta_time); - mAdjustedSpeed += speedDelta; - - // modulate speed by dot products of facing and velocity - // so that if we are moving sideways, we slow down the animation - // and if we're moving backward, we walk backward - // do this at the end to be more responsive to direction changes instead of in the above speed calculations - F32 directional_factor = (avatar_movement_dir * world_to_avatar_rot).mV[VX]; - - mAnimSpeed = mAdjustedSpeed * directional_factor; - } - else - { // standing/turning - - // damp out speed adjustment to 0 - mAnimSpeed = LLSmoothInterpolation::lerp(mAnimSpeed, 1.f, 0.2f); - //mPelvisOffset = lerp(mPelvisOffset, LLVector3::zero, LLSmoothInterpolation::getInterpolant(0.2f)); - } - - // broadcast walk speed change - mCharacter->setAnimationData("Walk Speed", &mAnimSpeed); - - // set position - // need to update *some* joint to keep this animation active - mPelvisState->setPosition(mPelvisOffset); - - return TRUE; + // delta_time is guaranteed to be non zero + F32 delta_time = llclamp(time - mLastTime, TIME_EPSILON, MAX_TIME_DELTA); + mLastTime = time; + + // find the avatar motion vector in the XY plane + LLVector3 avatar_velocity = mCharacter->getCharacterVelocity() * mCharacter->getTimeDilation(); + avatar_velocity.mV[VZ] = 0.f; + + F32 speed = llclamp(avatar_velocity.magVec(), 0.f, MAX_WALK_PLAYBACK_SPEED); + + // grab avatar->world transforms + LLQuaternion avatar_to_world_rot = mCharacter->getRootJoint()->getWorldRotation(); + + LLQuaternion world_to_avatar_rot(avatar_to_world_rot); + world_to_avatar_rot.conjugate(); + + LLVector3 foot_slip_vector; + + // find foot drift along velocity vector + if (speed > MIN_WALK_SPEED) + { // walking/running + + // calculate world-space foot drift + // use global coordinates to seamlessly handle region crossings + LLVector3d leftFootGlobalPosition = mCharacter->getPosGlobalFromAgent(mLeftAnkleJoint->getWorldPosition()); + leftFootGlobalPosition.mdV[VZ] = 0.0; + LLVector3 leftFootDelta(leftFootGlobalPosition - mLastLeftFootGlobalPos); + mLastLeftFootGlobalPos = leftFootGlobalPosition; + + LLVector3d rightFootGlobalPosition = mCharacter->getPosGlobalFromAgent(mRightAnkleJoint->getWorldPosition()); + rightFootGlobalPosition.mdV[VZ] = 0.0; + LLVector3 rightFootDelta(rightFootGlobalPosition - mLastRightFootGlobalPos); + mLastRightFootGlobalPos = rightFootGlobalPosition; + + // get foot drift along avatar direction of motion + F32 left_foot_slip_amt = leftFootDelta * avatar_velocity; + F32 right_foot_slip_amt = rightFootDelta * avatar_velocity; + + // if right foot is pushing back faster than left foot... + if (right_foot_slip_amt < left_foot_slip_amt) + { //...use it to calculate optimal animation speed + foot_slip_vector = rightFootDelta; + } + else + { // otherwise use the left foot + foot_slip_vector = leftFootDelta; + } + + // calculate ideal pelvis offset so that foot is glued to ground and damp towards it + // this will soak up transient slippage + // + // FIXME: this interacts poorly with speed adjustment + // mPelvisOffset compensates for foot drift by moving the avatar pelvis in the opposite + // direction of the drift, up to a certain limited distance + // but this will cause the animation playback rate calculation below to + // kick in too slowly and sometimes start playing the animation in reverse. + + //mPelvisOffset -= PELVIS_COMPENSATION_WIEGHT * (foot_slip_vector * world_to_avatar_rot);//lerp(LLVector3::zero, -1.f * (foot_slip_vector * world_to_avatar_rot), LLSmoothInterpolation::getInterpolant(0.1f)); + + ////F32 drift_comp_max = DRIFT_COMP_MAX_TOTAL * (llclamp(speed, 0.f, DRIFT_COMP_MAX_SPEED) / DRIFT_COMP_MAX_SPEED); + //F32 drift_comp_max = DRIFT_COMP_MAX_TOTAL; + + //// clamp pelvis offset to a 90 degree arc behind the nominal position + //// NB: this is an ADDITIVE amount that is accumulated every frame, so clamping it alone won't do the trick + //// must clamp with absolute position of pelvis in mind + //LLVector3 currentPelvisPos = mPelvisState->getJoint()->getPosition(); + //mPelvisOffset.mV[VX] = llclamp( mPelvisOffset.mV[VX], -drift_comp_max, drift_comp_max ); + //mPelvisOffset.mV[VY] = llclamp( mPelvisOffset.mV[VY], -drift_comp_max, drift_comp_max ); + //mPelvisOffset.mV[VZ] = 0.f; + // + //mLastRightFootGlobalPos += LLVector3d(mPelvisOffset * avatar_to_world_rot); + //mLastLeftFootGlobalPos += LLVector3d(mPelvisOffset * avatar_to_world_rot); + + //foot_slip_vector -= mPelvisOffset; + + LLVector3 avatar_movement_dir = avatar_velocity; + avatar_movement_dir.normalize(); + + // planted foot speed is avatar velocity - foot slip amount along avatar movement direction + F32 foot_speed = speed - ((foot_slip_vector * avatar_movement_dir) / delta_time); + + // multiply animation playback rate so that foot speed matches avatar speed + F32 min_speed_multiplier = clamp_rescale(speed, 0.f, 1.f, 0.f, 0.1f); + F32 desired_speed_multiplier = llclamp(speed / foot_speed, min_speed_multiplier, ANIM_SPEED_MAX); + + // blend towards new speed adjustment value + F32 new_speed_adjust = LLSmoothInterpolation::lerp(mAdjustedSpeed, desired_speed_multiplier, SPEED_ADJUST_TIME_CONSTANT); + + // limit that rate at which the speed adjustment changes + F32 speedDelta = llclamp(new_speed_adjust - mAdjustedSpeed, -SPEED_ADJUST_MAX_SEC * delta_time, SPEED_ADJUST_MAX_SEC * delta_time); + mAdjustedSpeed += speedDelta; + + // modulate speed by dot products of facing and velocity + // so that if we are moving sideways, we slow down the animation + // and if we're moving backward, we walk backward + // do this at the end to be more responsive to direction changes instead of in the above speed calculations + F32 directional_factor = (avatar_movement_dir * world_to_avatar_rot).mV[VX]; + + mAnimSpeed = mAdjustedSpeed * directional_factor; + } + else + { // standing/turning + + // damp out speed adjustment to 0 + mAnimSpeed = LLSmoothInterpolation::lerp(mAnimSpeed, 1.f, 0.2f); + //mPelvisOffset = lerp(mPelvisOffset, LLVector3::zero, LLSmoothInterpolation::getInterpolant(0.2f)); + } + + // broadcast walk speed change + mCharacter->setAnimationData("Walk Speed", &mAnimSpeed); + + // set position + // need to update *some* joint to keep this animation active + mPelvisState->setPosition(mPelvisOffset); + + return TRUE; } //----------------------------------------------------------------------------- @@ -323,19 +323,19 @@ BOOL LLWalkAdjustMotion::onUpdate(F32 time, U8* joint_mask) //----------------------------------------------------------------------------- void LLWalkAdjustMotion::onDeactivate() { - mCharacter->removeAnimationData("Walk Speed"); + mCharacter->removeAnimationData("Walk Speed"); } //----------------------------------------------------------------------------- // LLFlyAdjustMotion::LLFlyAdjustMotion() //----------------------------------------------------------------------------- LLFlyAdjustMotion::LLFlyAdjustMotion(const LLUUID &id) - : LLMotion(id), - mRoll(0.f) + : LLMotion(id), + mRoll(0.f) { - mName = "fly_adjust"; + mName = "fly_adjust"; - mPelvisState = new LLJointState; + mPelvisState = new LLJointState; } //----------------------------------------------------------------------------- @@ -343,20 +343,20 @@ LLFlyAdjustMotion::LLFlyAdjustMotion(const LLUUID &id) //----------------------------------------------------------------------------- LLMotion::LLMotionInitStatus LLFlyAdjustMotion::onInitialize(LLCharacter *character) { - mCharacter = character; + mCharacter = character; - LLJoint* pelvisJoint = mCharacter->getJoint("mPelvis"); - mPelvisState->setJoint( pelvisJoint ); - if ( !pelvisJoint ) - { - LL_WARNS() << getName() << ": Can't get pelvis joint." << LL_ENDL; - return STATUS_FAILURE; - } + LLJoint* pelvisJoint = mCharacter->getJoint("mPelvis"); + mPelvisState->setJoint( pelvisJoint ); + if ( !pelvisJoint ) + { + LL_WARNS() << getName() << ": Can't get pelvis joint." << LL_ENDL; + return STATUS_FAILURE; + } - mPelvisState->setUsage(LLJointState::POS | LLJointState::ROT); - addJointState( mPelvisState ); + mPelvisState->setUsage(LLJointState::POS | LLJointState::ROT); + addJointState( mPelvisState ); - return STATUS_SUCCESS; + return STATUS_SUCCESS; } //----------------------------------------------------------------------------- @@ -364,10 +364,10 @@ LLMotion::LLMotionInitStatus LLFlyAdjustMotion::onInitialize(LLCharacter *charac //----------------------------------------------------------------------------- BOOL LLFlyAdjustMotion::onActivate() { - mPelvisState->setPosition(LLVector3::zero); - mPelvisState->setRotation(LLQuaternion::DEFAULT); - mRoll = 0.f; - return TRUE; + mPelvisState->setPosition(LLVector3::zero); + mPelvisState->setRotation(LLQuaternion::DEFAULT); + mRoll = 0.f; + return TRUE; } //----------------------------------------------------------------------------- @@ -376,18 +376,18 @@ BOOL LLFlyAdjustMotion::onActivate() BOOL LLFlyAdjustMotion::onUpdate(F32 time, U8* joint_mask) { LL_PROFILE_ZONE_SCOPED; - LLVector3 ang_vel = mCharacter->getCharacterAngularVelocity() * mCharacter->getTimeDilation(); - F32 speed = mCharacter->getCharacterVelocity().magVec(); + LLVector3 ang_vel = mCharacter->getCharacterAngularVelocity() * mCharacter->getTimeDilation(); + F32 speed = mCharacter->getCharacterVelocity().magVec(); - F32 roll_factor = clamp_rescale(speed, 7.f, 15.f, 0.f, -MAX_ROLL); - F32 target_roll = llclamp(ang_vel.mV[VZ], -4.f, 4.f) * roll_factor; + F32 roll_factor = clamp_rescale(speed, 7.f, 15.f, 0.f, -MAX_ROLL); + F32 target_roll = llclamp(ang_vel.mV[VZ], -4.f, 4.f) * roll_factor; - // roll is critically damped interpolation between current roll and angular velocity-derived target roll - mRoll = LLSmoothInterpolation::lerp(mRoll, target_roll, U32Milliseconds(100)); + // roll is critically damped interpolation between current roll and angular velocity-derived target roll + mRoll = LLSmoothInterpolation::lerp(mRoll, target_roll, U32Milliseconds(100)); - LLQuaternion roll(mRoll, LLVector3(0.f, 0.f, 1.f)); - mPelvisState->setRotation(roll); + LLQuaternion roll(mRoll, LLVector3(0.f, 0.f, 1.f)); + mPelvisState->setRotation(roll); - return TRUE; + return TRUE; } diff --git a/indra/llcharacter/llkeyframewalkmotion.h b/indra/llcharacter/llkeyframewalkmotion.h index 0e8d21b765..110dbeeee3 100644 --- a/indra/llcharacter/llkeyframewalkmotion.h +++ b/indra/llcharacter/llkeyframewalkmotion.h @@ -1,25 +1,25 @@ -/** +/** * @file llkeyframewalkmotion.h * @brief Implementation of LLKeframeWalkMotion class. * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -41,133 +41,133 @@ // class LLKeyframeWalkMotion //----------------------------------------------------------------------------- class LLKeyframeWalkMotion : - public LLKeyframeMotion + public LLKeyframeMotion { - friend class LLWalkAdjustMotion; + friend class LLWalkAdjustMotion; public: - // Constructor - LLKeyframeWalkMotion(const LLUUID &id); + // Constructor + LLKeyframeWalkMotion(const LLUUID &id); - // Destructor - virtual ~LLKeyframeWalkMotion(); + // Destructor + virtual ~LLKeyframeWalkMotion(); public: - //------------------------------------------------------------------------- - // functions to support MotionController and MotionRegistry - //------------------------------------------------------------------------- - - // static constructor - // all subclasses must implement such a function and register it - static LLMotion *create(const LLUUID &id) { return new LLKeyframeWalkMotion(id); } + //------------------------------------------------------------------------- + // functions to support MotionController and MotionRegistry + //------------------------------------------------------------------------- + + // static constructor + // all subclasses must implement such a function and register it + static LLMotion *create(const LLUUID &id) { return new LLKeyframeWalkMotion(id); } public: - //------------------------------------------------------------------------- - // animation callbacks to be implemented by subclasses - //------------------------------------------------------------------------- - virtual LLMotionInitStatus onInitialize(LLCharacter *character); - virtual BOOL onActivate(); - virtual void onDeactivate(); - virtual BOOL onUpdate(F32 time, U8* joint_mask); + //------------------------------------------------------------------------- + // animation callbacks to be implemented by subclasses + //------------------------------------------------------------------------- + virtual LLMotionInitStatus onInitialize(LLCharacter *character); + virtual BOOL onActivate(); + virtual void onDeactivate(); + virtual BOOL onUpdate(F32 time, U8* joint_mask); public: - //------------------------------------------------------------------------- - // Member Data - //------------------------------------------------------------------------- - LLCharacter *mCharacter; - F32 mCyclePhase; - F32 mRealTimeLast; - F32 mAdjTimeLast; - S32 mDownFoot; + //------------------------------------------------------------------------- + // Member Data + //------------------------------------------------------------------------- + LLCharacter *mCharacter; + F32 mCyclePhase; + F32 mRealTimeLast; + F32 mAdjTimeLast; + S32 mDownFoot; }; class LLWalkAdjustMotion : public LLMotion { public: - // Constructor - LLWalkAdjustMotion(const LLUUID &id); + // Constructor + LLWalkAdjustMotion(const LLUUID &id); public: - //------------------------------------------------------------------------- - // functions to support MotionController and MotionRegistry - //------------------------------------------------------------------------- + //------------------------------------------------------------------------- + // functions to support MotionController and MotionRegistry + //------------------------------------------------------------------------- - // static constructor - // all subclasses must implement such a function and register it - static LLMotion *create(const LLUUID &id) { return new LLWalkAdjustMotion(id); } + // static constructor + // all subclasses must implement such a function and register it + static LLMotion *create(const LLUUID &id) { return new LLWalkAdjustMotion(id); } public: - //------------------------------------------------------------------------- - // animation callbacks to be implemented by subclasses - //------------------------------------------------------------------------- - virtual LLMotionInitStatus onInitialize(LLCharacter *character); - virtual BOOL onActivate(); - virtual void onDeactivate(); - virtual BOOL onUpdate(F32 time, U8* joint_mask); - virtual LLJoint::JointPriority getPriority(){return LLJoint::HIGH_PRIORITY;} - virtual BOOL getLoop() { return TRUE; } - virtual F32 getDuration() { return 0.f; } - virtual F32 getEaseInDuration() { return 0.f; } - virtual F32 getEaseOutDuration() { return 0.f; } - virtual F32 getMinPixelArea() { return MIN_REQUIRED_PIXEL_AREA_WALK_ADJUST; } - virtual LLMotionBlendType getBlendType() { return ADDITIVE_BLEND; } + //------------------------------------------------------------------------- + // animation callbacks to be implemented by subclasses + //------------------------------------------------------------------------- + virtual LLMotionInitStatus onInitialize(LLCharacter *character); + virtual BOOL onActivate(); + virtual void onDeactivate(); + virtual BOOL onUpdate(F32 time, U8* joint_mask); + virtual LLJoint::JointPriority getPriority(){return LLJoint::HIGH_PRIORITY;} + virtual BOOL getLoop() { return TRUE; } + virtual F32 getDuration() { return 0.f; } + virtual F32 getEaseInDuration() { return 0.f; } + virtual F32 getEaseOutDuration() { return 0.f; } + virtual F32 getMinPixelArea() { return MIN_REQUIRED_PIXEL_AREA_WALK_ADJUST; } + virtual LLMotionBlendType getBlendType() { return ADDITIVE_BLEND; } public: - //------------------------------------------------------------------------- - // Member Data - //------------------------------------------------------------------------- - LLCharacter *mCharacter; - LLJoint* mLeftAnkleJoint; - LLJoint* mRightAnkleJoint; - LLPointer<LLJointState> mPelvisState; - LLJoint* mPelvisJoint; - LLVector3d mLastLeftFootGlobalPos; - LLVector3d mLastRightFootGlobalPos; - F32 mLastTime; - F32 mAdjustedSpeed; - F32 mAnimSpeed; - F32 mRelativeDir; - LLVector3 mPelvisOffset; - F32 mAnkleOffset; + //------------------------------------------------------------------------- + // Member Data + //------------------------------------------------------------------------- + LLCharacter *mCharacter; + LLJoint* mLeftAnkleJoint; + LLJoint* mRightAnkleJoint; + LLPointer<LLJointState> mPelvisState; + LLJoint* mPelvisJoint; + LLVector3d mLastLeftFootGlobalPos; + LLVector3d mLastRightFootGlobalPos; + F32 mLastTime; + F32 mAdjustedSpeed; + F32 mAnimSpeed; + F32 mRelativeDir; + LLVector3 mPelvisOffset; + F32 mAnkleOffset; }; class LLFlyAdjustMotion : public LLMotion { public: - // Constructor - LLFlyAdjustMotion(const LLUUID &id); + // Constructor + LLFlyAdjustMotion(const LLUUID &id); public: - //------------------------------------------------------------------------- - // functions to support MotionController and MotionRegistry - //------------------------------------------------------------------------- + //------------------------------------------------------------------------- + // functions to support MotionController and MotionRegistry + //------------------------------------------------------------------------- - // static constructor - // all subclasses must implement such a function and register it - static LLMotion *create(const LLUUID &id) { return new LLFlyAdjustMotion(id); } + // static constructor + // all subclasses must implement such a function and register it + static LLMotion *create(const LLUUID &id) { return new LLFlyAdjustMotion(id); } public: - //------------------------------------------------------------------------- - // animation callbacks to be implemented by subclasses - //------------------------------------------------------------------------- - virtual LLMotionInitStatus onInitialize(LLCharacter *character); - virtual BOOL onActivate(); - virtual void onDeactivate() {}; - virtual BOOL onUpdate(F32 time, U8* joint_mask); - virtual LLJoint::JointPriority getPriority(){return LLJoint::HIGHER_PRIORITY;} - virtual BOOL getLoop() { return TRUE; } - virtual F32 getDuration() { return 0.f; } - virtual F32 getEaseInDuration() { return 0.f; } - virtual F32 getEaseOutDuration() { return 0.f; } - virtual F32 getMinPixelArea() { return MIN_REQUIRED_PIXEL_AREA_FLY_ADJUST; } - virtual LLMotionBlendType getBlendType() { return ADDITIVE_BLEND; } + //------------------------------------------------------------------------- + // animation callbacks to be implemented by subclasses + //------------------------------------------------------------------------- + virtual LLMotionInitStatus onInitialize(LLCharacter *character); + virtual BOOL onActivate(); + virtual void onDeactivate() {}; + virtual BOOL onUpdate(F32 time, U8* joint_mask); + virtual LLJoint::JointPriority getPriority(){return LLJoint::HIGHER_PRIORITY;} + virtual BOOL getLoop() { return TRUE; } + virtual F32 getDuration() { return 0.f; } + virtual F32 getEaseInDuration() { return 0.f; } + virtual F32 getEaseOutDuration() { return 0.f; } + virtual F32 getMinPixelArea() { return MIN_REQUIRED_PIXEL_AREA_FLY_ADJUST; } + virtual LLMotionBlendType getBlendType() { return ADDITIVE_BLEND; } protected: - //------------------------------------------------------------------------- - // Member Data - //------------------------------------------------------------------------- - LLCharacter *mCharacter; - LLPointer<LLJointState> mPelvisState; - F32 mRoll; + //------------------------------------------------------------------------- + // Member Data + //------------------------------------------------------------------------- + LLCharacter *mCharacter; + LLPointer<LLJointState> mPelvisState; + F32 mRoll; }; #endif // LL_LLKeyframeWalkMotion_H diff --git a/indra/llcharacter/llmotion.cpp b/indra/llcharacter/llmotion.cpp index 697efc8157..0e0df26b04 100644 --- a/indra/llcharacter/llmotion.cpp +++ b/indra/llcharacter/llmotion.cpp @@ -1,25 +1,25 @@ -/** +/** * @file llmotion.cpp * @brief Implementation of LLMotion class. * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -43,19 +43,19 @@ // Class Constructor //----------------------------------------------------------------------------- LLMotion::LLMotion( const LLUUID &id ) : - mStopped(TRUE), - mActive(FALSE), - mID(id), - mActivationTimestamp(0.f), - mStopTimestamp(0.f), - mSendStopTimestamp(F32_MAX), - mResidualWeight(0.f), - mFadeWeight(1.f), - mDeactivateCallback(NULL), - mDeactivateCallbackUserData(NULL) + mStopped(TRUE), + mActive(FALSE), + mID(id), + mActivationTimestamp(0.f), + mStopTimestamp(0.f), + mSendStopTimestamp(F32_MAX), + mResidualWeight(0.f), + mFadeWeight(1.f), + mDeactivateCallback(NULL), + mDeactivateCallbackUserData(NULL) { - for (S32 i=0; i<3; ++i) - memset(&mJointSignature[i][0], 0, sizeof(U8) * LL_CHARACTER_MAX_ANIMATED_JOINTS); + for (S32 i=0; i<3; ++i) + memset(&mJointSignature[i][0], 0, sizeof(U8) * LL_CHARACTER_MAX_ANIMATED_JOINTS); } //----------------------------------------------------------------------------- @@ -71,14 +71,14 @@ LLMotion::~LLMotion() //----------------------------------------------------------------------------- void LLMotion::fadeOut() { - if (mFadeWeight > 0.01f) - { - mFadeWeight = lerp(mFadeWeight, 0.f, LLSmoothInterpolation::getInterpolant(0.15f)); - } - else - { - mFadeWeight = 0.f; - } + if (mFadeWeight > 0.01f) + { + mFadeWeight = lerp(mFadeWeight, 0.f, LLSmoothInterpolation::getInterpolant(0.15f)); + } + else + { + mFadeWeight = 0.f; + } } //----------------------------------------------------------------------------- @@ -86,14 +86,14 @@ void LLMotion::fadeOut() //----------------------------------------------------------------------------- void LLMotion::fadeIn() { - if (mFadeWeight < 0.99f) - { - mFadeWeight = lerp(mFadeWeight, 1.f, LLSmoothInterpolation::getInterpolant(0.15f)); - } - else - { - mFadeWeight = 1.f; - } + if (mFadeWeight < 0.99f) + { + mFadeWeight = lerp(mFadeWeight, 1.f, LLSmoothInterpolation::getInterpolant(0.15f)); + } + else + { + mFadeWeight = 1.f; + } } //----------------------------------------------------------------------------- @@ -101,43 +101,43 @@ void LLMotion::fadeIn() //----------------------------------------------------------------------------- void LLMotion::addJointState(const LLPointer<LLJointState>& jointState) { - mPose.addJointState(jointState); - S32 priority = jointState->getPriority(); - if (priority == LLJoint::USE_MOTION_PRIORITY) - { - priority = getPriority(); - } + mPose.addJointState(jointState); + S32 priority = jointState->getPriority(); + if (priority == LLJoint::USE_MOTION_PRIORITY) + { + priority = getPriority(); + } - U32 usage = jointState->getUsage(); + U32 usage = jointState->getUsage(); - // for now, usage is everything + // for now, usage is everything S32 joint_num = jointState->getJoint()->getJointNum(); if ((joint_num >= (S32)LL_CHARACTER_MAX_ANIMATED_JOINTS) || (joint_num < 0)) { LL_WARNS() << "joint_num " << joint_num << " is outside of legal range [0-" << LL_CHARACTER_MAX_ANIMATED_JOINTS << ") for joint " << jointState->getJoint()->getName() << LL_ENDL; return; } - mJointSignature[0][joint_num] = (usage & LLJointState::POS) ? (0xff >> (7 - priority)) : 0; - mJointSignature[1][joint_num] = (usage & LLJointState::ROT) ? (0xff >> (7 - priority)) : 0; - mJointSignature[2][joint_num] = (usage & LLJointState::SCALE) ? (0xff >> (7 - priority)) : 0; + mJointSignature[0][joint_num] = (usage & LLJointState::POS) ? (0xff >> (7 - priority)) : 0; + mJointSignature[1][joint_num] = (usage & LLJointState::ROT) ? (0xff >> (7 - priority)) : 0; + mJointSignature[2][joint_num] = (usage & LLJointState::SCALE) ? (0xff >> (7 - priority)) : 0; } void LLMotion::setDeactivateCallback( void (*cb)(void *), void* userdata ) { - mDeactivateCallback = cb; - mDeactivateCallbackUserData = userdata; + mDeactivateCallback = cb; + mDeactivateCallbackUserData = userdata; } //virtual void LLMotion::setStopTime(F32 time) { - mStopTimestamp = time; - mStopped = TRUE; + mStopTimestamp = time; + mStopped = TRUE; } BOOL LLMotion::isBlending() { - return mPose.getWeight() < 1.f; + return mPose.getWeight() < 1.f; } //----------------------------------------------------------------------------- @@ -145,10 +145,10 @@ BOOL LLMotion::isBlending() //----------------------------------------------------------------------------- void LLMotion::activate(F32 time) { - mActivationTimestamp = time; - mStopped = FALSE; - mActive = TRUE; - onActivate(); + mActivationTimestamp = time; + mStopped = FALSE; + mActive = TRUE; + onActivate(); } //----------------------------------------------------------------------------- @@ -156,22 +156,22 @@ void LLMotion::activate(F32 time) //----------------------------------------------------------------------------- void LLMotion::deactivate() { - mActive = FALSE; - mPose.setWeight(0.f); + mActive = FALSE; + mPose.setWeight(0.f); - if (mDeactivateCallback) - { - (*mDeactivateCallback)(mDeactivateCallbackUserData); - mDeactivateCallback = NULL; // only call callback once - mDeactivateCallbackUserData = NULL; - } + if (mDeactivateCallback) + { + (*mDeactivateCallback)(mDeactivateCallbackUserData); + mDeactivateCallback = NULL; // only call callback once + mDeactivateCallbackUserData = NULL; + } - onDeactivate(); + onDeactivate(); } BOOL LLMotion::canDeprecate() { - return TRUE; + return TRUE; } // End diff --git a/indra/llcharacter/llmotion.h b/indra/llcharacter/llmotion.h index aaa9a146d7..d45b8bceb6 100644 --- a/indra/llcharacter/llmotion.h +++ b/indra/llcharacter/llmotion.h @@ -1,25 +1,25 @@ -/** +/** * @file llmotion.h * @brief Implementation of LLMotion class. * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -43,150 +43,150 @@ class LLCharacter; //----------------------------------------------------------------------------- class LLMotion { - friend class LLMotionController; - + friend class LLMotionController; + public: - enum LLMotionBlendType - { - NORMAL_BLEND, - ADDITIVE_BLEND - }; + enum LLMotionBlendType + { + NORMAL_BLEND, + ADDITIVE_BLEND + }; - enum LLMotionInitStatus - { - STATUS_FAILURE, - STATUS_SUCCESS, - STATUS_HOLD - }; + enum LLMotionInitStatus + { + STATUS_FAILURE, + STATUS_SUCCESS, + STATUS_HOLD + }; - // Constructor - LLMotion(const LLUUID &id); + // Constructor + LLMotion(const LLUUID &id); - // Destructor - virtual ~LLMotion(); + // Destructor + virtual ~LLMotion(); public: - //------------------------------------------------------------------------- - // functions to support MotionController and MotionRegistry - //------------------------------------------------------------------------- + //------------------------------------------------------------------------- + // functions to support MotionController and MotionRegistry + //------------------------------------------------------------------------- - // get the name of this instance - const std::string &getName() const { return mName; } + // get the name of this instance + const std::string &getName() const { return mName; } - // set the name of this instance - void setName(const std::string &name) { mName = name; } + // set the name of this instance + void setName(const std::string &name) { mName = name; } - const LLUUID& getID() const { return mID; } + const LLUUID& getID() const { return mID; } - // returns the pose associated with the current state of this motion - virtual LLPose* getPose() { return &mPose;} + // returns the pose associated with the current state of this motion + virtual LLPose* getPose() { return &mPose;} - void fadeOut(); + void fadeOut(); - void fadeIn(); + void fadeIn(); - F32 getFadeWeight() const { return mFadeWeight; } + F32 getFadeWeight() const { return mFadeWeight; } - F32 getStopTime() const { return mStopTimestamp; } + F32 getStopTime() const { return mStopTimestamp; } - virtual void setStopTime(F32 time); + virtual void setStopTime(F32 time); - BOOL isStopped() const { return mStopped; } + BOOL isStopped() const { return mStopped; } - void setStopped(BOOL stopped) { mStopped = stopped; } + void setStopped(BOOL stopped) { mStopped = stopped; } - BOOL isBlending(); + BOOL isBlending(); - // Activation functions. - // It is OK for other classes to activate a motion, - // but only the controller can deactivate it. - // Thus, if mActive == TRUE, the motion *may* be on the controllers active list, - // but if mActive == FALSE, the motion is gauranteed not to be on the active list. + // Activation functions. + // It is OK for other classes to activate a motion, + // but only the controller can deactivate it. + // Thus, if mActive == TRUE, the motion *may* be on the controllers active list, + // but if mActive == FALSE, the motion is gauranteed not to be on the active list. protected: - // Used by LLMotionController only - void deactivate(); - BOOL isActive() { return mActive; } + // Used by LLMotionController only + void deactivate(); + BOOL isActive() { return mActive; } public: - void activate(F32 time); - + void activate(F32 time); + public: - //------------------------------------------------------------------------- - // animation callbacks to be implemented by subclasses - //------------------------------------------------------------------------- + //------------------------------------------------------------------------- + // animation callbacks to be implemented by subclasses + //------------------------------------------------------------------------- - // motions must specify whether or not they loop - virtual BOOL getLoop() = 0; + // motions must specify whether or not they loop + virtual BOOL getLoop() = 0; - // motions must report their total duration - virtual F32 getDuration() = 0; + // motions must report their total duration + virtual F32 getDuration() = 0; - // motions must report their "ease in" duration - virtual F32 getEaseInDuration() = 0; + // motions must report their "ease in" duration + virtual F32 getEaseInDuration() = 0; - // motions must report their "ease out" duration. - virtual F32 getEaseOutDuration() = 0; + // motions must report their "ease out" duration. + virtual F32 getEaseOutDuration() = 0; - // motions must report their priority level - virtual LLJoint::JointPriority getPriority() = 0; + // motions must report their priority level + virtual LLJoint::JointPriority getPriority() = 0; - // amount of affected joints - virtual S32 getNumJointMotions() { return 0; }; + // amount of affected joints + virtual S32 getNumJointMotions() { return 0; }; - // motions must report their blend type - virtual LLMotionBlendType getBlendType() = 0; + // motions must report their blend type + virtual LLMotionBlendType getBlendType() = 0; - // called to determine when a motion should be activated/deactivated based on avatar pixel coverage - virtual F32 getMinPixelArea() = 0; + // called to determine when a motion should be activated/deactivated based on avatar pixel coverage + virtual F32 getMinPixelArea() = 0; - // run-time (post constructor) initialization, - // called after parameters have been set - // must return true to indicate success and be available for activation - virtual LLMotionInitStatus onInitialize(LLCharacter *character) = 0; + // run-time (post constructor) initialization, + // called after parameters have been set + // must return true to indicate success and be available for activation + virtual LLMotionInitStatus onInitialize(LLCharacter *character) = 0; - // called per time step - // must return TRUE while it is active, and - // must return FALSE when the motion is completed. - virtual BOOL onUpdate(F32 activeTime, U8* joint_mask) = 0; + // called per time step + // must return TRUE while it is active, and + // must return FALSE when the motion is completed. + virtual BOOL onUpdate(F32 activeTime, U8* joint_mask) = 0; - // called when a motion is deactivated - virtual void onDeactivate() = 0; + // called when a motion is deactivated + virtual void onDeactivate() = 0; - // can we crossfade this motion with a new instance when restarted? - // should ultimately always be TRUE, but lack of emote blending, etc - // requires this - virtual BOOL canDeprecate(); + // can we crossfade this motion with a new instance when restarted? + // should ultimately always be TRUE, but lack of emote blending, etc + // requires this + virtual BOOL canDeprecate(); - // optional callback routine called when animation deactivated. - void setDeactivateCallback( void (*cb)(void *), void* userdata ); + // optional callback routine called when animation deactivated. + void setDeactivateCallback( void (*cb)(void *), void* userdata ); protected: - // called when a motion is activated - // must return TRUE to indicate success, or else - // it will be deactivated - virtual BOOL onActivate() = 0; + // called when a motion is activated + // must return TRUE to indicate success, or else + // it will be deactivated + virtual BOOL onActivate() = 0; - void addJointState(const LLPointer<LLJointState>& jointState); + void addJointState(const LLPointer<LLJointState>& jointState); protected: - LLPose mPose; - BOOL mStopped; // motion has been stopped; - BOOL mActive; // motion is on active list (can be stopped or not stopped) - - //------------------------------------------------------------------------- - // these are set implicitly by the motion controller and - // may be referenced (read only) in the above handlers. - //------------------------------------------------------------------------- - std::string mName; // instance name assigned by motion controller - LLUUID mID; - - F32 mActivationTimestamp; // time when motion was activated - F32 mStopTimestamp; // time when motion was told to stop - F32 mSendStopTimestamp; // time when simulator should be told to stop this motion - F32 mResidualWeight; // blend weight at beginning of stop motion phase - F32 mFadeWeight; // for fading in and out based on LOD - U8 mJointSignature[3][LL_CHARACTER_MAX_ANIMATED_JOINTS]; // signature of which joints are animated at what priority - void (*mDeactivateCallback)(void* data); - void* mDeactivateCallbackUserData; + LLPose mPose; + BOOL mStopped; // motion has been stopped; + BOOL mActive; // motion is on active list (can be stopped or not stopped) + + //------------------------------------------------------------------------- + // these are set implicitly by the motion controller and + // may be referenced (read only) in the above handlers. + //------------------------------------------------------------------------- + std::string mName; // instance name assigned by motion controller + LLUUID mID; + + F32 mActivationTimestamp; // time when motion was activated + F32 mStopTimestamp; // time when motion was told to stop + F32 mSendStopTimestamp; // time when simulator should be told to stop this motion + F32 mResidualWeight; // blend weight at beginning of stop motion phase + F32 mFadeWeight; // for fading in and out based on LOD + U8 mJointSignature[3][LL_CHARACTER_MAX_ANIMATED_JOINTS]; // signature of which joints are animated at what priority + void (*mDeactivateCallback)(void* data); + void* mDeactivateCallbackUserData; }; @@ -196,21 +196,21 @@ protected: class LLTestMotion : public LLMotion { public: - LLTestMotion(const LLUUID &id) : LLMotion(id){} - ~LLTestMotion() {} - static LLMotion *create(const LLUUID& id) { return new LLTestMotion(id); } - BOOL getLoop() { return FALSE; } - F32 getDuration() { return 0.0f; } - F32 getEaseInDuration() { return 0.0f; } - F32 getEaseOutDuration() { return 0.0f; } - LLJoint::JointPriority getPriority() { return LLJoint::HIGH_PRIORITY; } - LLMotionBlendType getBlendType() { return NORMAL_BLEND; } - F32 getMinPixelArea() { return 0.f; } - - LLMotionInitStatus onInitialize(LLCharacter*) { LL_INFOS() << "LLTestMotion::onInitialize()" << LL_ENDL; return STATUS_SUCCESS; } - BOOL onActivate() { LL_INFOS() << "LLTestMotion::onActivate()" << LL_ENDL; return TRUE; } - BOOL onUpdate(F32 time, U8* joint_mask) { LL_INFOS() << "LLTestMotion::onUpdate(" << time << ")" << LL_ENDL; return TRUE; } - void onDeactivate() { LL_INFOS() << "LLTestMotion::onDeactivate()" << LL_ENDL; } + LLTestMotion(const LLUUID &id) : LLMotion(id){} + ~LLTestMotion() {} + static LLMotion *create(const LLUUID& id) { return new LLTestMotion(id); } + BOOL getLoop() { return FALSE; } + F32 getDuration() { return 0.0f; } + F32 getEaseInDuration() { return 0.0f; } + F32 getEaseOutDuration() { return 0.0f; } + LLJoint::JointPriority getPriority() { return LLJoint::HIGH_PRIORITY; } + LLMotionBlendType getBlendType() { return NORMAL_BLEND; } + F32 getMinPixelArea() { return 0.f; } + + LLMotionInitStatus onInitialize(LLCharacter*) { LL_INFOS() << "LLTestMotion::onInitialize()" << LL_ENDL; return STATUS_SUCCESS; } + BOOL onActivate() { LL_INFOS() << "LLTestMotion::onActivate()" << LL_ENDL; return TRUE; } + BOOL onUpdate(F32 time, U8* joint_mask) { LL_INFOS() << "LLTestMotion::onUpdate(" << time << ")" << LL_ENDL; return TRUE; } + void onDeactivate() { LL_INFOS() << "LLTestMotion::onDeactivate()" << LL_ENDL; } }; @@ -220,48 +220,48 @@ public: class LLNullMotion : public LLMotion { public: - LLNullMotion(const LLUUID &id) : LLMotion(id) {} - ~LLNullMotion() {} - static LLMotion *create(const LLUUID &id) { return new LLNullMotion(id); } + LLNullMotion(const LLUUID &id) : LLMotion(id) {} + ~LLNullMotion() {} + static LLMotion *create(const LLUUID &id) { return new LLNullMotion(id); } - // motions must specify whether or not they loop - /*virtual*/ BOOL getLoop() { return TRUE; } + // motions must specify whether or not they loop + /*virtual*/ BOOL getLoop() { return TRUE; } - // motions must report their total duration - /*virtual*/ F32 getDuration() { return 1.f; } + // motions must report their total duration + /*virtual*/ F32 getDuration() { return 1.f; } - // motions must report their "ease in" duration - /*virtual*/ F32 getEaseInDuration() { return 0.f; } + // motions must report their "ease in" duration + /*virtual*/ F32 getEaseInDuration() { return 0.f; } - // motions must report their "ease out" duration. - /*virtual*/ F32 getEaseOutDuration() { return 0.f; } + // motions must report their "ease out" duration. + /*virtual*/ F32 getEaseOutDuration() { return 0.f; } - // motions must report their priority level - /*virtual*/ LLJoint::JointPriority getPriority() { return LLJoint::HIGH_PRIORITY; } + // motions must report their priority level + /*virtual*/ LLJoint::JointPriority getPriority() { return LLJoint::HIGH_PRIORITY; } - // motions must report their blend type - /*virtual*/ LLMotionBlendType getBlendType() { return NORMAL_BLEND; } + // motions must report their blend type + /*virtual*/ LLMotionBlendType getBlendType() { return NORMAL_BLEND; } - // called to determine when a motion should be activated/deactivated based on avatar pixel coverage - /*virtual*/ F32 getMinPixelArea() { return 0.f; } + // called to determine when a motion should be activated/deactivated based on avatar pixel coverage + /*virtual*/ F32 getMinPixelArea() { return 0.f; } - // run-time (post constructor) initialization, - // called after parameters have been set - // must return true to indicate success and be available for activation - /*virtual*/ LLMotionInitStatus onInitialize(LLCharacter *character) { return STATUS_SUCCESS; } + // run-time (post constructor) initialization, + // called after parameters have been set + // must return true to indicate success and be available for activation + /*virtual*/ LLMotionInitStatus onInitialize(LLCharacter *character) { return STATUS_SUCCESS; } - // called when a motion is activated - // must return TRUE to indicate success, or else - // it will be deactivated - /*virtual*/ BOOL onActivate() { return TRUE; } + // called when a motion is activated + // must return TRUE to indicate success, or else + // it will be deactivated + /*virtual*/ BOOL onActivate() { return TRUE; } - // called per time step - // must return TRUE while it is active, and - // must return FALSE when the motion is completed. - /*virtual*/ BOOL onUpdate(F32 activeTime, U8* joint_mask) { return TRUE; } + // called per time step + // must return TRUE while it is active, and + // must return FALSE when the motion is completed. + /*virtual*/ BOOL onUpdate(F32 activeTime, U8* joint_mask) { return TRUE; } - // called when a motion is deactivated - /*virtual*/ void onDeactivate() {} + // called when a motion is deactivated + /*virtual*/ void onDeactivate() {} }; #endif // LL_LLMOTION_H diff --git a/indra/llcharacter/llmotioncontroller.cpp b/indra/llcharacter/llmotioncontroller.cpp index 96e0d5e8d7..689737a190 100644 --- a/indra/llcharacter/llmotioncontroller.cpp +++ b/indra/llcharacter/llmotioncontroller.cpp @@ -1,25 +1,25 @@ -/** +/** * @file llmotioncontroller.cpp * @brief Implementation of LLMotionController class. * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -59,7 +59,7 @@ LLMotionRegistry LLMotionController::sRegistry; //----------------------------------------------------------------------------- LLMotionRegistry::LLMotionRegistry() { - + } @@ -69,7 +69,7 @@ LLMotionRegistry::LLMotionRegistry() //----------------------------------------------------------------------------- LLMotionRegistry::~LLMotionRegistry() { - mMotionTable.clear(); + mMotionTable.clear(); } @@ -78,14 +78,14 @@ LLMotionRegistry::~LLMotionRegistry() //----------------------------------------------------------------------------- BOOL LLMotionRegistry::registerMotion( const LLUUID& id, LLMotionConstructor constructor ) { - // LL_INFOS() << "Registering motion: " << name << LL_ENDL; - if (!is_in_map(mMotionTable, id)) - { - mMotionTable[id] = constructor; - return TRUE; - } - - return FALSE; + // LL_INFOS() << "Registering motion: " << name << LL_ENDL; + if (!is_in_map(mMotionTable, id)) + { + mMotionTable[id] = constructor; + return TRUE; + } + + return FALSE; } //----------------------------------------------------------------------------- @@ -93,7 +93,7 @@ BOOL LLMotionRegistry::registerMotion( const LLUUID& id, LLMotionConstructor con //----------------------------------------------------------------------------- void LLMotionRegistry::markBad( const LLUUID& id ) { - mMotionTable[id] = LLMotionConstructor(NULL); + mMotionTable[id] = LLMotionConstructor(NULL); } //----------------------------------------------------------------------------- @@ -101,20 +101,20 @@ void LLMotionRegistry::markBad( const LLUUID& id ) //----------------------------------------------------------------------------- LLMotion *LLMotionRegistry::createMotion( const LLUUID &id ) { - LLMotionConstructor constructor = get_if_there(mMotionTable, id, LLMotionConstructor(NULL)); - LLMotion* motion = NULL; - - if ( constructor == NULL ) - { - // *FIX: need to replace with a better default scheme. RN - motion = LLKeyframeMotion::create(id); - } - else - { - motion = constructor(id); - } - - return motion; + LLMotionConstructor constructor = get_if_there(mMotionTable, id, LLMotionConstructor(NULL)); + LLMotion* motion = NULL; + + if ( constructor == NULL ) + { + // *FIX: need to replace with a better default scheme. RN + motion = LLKeyframeMotion::create(id); + } + else + { + motion = constructor(id); + } + + return motion; } //----------------------------------------------------------------------------- @@ -128,19 +128,19 @@ LLMotion *LLMotionRegistry::createMotion( const LLUUID &id ) // Class Constructor //----------------------------------------------------------------------------- LLMotionController::LLMotionController() - : mTimeFactor(sCurrentTimeFactor), - mCharacter(NULL), - mAnimTime(0.f), - mPrevTimerElapsed(0.f), - mLastTime(0.0f), - mHasRunOnce(FALSE), - mPaused(FALSE), - mPausedFrame(0), - mTimeStep(0.f), - mTimeStepCount(0), - mLastInterp(0.f), - mIsSelf(FALSE), - mLastCountAfterPurge(0) + : mTimeFactor(sCurrentTimeFactor), + mCharacter(NULL), + mAnimTime(0.f), + mPrevTimerElapsed(0.f), + mLastTime(0.0f), + mHasRunOnce(FALSE), + mPaused(FALSE), + mPausedFrame(0), + mTimeStep(0.f), + mTimeStepCount(0), + mLastInterp(0.f), + mIsSelf(FALSE), + mLastCountAfterPurge(0) { } @@ -151,16 +151,16 @@ LLMotionController::LLMotionController() //----------------------------------------------------------------------------- LLMotionController::~LLMotionController() { - deleteAllMotions(); + deleteAllMotions(); } void LLMotionController::incMotionCounts(S32& num_motions, S32& num_loading_motions, S32& num_loaded_motions, S32& num_active_motions, S32& num_deprecated_motions) { - num_motions += mAllMotions.size(); - num_loading_motions += mLoadingMotions.size(); - num_loaded_motions += mLoadedMotions.size(); - num_active_motions += mActiveMotions.size(); - num_deprecated_motions += mDeprecatedMotions.size(); + num_motions += mAllMotions.size(); + num_loading_motions += mLoadingMotions.size(); + num_loaded_motions += mLoadedMotions.size(); + num_active_motions += mActiveMotions.size(); + num_deprecated_motions += mDeprecatedMotions.size(); } //----------------------------------------------------------------------------- @@ -168,19 +168,19 @@ void LLMotionController::incMotionCounts(S32& num_motions, S32& num_loading_moti //----------------------------------------------------------------------------- void LLMotionController::deleteAllMotions() { - mLoadingMotions.clear(); - mLoadedMotions.clear(); - mActiveMotions.clear(); - - for_each(mAllMotions.begin(), mAllMotions.end(), DeletePairedPointer()); - mAllMotions.clear(); - - // stinson 05/12/20014 : Ownership of the LLMotion pointers is transferred from - // mAllMotions to mDeprecatedMotions in method - // LLMotionController::deprecateMotionInstance(). Thus, we should also clean - // up the mDeprecatedMotions list as well. - for_each(mDeprecatedMotions.begin(), mDeprecatedMotions.end(), DeletePointer()); - mDeprecatedMotions.clear(); + mLoadingMotions.clear(); + mLoadedMotions.clear(); + mActiveMotions.clear(); + + for_each(mAllMotions.begin(), mAllMotions.end(), DeletePairedPointer()); + mAllMotions.clear(); + + // stinson 05/12/20014 : Ownership of the LLMotion pointers is transferred from + // mAllMotions to mDeprecatedMotions in method + // LLMotionController::deprecateMotionInstance(). Thus, we should also clean + // up the mDeprecatedMotions list as well. + for_each(mDeprecatedMotions.begin(), mDeprecatedMotions.end(), DeletePointer()); + mDeprecatedMotions.clear(); } //----------------------------------------------------------------------------- @@ -188,57 +188,57 @@ void LLMotionController::deleteAllMotions() //----------------------------------------------------------------------------- void LLMotionController::purgeExcessMotions() { - if (mLoadedMotions.size() > MAX_MOTION_INSTANCES) - { - // clean up deprecated motions - for (motion_set_t::iterator deprecated_motion_it = mDeprecatedMotions.begin(); - deprecated_motion_it != mDeprecatedMotions.end(); ) - { - motion_set_t::iterator cur_iter = deprecated_motion_it++; - LLMotion* cur_motionp = *cur_iter; - if (!isMotionActive(cur_motionp)) - { - // Motion is deprecated so we know it's not cannonical, - // we can safely remove the instance - removeMotionInstance(cur_motionp); // modifies mDeprecatedMotions - mDeprecatedMotions.erase(cur_iter); - } - } - } - - std::set<LLUUID> motions_to_kill; - if (mLoadedMotions.size() > MAX_MOTION_INSTANCES) - { - // too many motions active this frame, kill all blenders - mPoseBlender.clearBlenders(); - for (LLMotion* cur_motionp : mLoadedMotions) - { - // motion isn't playing, delete it - if (!isMotionActive(cur_motionp)) - { - motions_to_kill.insert(cur_motionp->getID()); - } - } - } - - // clean up all inactive, loaded motions - for (LLUUID motion_id : motions_to_kill) - { - // look up the motion again by ID to get canonical instance - // and kill it only if that one is inactive - LLMotion* motionp = findMotion(motion_id); - if (motionp && !isMotionActive(motionp)) - { - removeMotion(motion_id); - } - } - - U32 loaded_count = mLoadedMotions.size(); - if (loaded_count > (2 * MAX_MOTION_INSTANCES) && loaded_count > mLastCountAfterPurge) - { - LL_WARNS_ONCE("Animation") << loaded_count << " Loaded Motions. Amount of motions is over limit." << LL_ENDL; - } - mLastCountAfterPurge = loaded_count; + if (mLoadedMotions.size() > MAX_MOTION_INSTANCES) + { + // clean up deprecated motions + for (motion_set_t::iterator deprecated_motion_it = mDeprecatedMotions.begin(); + deprecated_motion_it != mDeprecatedMotions.end(); ) + { + motion_set_t::iterator cur_iter = deprecated_motion_it++; + LLMotion* cur_motionp = *cur_iter; + if (!isMotionActive(cur_motionp)) + { + // Motion is deprecated so we know it's not cannonical, + // we can safely remove the instance + removeMotionInstance(cur_motionp); // modifies mDeprecatedMotions + mDeprecatedMotions.erase(cur_iter); + } + } + } + + std::set<LLUUID> motions_to_kill; + if (mLoadedMotions.size() > MAX_MOTION_INSTANCES) + { + // too many motions active this frame, kill all blenders + mPoseBlender.clearBlenders(); + for (LLMotion* cur_motionp : mLoadedMotions) + { + // motion isn't playing, delete it + if (!isMotionActive(cur_motionp)) + { + motions_to_kill.insert(cur_motionp->getID()); + } + } + } + + // clean up all inactive, loaded motions + for (LLUUID motion_id : motions_to_kill) + { + // look up the motion again by ID to get canonical instance + // and kill it only if that one is inactive + LLMotion* motionp = findMotion(motion_id); + if (motionp && !isMotionActive(motionp)) + { + removeMotion(motion_id); + } + } + + U32 loaded_count = mLoadedMotions.size(); + if (loaded_count > (2 * MAX_MOTION_INSTANCES) && loaded_count > mLastCountAfterPurge) + { + LL_WARNS_ONCE("Animation") << loaded_count << " Loaded Motions. Amount of motions is over limit." << LL_ENDL; + } + mLastCountAfterPurge = loaded_count; } //----------------------------------------------------------------------------- @@ -246,17 +246,17 @@ void LLMotionController::purgeExcessMotions() //----------------------------------------------------------------------------- void LLMotionController::deactivateStoppedMotions() { - // Since we're hidden, deactivate any stopped motions. - for (motion_list_t::iterator iter = mActiveMotions.begin(); - iter != mActiveMotions.end(); ) - { - motion_list_t::iterator curiter = iter++; - LLMotion* motionp = *curiter; - if (motionp->isStopped()) - { - deactivateMotionInstance(motionp); - } - } + // Since we're hidden, deactivate any stopped motions. + for (motion_list_t::iterator iter = mActiveMotions.begin(); + iter != mActiveMotions.end(); ) + { + motion_list_t::iterator curiter = iter++; + LLMotion* motionp = *curiter; + if (motionp->isStopped()) + { + deactivateMotionInstance(motionp); + } + } } //----------------------------------------------------------------------------- @@ -264,31 +264,31 @@ void LLMotionController::deactivateStoppedMotions() //----------------------------------------------------------------------------- void LLMotionController::setTimeStep(F32 step) { - mTimeStep = step; - - if (step != 0.f) - { - // make sure timestamps conform to new quantum - for (motion_list_t::iterator iter = mActiveMotions.begin(); - iter != mActiveMotions.end(); ++iter) - { - LLMotion* motionp = *iter; - F32 activation_time = motionp->mActivationTimestamp; - motionp->mActivationTimestamp = (F32)(llfloor(activation_time / step)) * step; - BOOL stopped = motionp->isStopped(); - motionp->setStopTime((F32)(llfloor(motionp->getStopTime() / step)) * step); - motionp->setStopped(stopped); - motionp->mSendStopTimestamp = (F32)llfloor(motionp->mSendStopTimestamp / step) * step; - } - } + mTimeStep = step; + + if (step != 0.f) + { + // make sure timestamps conform to new quantum + for (motion_list_t::iterator iter = mActiveMotions.begin(); + iter != mActiveMotions.end(); ++iter) + { + LLMotion* motionp = *iter; + F32 activation_time = motionp->mActivationTimestamp; + motionp->mActivationTimestamp = (F32)(llfloor(activation_time / step)) * step; + BOOL stopped = motionp->isStopped(); + motionp->setStopTime((F32)(llfloor(motionp->getStopTime() / step)) * step); + motionp->setStopped(stopped); + motionp->mSendStopTimestamp = (F32)llfloor(motionp->mSendStopTimestamp / step) * step; + } + } } //----------------------------------------------------------------------------- // setTimeFactor() //----------------------------------------------------------------------------- void LLMotionController::setTimeFactor(F32 time_factor) -{ - mTimeFactor = time_factor; +{ + mTimeFactor = time_factor; } //----------------------------------------------------------------------------- @@ -296,7 +296,7 @@ void LLMotionController::setTimeFactor(F32 time_factor) //----------------------------------------------------------------------------- void LLMotionController::setCharacter(LLCharacter *character) { - mCharacter = character; + mCharacter = character; } @@ -305,7 +305,7 @@ void LLMotionController::setCharacter(LLCharacter *character) //----------------------------------------------------------------------------- BOOL LLMotionController::registerMotion( const LLUUID& id, LLMotionConstructor constructor ) { - return sRegistry.registerMotion(id, constructor); + return sRegistry.registerMotion(id, constructor); } //----------------------------------------------------------------------------- @@ -313,9 +313,9 @@ BOOL LLMotionController::registerMotion( const LLUUID& id, LLMotionConstructor c //----------------------------------------------------------------------------- void LLMotionController::removeMotion( const LLUUID& id) { - LLMotion* motionp = findMotion(id); - mAllMotions.erase(id); - removeMotionInstance(motionp); + LLMotion* motionp = findMotion(id); + mAllMotions.erase(id); + removeMotionInstance(motionp); } // removes instance of a motion from all runtime structures, but does @@ -323,16 +323,16 @@ void LLMotionController::removeMotion( const LLUUID& id) // use removeMotion(id) to remove all references to a given motion by id. void LLMotionController::removeMotionInstance(LLMotion* motionp) { - if (motionp) - { - llassert(findMotion(motionp->getID()) != motionp); - if (motionp->isActive()) - motionp->deactivate(); - mLoadingMotions.erase(motionp); - mLoadedMotions.erase(motionp); - mActiveMotions.remove(motionp); - delete motionp; - } + if (motionp) + { + llassert(findMotion(motionp->getID()) != motionp); + if (motionp->isActive()) + motionp->deactivate(); + mLoadingMotions.erase(motionp); + mLoadedMotions.erase(motionp); + mActiveMotions.remove(motionp); + delete motionp; + } } //----------------------------------------------------------------------------- @@ -340,50 +340,50 @@ void LLMotionController::removeMotionInstance(LLMotion* motionp) //----------------------------------------------------------------------------- LLMotion* LLMotionController::createMotion( const LLUUID &id ) { - // do we have an instance of this motion for this character? - LLMotion *motion = findMotion(id); - - // if not, we need to create one - if (!motion) - { - // look up constructor and create it - motion = sRegistry.createMotion(id); - if (!motion) - { - return NULL; - } - - // look up name for default motions - const char* motion_name = gAnimLibrary.animStateToString(id); - if (motion_name) - { - motion->setName(motion_name); - } - - // initialize the new instance - LLMotion::LLMotionInitStatus stat = motion->onInitialize(mCharacter); - switch(stat) - { - case LLMotion::STATUS_FAILURE: - LL_INFOS() << "Motion " << id << " init failed." << LL_ENDL; - sRegistry.markBad(id); - delete motion; - return NULL; - case LLMotion::STATUS_HOLD: - mLoadingMotions.insert(motion); - break; - case LLMotion::STATUS_SUCCESS: - // add motion to our list - mLoadedMotions.insert(motion); - break; - default: - LL_ERRS() << "Invalid initialization status" << LL_ENDL; - break; - } - - mAllMotions[id] = motion; - } - return motion; + // do we have an instance of this motion for this character? + LLMotion *motion = findMotion(id); + + // if not, we need to create one + if (!motion) + { + // look up constructor and create it + motion = sRegistry.createMotion(id); + if (!motion) + { + return NULL; + } + + // look up name for default motions + const char* motion_name = gAnimLibrary.animStateToString(id); + if (motion_name) + { + motion->setName(motion_name); + } + + // initialize the new instance + LLMotion::LLMotionInitStatus stat = motion->onInitialize(mCharacter); + switch(stat) + { + case LLMotion::STATUS_FAILURE: + LL_INFOS() << "Motion " << id << " init failed." << LL_ENDL; + sRegistry.markBad(id); + delete motion; + return NULL; + case LLMotion::STATUS_HOLD: + mLoadingMotions.insert(motion); + break; + case LLMotion::STATUS_SUCCESS: + // add motion to our list + mLoadedMotions.insert(motion); + break; + default: + LL_ERRS() << "Invalid initialization status" << LL_ENDL; + break; + } + + mAllMotions[id] = motion; + } + return motion; } //----------------------------------------------------------------------------- @@ -391,40 +391,40 @@ LLMotion* LLMotionController::createMotion( const LLUUID &id ) //----------------------------------------------------------------------------- BOOL LLMotionController::startMotion(const LLUUID &id, F32 start_offset) { - // do we have an instance of this motion for this character? - LLMotion *motion = findMotion(id); - - // motion that is stopping will be allowed to stop but - // replaced by a new instance of that motion - if (motion - && !mPaused - && motion->canDeprecate() - && motion->getFadeWeight() > 0.01f // not LOD-ed out - && (motion->isBlending() || motion->getStopTime() != 0.f)) - { - deprecateMotionInstance(motion); - // force creation of new instance - motion = NULL; - } - - // create new motion instance - if (!motion) - { - motion = createMotion(id); - } - - if (!motion) - { - return FALSE; - } - //if the motion is already active and allows deprecation, then let it keep playing - else if (motion->canDeprecate() && isMotionActive(motion)) - { - return TRUE; - } - -// LL_INFOS() << "Starting motion " << name << LL_ENDL; - return activateMotionInstance(motion, mAnimTime - start_offset); + // do we have an instance of this motion for this character? + LLMotion *motion = findMotion(id); + + // motion that is stopping will be allowed to stop but + // replaced by a new instance of that motion + if (motion + && !mPaused + && motion->canDeprecate() + && motion->getFadeWeight() > 0.01f // not LOD-ed out + && (motion->isBlending() || motion->getStopTime() != 0.f)) + { + deprecateMotionInstance(motion); + // force creation of new instance + motion = NULL; + } + + // create new motion instance + if (!motion) + { + motion = createMotion(id); + } + + if (!motion) + { + return FALSE; + } + //if the motion is already active and allows deprecation, then let it keep playing + else if (motion->canDeprecate() && isMotionActive(motion)) + { + return TRUE; + } + +// LL_INFOS() << "Starting motion " << name << LL_ENDL; + return activateMotionInstance(motion, mAnimTime - start_offset); } @@ -433,37 +433,37 @@ BOOL LLMotionController::startMotion(const LLUUID &id, F32 start_offset) //----------------------------------------------------------------------------- BOOL LLMotionController::stopMotionLocally(const LLUUID &id, BOOL stop_immediate) { - // if already inactive, return false - LLMotion *motion = findMotion(id); - // SL-1290: always stop immediate if paused - return stopMotionInstance(motion, stop_immediate||mPaused); + // if already inactive, return false + LLMotion *motion = findMotion(id); + // SL-1290: always stop immediate if paused + return stopMotionInstance(motion, stop_immediate||mPaused); } BOOL LLMotionController::stopMotionInstance(LLMotion* motion, BOOL stop_immediate) { - if (!motion) - { - return FALSE; - } - - - // If on active list, stop it - if (isMotionActive(motion) && !motion->isStopped()) - { - motion->setStopTime(mAnimTime); - if (stop_immediate) - { - deactivateMotionInstance(motion); - } - return TRUE; - } - else if (isMotionLoading(motion)) - { - motion->setStopped(TRUE); - return TRUE; - } - - return FALSE; + if (!motion) + { + return FALSE; + } + + + // If on active list, stop it + if (isMotionActive(motion) && !motion->isStopped()) + { + motion->setStopTime(mAnimTime); + if (stop_immediate) + { + deactivateMotionInstance(motion); + } + return TRUE; + } + else if (isMotionLoading(motion)) + { + motion->setStopped(TRUE); + return TRUE; + } + + return FALSE; } //----------------------------------------------------------------------------- @@ -471,7 +471,7 @@ BOOL LLMotionController::stopMotionInstance(LLMotion* motion, BOOL stop_immediat //----------------------------------------------------------------------------- void LLMotionController::updateRegularMotions() { - updateMotionsByType(LLMotion::NORMAL_BLEND); + updateMotionsByType(LLMotion::NORMAL_BLEND); } //----------------------------------------------------------------------------- @@ -479,7 +479,7 @@ void LLMotionController::updateRegularMotions() //----------------------------------------------------------------------------- void LLMotionController::updateAdditiveMotions() { - updateMotionsByType(LLMotion::ADDITIVE_BLEND); + updateMotionsByType(LLMotion::ADDITIVE_BLEND); } //----------------------------------------------------------------------------- @@ -487,8 +487,8 @@ void LLMotionController::updateAdditiveMotions() //----------------------------------------------------------------------------- void LLMotionController::resetJointSignatures() { - memset(&mJointSignature[0][0], 0, sizeof(U8) * LL_CHARACTER_MAX_ANIMATED_JOINTS); - memset(&mJointSignature[1][0], 0, sizeof(U8) * LL_CHARACTER_MAX_ANIMATED_JOINTS); + memset(&mJointSignature[0][0], 0, sizeof(U8) * LL_CHARACTER_MAX_ANIMATED_JOINTS); + memset(&mJointSignature[1][0], 0, sizeof(U8) * LL_CHARACTER_MAX_ANIMATED_JOINTS); } //----------------------------------------------------------------------------- @@ -498,36 +498,36 @@ void LLMotionController::resetJointSignatures() void LLMotionController::updateIdleMotion(LLMotion* motionp) { LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR; - if (motionp->isStopped() && mAnimTime > motionp->getStopTime() + motionp->getEaseOutDuration()) - { - deactivateMotionInstance(motionp); - } - else if (motionp->isStopped() && mAnimTime > motionp->getStopTime()) - { - // is this the first iteration in the ease out phase? - if (mLastTime <= motionp->getStopTime()) - { - // store residual weight for this motion - motionp->mResidualWeight = motionp->getPose()->getWeight(); - } - } - else if (mAnimTime > motionp->mSendStopTimestamp) - { - // notify character of timed stop event on first iteration past sendstoptimestamp - // this will only be called when an animation stops itself (runs out of time) - if (mLastTime <= motionp->mSendStopTimestamp) - { - mCharacter->requestStopMotion( motionp ); - stopMotionInstance(motionp, FALSE); - } - } - else if (mAnimTime >= motionp->mActivationTimestamp) - { - if (mLastTime < motionp->mActivationTimestamp) - { - motionp->mResidualWeight = motionp->getPose()->getWeight(); - } - } + if (motionp->isStopped() && mAnimTime > motionp->getStopTime() + motionp->getEaseOutDuration()) + { + deactivateMotionInstance(motionp); + } + else if (motionp->isStopped() && mAnimTime > motionp->getStopTime()) + { + // is this the first iteration in the ease out phase? + if (mLastTime <= motionp->getStopTime()) + { + // store residual weight for this motion + motionp->mResidualWeight = motionp->getPose()->getWeight(); + } + } + else if (mAnimTime > motionp->mSendStopTimestamp) + { + // notify character of timed stop event on first iteration past sendstoptimestamp + // this will only be called when an animation stops itself (runs out of time) + if (mLastTime <= motionp->mSendStopTimestamp) + { + mCharacter->requestStopMotion( motionp ); + stopMotionInstance(motionp, FALSE); + } + } + else if (mAnimTime >= motionp->mActivationTimestamp) + { + if (mLastTime < motionp->mActivationTimestamp) + { + motionp->mResidualWeight = motionp->getPose()->getWeight(); + } + } } //----------------------------------------------------------------------------- @@ -537,13 +537,13 @@ void LLMotionController::updateIdleMotion(LLMotion* motionp) void LLMotionController::updateIdleActiveMotions() { LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR; - for (motion_list_t::iterator iter = mActiveMotions.begin(); - iter != mActiveMotions.end(); ) - { - motion_list_t::iterator curiter = iter++; - LLMotion* motionp = *curiter; - updateIdleMotion(motionp); - } + for (motion_list_t::iterator iter = mActiveMotions.begin(); + iter != mActiveMotions.end(); ) + { + motion_list_t::iterator curiter = iter++; + LLMotion* motionp = *curiter; + updateIdleMotion(motionp); + } } //----------------------------------------------------------------------------- @@ -552,209 +552,209 @@ void LLMotionController::updateIdleActiveMotions() void LLMotionController::updateMotionsByType(LLMotion::LLMotionBlendType anim_type) { LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR; - BOOL update_result = TRUE; - U8 last_joint_signature[LL_CHARACTER_MAX_ANIMATED_JOINTS]; - - memset(&last_joint_signature, 0, sizeof(U8) * LL_CHARACTER_MAX_ANIMATED_JOINTS); - - // iterate through active motions in chronological order - for (motion_list_t::iterator iter = mActiveMotions.begin(); - iter != mActiveMotions.end(); ) - { - motion_list_t::iterator curiter = iter++; - LLMotion* motionp = *curiter; - if (motionp->getBlendType() != anim_type) - { - continue; - } - - BOOL update_motion = FALSE; - - if (motionp->getPose()->getWeight() < 1.f) - { - update_motion = TRUE; - } - else - { - for (S32 i = 0; i < NUM_JOINT_SIGNATURE_STRIDES; i++) - { - U32 *current_signature = (U32*)&(mJointSignature[0][i * 4]); - U32 test_signature = *(U32*)&(motionp->mJointSignature[0][i * 4]); - - if ((*current_signature | test_signature) > (*current_signature)) - { - *current_signature |= test_signature; - update_motion = TRUE; - } - - *((U32*)&last_joint_signature[i * 4]) = *(U32*)&(mJointSignature[1][i * 4]); - current_signature = (U32*)&(mJointSignature[1][i * 4]); - test_signature = *(U32*)&(motionp->mJointSignature[1][i * 4]); - - if ((*current_signature | test_signature) > (*current_signature)) - { - *current_signature |= test_signature; - update_motion = TRUE; - } - } - } - - if (!update_motion) - { - updateIdleMotion(motionp); - continue; - } - - LLPose *posep = motionp->getPose(); - - // only filter by LOD after running every animation at least once (to prime the avatar state) - if (mHasRunOnce && motionp->getMinPixelArea() > mCharacter->getPixelArea()) - { - motionp->fadeOut(); - - //should we notify the simulator that this motion should be stopped (check even if skipped by LOD logic) - if (mAnimTime > motionp->mSendStopTimestamp) - { - // notify character of timed stop event on first iteration past sendstoptimestamp - // this will only be called when an animation stops itself (runs out of time) - if (mLastTime <= motionp->mSendStopTimestamp) - { - mCharacter->requestStopMotion( motionp ); - stopMotionInstance(motionp, FALSE); - } - } - - if (motionp->getFadeWeight() < 0.01f) - { - if (motionp->isStopped() && mAnimTime > motionp->getStopTime() + motionp->getEaseOutDuration()) - { - posep->setWeight(0.f); - deactivateMotionInstance(motionp); - } - continue; - } - } - else - { - motionp->fadeIn(); - } - - //********************** - // MOTION INACTIVE - //********************** - if (motionp->isStopped() && mAnimTime > motionp->getStopTime() + motionp->getEaseOutDuration()) - { - // this motion has gone on too long, deactivate it - // did we have a chance to stop it? - if (mLastTime <= motionp->getStopTime()) - { - // if not, let's stop it this time through and deactivate it the next - - posep->setWeight(motionp->getFadeWeight()); - motionp->onUpdate(motionp->getStopTime() - motionp->mActivationTimestamp, last_joint_signature); - } - else - { - posep->setWeight(0.f); - deactivateMotionInstance(motionp); - continue; - } - } - - //********************** - // MOTION EASE OUT - //********************** - else if (motionp->isStopped() && mAnimTime > motionp->getStopTime()) - { - // is this the first iteration in the ease out phase? - if (mLastTime <= motionp->getStopTime()) - { - // store residual weight for this motion - motionp->mResidualWeight = motionp->getPose()->getWeight(); - } - - if (motionp->getEaseOutDuration() == 0.f) - { - posep->setWeight(0.f); - } - else - { - posep->setWeight(motionp->getFadeWeight() * motionp->mResidualWeight * cubic_step(1.f - ((mAnimTime - motionp->getStopTime()) / motionp->getEaseOutDuration()))); - } - - // perform motion update - update_result = motionp->onUpdate(mAnimTime - motionp->mActivationTimestamp, last_joint_signature); - } - - //********************** - // MOTION ACTIVE - //********************** - else if (mAnimTime > motionp->mActivationTimestamp + motionp->getEaseInDuration()) - { - posep->setWeight(motionp->getFadeWeight()); - - //should we notify the simulator that this motion should be stopped? - if (mAnimTime > motionp->mSendStopTimestamp) - { - // notify character of timed stop event on first iteration past sendstoptimestamp - // this will only be called when an animation stops itself (runs out of time) - if (mLastTime <= motionp->mSendStopTimestamp) - { - mCharacter->requestStopMotion( motionp ); - stopMotionInstance(motionp, FALSE); - } - } - - // perform motion update - { - update_result = motionp->onUpdate(mAnimTime - motionp->mActivationTimestamp, last_joint_signature); - } - } - - //********************** - // MOTION EASE IN - //********************** - else if (mAnimTime >= motionp->mActivationTimestamp) - { - if (mLastTime < motionp->mActivationTimestamp) - { - motionp->mResidualWeight = motionp->getPose()->getWeight(); - } - if (motionp->getEaseInDuration() == 0.f) - { - posep->setWeight(motionp->getFadeWeight()); - } - else - { - // perform motion update - posep->setWeight(motionp->getFadeWeight() * motionp->mResidualWeight + (1.f - motionp->mResidualWeight) * cubic_step((mAnimTime - motionp->mActivationTimestamp) / motionp->getEaseInDuration())); - } - // perform motion update - update_result = motionp->onUpdate(mAnimTime - motionp->mActivationTimestamp, last_joint_signature); - } - else - { - posep->setWeight(0.f); - update_result = motionp->onUpdate(0.f, last_joint_signature); - } - - // allow motions to deactivate themselves - if (!update_result) - { - if (!motionp->isStopped() || motionp->getStopTime() > mAnimTime) - { - // animation has stopped itself due to internal logic - // propagate this to the network - // as not all viewers are guaranteed to have access to the same logic - mCharacter->requestStopMotion( motionp ); - stopMotionInstance(motionp, FALSE); - } - - } - - // even if onupdate returns FALSE, add this motion in to the blend one last time - mPoseBlender.addMotion(motionp); - } + BOOL update_result = TRUE; + U8 last_joint_signature[LL_CHARACTER_MAX_ANIMATED_JOINTS]; + + memset(&last_joint_signature, 0, sizeof(U8) * LL_CHARACTER_MAX_ANIMATED_JOINTS); + + // iterate through active motions in chronological order + for (motion_list_t::iterator iter = mActiveMotions.begin(); + iter != mActiveMotions.end(); ) + { + motion_list_t::iterator curiter = iter++; + LLMotion* motionp = *curiter; + if (motionp->getBlendType() != anim_type) + { + continue; + } + + BOOL update_motion = FALSE; + + if (motionp->getPose()->getWeight() < 1.f) + { + update_motion = TRUE; + } + else + { + for (S32 i = 0; i < NUM_JOINT_SIGNATURE_STRIDES; i++) + { + U32 *current_signature = (U32*)&(mJointSignature[0][i * 4]); + U32 test_signature = *(U32*)&(motionp->mJointSignature[0][i * 4]); + + if ((*current_signature | test_signature) > (*current_signature)) + { + *current_signature |= test_signature; + update_motion = TRUE; + } + + *((U32*)&last_joint_signature[i * 4]) = *(U32*)&(mJointSignature[1][i * 4]); + current_signature = (U32*)&(mJointSignature[1][i * 4]); + test_signature = *(U32*)&(motionp->mJointSignature[1][i * 4]); + + if ((*current_signature | test_signature) > (*current_signature)) + { + *current_signature |= test_signature; + update_motion = TRUE; + } + } + } + + if (!update_motion) + { + updateIdleMotion(motionp); + continue; + } + + LLPose *posep = motionp->getPose(); + + // only filter by LOD after running every animation at least once (to prime the avatar state) + if (mHasRunOnce && motionp->getMinPixelArea() > mCharacter->getPixelArea()) + { + motionp->fadeOut(); + + //should we notify the simulator that this motion should be stopped (check even if skipped by LOD logic) + if (mAnimTime > motionp->mSendStopTimestamp) + { + // notify character of timed stop event on first iteration past sendstoptimestamp + // this will only be called when an animation stops itself (runs out of time) + if (mLastTime <= motionp->mSendStopTimestamp) + { + mCharacter->requestStopMotion( motionp ); + stopMotionInstance(motionp, FALSE); + } + } + + if (motionp->getFadeWeight() < 0.01f) + { + if (motionp->isStopped() && mAnimTime > motionp->getStopTime() + motionp->getEaseOutDuration()) + { + posep->setWeight(0.f); + deactivateMotionInstance(motionp); + } + continue; + } + } + else + { + motionp->fadeIn(); + } + + //********************** + // MOTION INACTIVE + //********************** + if (motionp->isStopped() && mAnimTime > motionp->getStopTime() + motionp->getEaseOutDuration()) + { + // this motion has gone on too long, deactivate it + // did we have a chance to stop it? + if (mLastTime <= motionp->getStopTime()) + { + // if not, let's stop it this time through and deactivate it the next + + posep->setWeight(motionp->getFadeWeight()); + motionp->onUpdate(motionp->getStopTime() - motionp->mActivationTimestamp, last_joint_signature); + } + else + { + posep->setWeight(0.f); + deactivateMotionInstance(motionp); + continue; + } + } + + //********************** + // MOTION EASE OUT + //********************** + else if (motionp->isStopped() && mAnimTime > motionp->getStopTime()) + { + // is this the first iteration in the ease out phase? + if (mLastTime <= motionp->getStopTime()) + { + // store residual weight for this motion + motionp->mResidualWeight = motionp->getPose()->getWeight(); + } + + if (motionp->getEaseOutDuration() == 0.f) + { + posep->setWeight(0.f); + } + else + { + posep->setWeight(motionp->getFadeWeight() * motionp->mResidualWeight * cubic_step(1.f - ((mAnimTime - motionp->getStopTime()) / motionp->getEaseOutDuration()))); + } + + // perform motion update + update_result = motionp->onUpdate(mAnimTime - motionp->mActivationTimestamp, last_joint_signature); + } + + //********************** + // MOTION ACTIVE + //********************** + else if (mAnimTime > motionp->mActivationTimestamp + motionp->getEaseInDuration()) + { + posep->setWeight(motionp->getFadeWeight()); + + //should we notify the simulator that this motion should be stopped? + if (mAnimTime > motionp->mSendStopTimestamp) + { + // notify character of timed stop event on first iteration past sendstoptimestamp + // this will only be called when an animation stops itself (runs out of time) + if (mLastTime <= motionp->mSendStopTimestamp) + { + mCharacter->requestStopMotion( motionp ); + stopMotionInstance(motionp, FALSE); + } + } + + // perform motion update + { + update_result = motionp->onUpdate(mAnimTime - motionp->mActivationTimestamp, last_joint_signature); + } + } + + //********************** + // MOTION EASE IN + //********************** + else if (mAnimTime >= motionp->mActivationTimestamp) + { + if (mLastTime < motionp->mActivationTimestamp) + { + motionp->mResidualWeight = motionp->getPose()->getWeight(); + } + if (motionp->getEaseInDuration() == 0.f) + { + posep->setWeight(motionp->getFadeWeight()); + } + else + { + // perform motion update + posep->setWeight(motionp->getFadeWeight() * motionp->mResidualWeight + (1.f - motionp->mResidualWeight) * cubic_step((mAnimTime - motionp->mActivationTimestamp) / motionp->getEaseInDuration())); + } + // perform motion update + update_result = motionp->onUpdate(mAnimTime - motionp->mActivationTimestamp, last_joint_signature); + } + else + { + posep->setWeight(0.f); + update_result = motionp->onUpdate(0.f, last_joint_signature); + } + + // allow motions to deactivate themselves + if (!update_result) + { + if (!motionp->isStopped() || motionp->getStopTime() > mAnimTime) + { + // animation has stopped itself due to internal logic + // propagate this to the network + // as not all viewers are guaranteed to have access to the same logic + mCharacter->requestStopMotion( motionp ); + stopMotionInstance(motionp, FALSE); + } + + } + + // even if onupdate returns FALSE, add this motion in to the blend one last time + mPoseBlender.addMotion(motionp); + } } //----------------------------------------------------------------------------- @@ -763,42 +763,42 @@ void LLMotionController::updateMotionsByType(LLMotion::LLMotionBlendType anim_ty void LLMotionController::updateLoadingMotions() { LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR; - // query pending motions for completion - for (motion_set_t::iterator iter = mLoadingMotions.begin(); - iter != mLoadingMotions.end(); ) - { - motion_set_t::iterator curiter = iter++; - LLMotion* motionp = *curiter; - if( !motionp) - { - continue; // maybe shouldn't happen but i've seen it -MG - } - LLMotion::LLMotionInitStatus status = motionp->onInitialize(mCharacter); - if (status == LLMotion::STATUS_SUCCESS) - { - mLoadingMotions.erase(curiter); - // add motion to our loaded motion list - mLoadedMotions.insert(motionp); - // this motion should be playing - if (!motionp->isStopped()) - { - activateMotionInstance(motionp, mAnimTime); - } - } - else if (status == LLMotion::STATUS_FAILURE) - { - LL_INFOS() << "Motion " << motionp->getID() << " init failed." << LL_ENDL; - sRegistry.markBad(motionp->getID()); - mLoadingMotions.erase(curiter); - motion_set_t::iterator found_it = mDeprecatedMotions.find(motionp); - if (found_it != mDeprecatedMotions.end()) - { - mDeprecatedMotions.erase(found_it); - } - mAllMotions.erase(motionp->getID()); - delete motionp; - } - } + // query pending motions for completion + for (motion_set_t::iterator iter = mLoadingMotions.begin(); + iter != mLoadingMotions.end(); ) + { + motion_set_t::iterator curiter = iter++; + LLMotion* motionp = *curiter; + if( !motionp) + { + continue; // maybe shouldn't happen but i've seen it -MG + } + LLMotion::LLMotionInitStatus status = motionp->onInitialize(mCharacter); + if (status == LLMotion::STATUS_SUCCESS) + { + mLoadingMotions.erase(curiter); + // add motion to our loaded motion list + mLoadedMotions.insert(motionp); + // this motion should be playing + if (!motionp->isStopped()) + { + activateMotionInstance(motionp, mAnimTime); + } + } + else if (status == LLMotion::STATUS_FAILURE) + { + LL_INFOS() << "Motion " << motionp->getID() << " init failed." << LL_ENDL; + sRegistry.markBad(motionp->getID()); + mLoadingMotions.erase(curiter); + motion_set_t::iterator found_it = mDeprecatedMotions.find(motionp); + if (found_it != mDeprecatedMotions.end()) + { + mDeprecatedMotions.erase(found_it); + } + mAllMotions.erase(motionp->getID()); + delete motionp; + } + } } //----------------------------------------------------------------------------- @@ -815,86 +815,86 @@ void LLMotionController::updateMotions(bool force_update) // The use_quantum optimization or possibly the associated code in setTimeStamp() // does not work as implemented. // Currently setting mTimeStep to nonzero is disabled elsewhere. - BOOL use_quantum = (mTimeStep != 0.f); - - // Always update mPrevTimerElapsed - F32 cur_time = mTimer.getElapsedTimeF32(); - F32 delta_time = cur_time - mPrevTimerElapsed; - mPrevTimerElapsed = cur_time; - mLastTime = mAnimTime; - - // Always cap the number of loaded motions - purgeExcessMotions(); - - // Update timing info for this time step. - if (!mPaused) - { - F32 update_time = mAnimTime + delta_time * mTimeFactor; - if (use_quantum) - { - F32 time_interval = fmodf(update_time, mTimeStep); - - // always animate *ahead* of actual time - S32 quantum_count = llmax(0, llfloor((update_time - time_interval) / mTimeStep)) + 1; - if (quantum_count == mTimeStepCount) - { - // we're still in same time quantum as before, so just interpolate and exit - if (!mPaused) - { - F32 interp = time_interval / mTimeStep; - mPoseBlender.interpolate(interp - mLastInterp); - mLastInterp = interp; - } - - updateLoadingMotions(); - - return; - } - - // is calculating a new keyframe pose, make sure the last one gets applied - mPoseBlender.interpolate(1.f); - clearBlenders(); - - mTimeStepCount = quantum_count; - mAnimTime = (F32)quantum_count * mTimeStep; - mLastInterp = 0.f; - } - else - { - mAnimTime = update_time; - } - } - - updateLoadingMotions(); - - resetJointSignatures(); - - if (mPaused && !force_update) - { - updateIdleActiveMotions(); - } - else - { - // update additive motions - updateAdditiveMotions(); - - resetJointSignatures(); - - // update all regular motions - updateRegularMotions(); - - if (use_quantum) - { - mPoseBlender.blendAndCache(TRUE); - } - else - { - mPoseBlender.blendAndApply(); - } - } - - mHasRunOnce = TRUE; -// LL_INFOS() << "Motion controller time " << motionTimer.getElapsedTimeF32() << LL_ENDL; + BOOL use_quantum = (mTimeStep != 0.f); + + // Always update mPrevTimerElapsed + F32 cur_time = mTimer.getElapsedTimeF32(); + F32 delta_time = cur_time - mPrevTimerElapsed; + mPrevTimerElapsed = cur_time; + mLastTime = mAnimTime; + + // Always cap the number of loaded motions + purgeExcessMotions(); + + // Update timing info for this time step. + if (!mPaused) + { + F32 update_time = mAnimTime + delta_time * mTimeFactor; + if (use_quantum) + { + F32 time_interval = fmodf(update_time, mTimeStep); + + // always animate *ahead* of actual time + S32 quantum_count = llmax(0, llfloor((update_time - time_interval) / mTimeStep)) + 1; + if (quantum_count == mTimeStepCount) + { + // we're still in same time quantum as before, so just interpolate and exit + if (!mPaused) + { + F32 interp = time_interval / mTimeStep; + mPoseBlender.interpolate(interp - mLastInterp); + mLastInterp = interp; + } + + updateLoadingMotions(); + + return; + } + + // is calculating a new keyframe pose, make sure the last one gets applied + mPoseBlender.interpolate(1.f); + clearBlenders(); + + mTimeStepCount = quantum_count; + mAnimTime = (F32)quantum_count * mTimeStep; + mLastInterp = 0.f; + } + else + { + mAnimTime = update_time; + } + } + + updateLoadingMotions(); + + resetJointSignatures(); + + if (mPaused && !force_update) + { + updateIdleActiveMotions(); + } + else + { + // update additive motions + updateAdditiveMotions(); + + resetJointSignatures(); + + // update all regular motions + updateRegularMotions(); + + if (use_quantum) + { + mPoseBlender.blendAndCache(TRUE); + } + else + { + mPoseBlender.blendAndApply(); + } + } + + mHasRunOnce = TRUE; +// LL_INFOS() << "Motion controller time " << motionTimer.getElapsedTimeF32() << LL_ENDL; } //----------------------------------------------------------------------------- @@ -904,16 +904,16 @@ void LLMotionController::updateMotions(bool force_update) void LLMotionController::updateMotionsMinimal() { LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR; - // Always update mPrevTimerElapsed - mPrevTimerElapsed = mTimer.getElapsedTimeF32(); + // Always update mPrevTimerElapsed + mPrevTimerElapsed = mTimer.getElapsedTimeF32(); - purgeExcessMotions(); - updateLoadingMotions(); - resetJointSignatures(); + purgeExcessMotions(); + updateLoadingMotions(); + resetJointSignatures(); - deactivateStoppedMotions(); + deactivateStoppedMotions(); - mHasRunOnce = TRUE; + mHasRunOnce = TRUE; } //----------------------------------------------------------------------------- @@ -922,63 +922,63 @@ void LLMotionController::updateMotionsMinimal() BOOL LLMotionController::activateMotionInstance(LLMotion *motion, F32 time) { LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR; - // It's not clear why the getWeight() line seems to be crashing this, but - // hopefully this fixes it. - if (motion == NULL || motion->getPose() == NULL) - { - return FALSE; - } - - if (mLoadingMotions.find(motion) != mLoadingMotions.end()) - { - // we want to start this motion, but we can't yet, so flag it as started - motion->setStopped(FALSE); - // report pending animations as activated - return TRUE; - } - - motion->mResidualWeight = motion->getPose()->getWeight(); - - // set stop time based on given duration and ease out time - if (motion->getDuration() != 0.f && !motion->getLoop()) - { - F32 ease_out_time; - F32 motion_duration; - - // should we stop at the end of motion duration, or a bit earlier - // to allow it to ease out while moving? - ease_out_time = motion->getEaseOutDuration(); - - // is the clock running when the motion is easing in? - // if not (POSTURE_EASE) then we need to wait that much longer before triggering the stop - motion_duration = llmax(motion->getDuration() - ease_out_time, 0.f); - motion->mSendStopTimestamp = time + motion_duration; - } - else - { - motion->mSendStopTimestamp = F32_MAX; - } - - if (motion->isActive()) - { - mActiveMotions.remove(motion); - } - mActiveMotions.push_front(motion); - - motion->activate(time); - motion->onUpdate(0.f, mJointSignature[1]); - - if (mAnimTime >= motion->mSendStopTimestamp) - { - motion->setStopTime(motion->mSendStopTimestamp); - if (motion->mResidualWeight == 0.0f) - { - // bit of a hack; if newly activating a motion while easing out, weight should = 1 - motion->mResidualWeight = 1.f; - } - } - - return TRUE; + // It's not clear why the getWeight() line seems to be crashing this, but + // hopefully this fixes it. + if (motion == NULL || motion->getPose() == NULL) + { + return FALSE; + } + + if (mLoadingMotions.find(motion) != mLoadingMotions.end()) + { + // we want to start this motion, but we can't yet, so flag it as started + motion->setStopped(FALSE); + // report pending animations as activated + return TRUE; + } + + motion->mResidualWeight = motion->getPose()->getWeight(); + + // set stop time based on given duration and ease out time + if (motion->getDuration() != 0.f && !motion->getLoop()) + { + F32 ease_out_time; + F32 motion_duration; + + // should we stop at the end of motion duration, or a bit earlier + // to allow it to ease out while moving? + ease_out_time = motion->getEaseOutDuration(); + + // is the clock running when the motion is easing in? + // if not (POSTURE_EASE) then we need to wait that much longer before triggering the stop + motion_duration = llmax(motion->getDuration() - ease_out_time, 0.f); + motion->mSendStopTimestamp = time + motion_duration; + } + else + { + motion->mSendStopTimestamp = F32_MAX; + } + + if (motion->isActive()) + { + mActiveMotions.remove(motion); + } + mActiveMotions.push_front(motion); + + motion->activate(time); + motion->onUpdate(0.f, mJointSignature[1]); + + if (mAnimTime >= motion->mSendStopTimestamp) + { + motion->setStopTime(motion->mSendStopTimestamp); + if (motion->mResidualWeight == 0.0f) + { + // bit of a hack; if newly activating a motion while easing out, weight should = 1 + motion->mResidualWeight = 1.f; + } + } + + return TRUE; } //----------------------------------------------------------------------------- @@ -986,32 +986,32 @@ BOOL LLMotionController::activateMotionInstance(LLMotion *motion, F32 time) //----------------------------------------------------------------------------- BOOL LLMotionController::deactivateMotionInstance(LLMotion *motion) { - motion->deactivate(); - - motion_set_t::iterator found_it = mDeprecatedMotions.find(motion); - if (found_it != mDeprecatedMotions.end()) - { - // deprecated motions need to be completely excised - removeMotionInstance(motion); - mDeprecatedMotions.erase(found_it); - } - else - { - // for motions that we are keeping, simply remove from active queue - mActiveMotions.remove(motion); - } - - return TRUE; + motion->deactivate(); + + motion_set_t::iterator found_it = mDeprecatedMotions.find(motion); + if (found_it != mDeprecatedMotions.end()) + { + // deprecated motions need to be completely excised + removeMotionInstance(motion); + mDeprecatedMotions.erase(found_it); + } + else + { + // for motions that we are keeping, simply remove from active queue + mActiveMotions.remove(motion); + } + + return TRUE; } void LLMotionController::deprecateMotionInstance(LLMotion* motion) { - mDeprecatedMotions.insert(motion); + mDeprecatedMotions.insert(motion); - //fade out deprecated motion - stopMotionInstance(motion, FALSE); - //no longer canonical - mAllMotions.erase(motion->getID()); + //fade out deprecated motion + stopMotionInstance(motion, FALSE); + //no longer canonical + mAllMotions.erase(motion->getID()); } //----------------------------------------------------------------------------- @@ -1019,7 +1019,7 @@ void LLMotionController::deprecateMotionInstance(LLMotion* motion) //----------------------------------------------------------------------------- bool LLMotionController::isMotionActive(LLMotion *motion) { - return (motion && motion->isActive()); + return (motion && motion->isActive()); } //----------------------------------------------------------------------------- @@ -1027,7 +1027,7 @@ bool LLMotionController::isMotionActive(LLMotion *motion) //----------------------------------------------------------------------------- bool LLMotionController::isMotionLoading(LLMotion* motion) { - return (mLoadingMotions.find(motion) != mLoadingMotions.end()); + return (mLoadingMotions.find(motion) != mLoadingMotions.end()); } @@ -1036,15 +1036,15 @@ bool LLMotionController::isMotionLoading(LLMotion* motion) //----------------------------------------------------------------------------- LLMotion* LLMotionController::findMotion(const LLUUID& id) const { - motion_map_t::const_iterator iter = mAllMotions.find(id); - if(iter == mAllMotions.end()) - { - return NULL; - } - else - { - return iter->second; - } + motion_map_t::const_iterator iter = mAllMotions.find(id); + if(iter == mAllMotions.end()) + { + return NULL; + } + else + { + return iter->second; + } } //----------------------------------------------------------------------------- @@ -1052,23 +1052,23 @@ LLMotion* LLMotionController::findMotion(const LLUUID& id) const //----------------------------------------------------------------------------- void LLMotionController::dumpMotions() { - LL_INFOS() << "=====================================" << LL_ENDL; - for (motion_map_t::value_type& motion_pair : mAllMotions) - { - LLUUID id = motion_pair.first; - std::string state_string; - LLMotion *motion = motion_pair.second; - if (mLoadingMotions.find(motion) != mLoadingMotions.end()) - state_string += std::string("l"); - if (mLoadedMotions.find(motion) != mLoadedMotions.end()) - state_string += std::string("L"); - if (std::find(mActiveMotions.begin(), mActiveMotions.end(), motion)!=mActiveMotions.end()) - state_string += std::string("A"); - if (mDeprecatedMotions.find(motion) != mDeprecatedMotions.end()) - state_string += std::string("D"); - LL_INFOS() << gAnimLibrary.animationName(id) << " " << state_string << LL_ENDL; - - } + LL_INFOS() << "=====================================" << LL_ENDL; + for (motion_map_t::value_type& motion_pair : mAllMotions) + { + LLUUID id = motion_pair.first; + std::string state_string; + LLMotion *motion = motion_pair.second; + if (mLoadingMotions.find(motion) != mLoadingMotions.end()) + state_string += std::string("l"); + if (mLoadedMotions.find(motion) != mLoadedMotions.end()) + state_string += std::string("L"); + if (std::find(mActiveMotions.begin(), mActiveMotions.end(), motion)!=mActiveMotions.end()) + state_string += std::string("A"); + if (mDeprecatedMotions.find(motion) != mDeprecatedMotions.end()) + state_string += std::string("D"); + LL_INFOS() << gAnimLibrary.animationName(id) << " " << state_string << LL_ENDL; + + } } //----------------------------------------------------------------------------- @@ -1076,11 +1076,11 @@ void LLMotionController::dumpMotions() //----------------------------------------------------------------------------- void LLMotionController::deactivateAllMotions() { - for (motion_map_t::value_type& motion_pair : mAllMotions) - { - LLMotion* motionp = motion_pair.second; - deactivateMotionInstance(motionp); - } + for (motion_map_t::value_type& motion_pair : mAllMotions) + { + LLMotion* motionp = motion_pair.second; + deactivateMotionInstance(motionp); + } } @@ -1089,31 +1089,31 @@ void LLMotionController::deactivateAllMotions() //----------------------------------------------------------------------------- void LLMotionController::flushAllMotions() { - std::vector<std::pair<LLUUID,F32> > active_motions; - active_motions.reserve(mActiveMotions.size()); - for (motion_list_t::iterator iter = mActiveMotions.begin(); - iter != mActiveMotions.end(); ) - { - motion_list_t::iterator curiter = iter++; - LLMotion* motionp = *curiter; - F32 dtime = mAnimTime - motionp->mActivationTimestamp; - active_motions.push_back(std::make_pair(motionp->getID(),dtime)); - motionp->deactivate(); // don't call deactivateMotionInstance() because we are going to reactivate it - } - mActiveMotions.clear(); - - // delete all motion instances - deleteAllMotions(); - - // kill current hand pose that was previously called out by - // keyframe motion - mCharacter->removeAnimationData("Hand Pose"); - - // restart motions - for (std::vector<std::pair<LLUUID,F32> >::value_type& motion_pair : active_motions) - { - startMotion(motion_pair.first, motion_pair.second); - } + std::vector<std::pair<LLUUID,F32> > active_motions; + active_motions.reserve(mActiveMotions.size()); + for (motion_list_t::iterator iter = mActiveMotions.begin(); + iter != mActiveMotions.end(); ) + { + motion_list_t::iterator curiter = iter++; + LLMotion* motionp = *curiter; + F32 dtime = mAnimTime - motionp->mActivationTimestamp; + active_motions.push_back(std::make_pair(motionp->getID(),dtime)); + motionp->deactivate(); // don't call deactivateMotionInstance() because we are going to reactivate it + } + mActiveMotions.clear(); + + // delete all motion instances + deleteAllMotions(); + + // kill current hand pose that was previously called out by + // keyframe motion + mCharacter->removeAnimationData("Hand Pose"); + + // restart motions + for (std::vector<std::pair<LLUUID,F32> >::value_type& motion_pair : active_motions) + { + startMotion(motion_pair.first, motion_pair.second); + } } //----------------------------------------------------------------------------- @@ -1121,13 +1121,13 @@ void LLMotionController::flushAllMotions() //----------------------------------------------------------------------------- void LLMotionController::pauseAllMotions() { - if (!mPaused) - { - //LL_INFOS() << "Pausing animations..." << LL_ENDL; - mPaused = TRUE; + if (!mPaused) + { + //LL_INFOS() << "Pausing animations..." << LL_ENDL; + mPaused = TRUE; mPausedFrame = LLFrameTimer::getFrameCount(); - } - + } + } //----------------------------------------------------------------------------- @@ -1135,10 +1135,10 @@ void LLMotionController::pauseAllMotions() //----------------------------------------------------------------------------- void LLMotionController::unpauseAllMotions() { - if (mPaused) - { - //LL_INFOS() << "Unpausing animations..." << LL_ENDL; - mPaused = FALSE; - } + if (mPaused) + { + //LL_INFOS() << "Unpausing animations..." << LL_ENDL; + mPaused = FALSE; + } } // End diff --git a/indra/llcharacter/llmotioncontroller.h b/indra/llcharacter/llmotioncontroller.h index 637ee4d2bb..67193b0cf3 100644 --- a/indra/llcharacter/llmotioncontroller.h +++ b/indra/llcharacter/llmotioncontroller.h @@ -1,25 +1,25 @@ -/** +/** * @file llmotioncontroller.h * @brief Implementation of LLMotionController class. * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -54,27 +54,27 @@ typedef LLMotion*(*LLMotionConstructor)(const LLUUID &id); class LLMotionRegistry { public: - // Constructor - LLMotionRegistry(); + // Constructor + LLMotionRegistry(); - // Destructor - ~LLMotionRegistry(); + // Destructor + ~LLMotionRegistry(); - // adds motion classes to the registry - // returns true if successfull - BOOL registerMotion( const LLUUID& id, LLMotionConstructor create); + // adds motion classes to the registry + // returns true if successfull + BOOL registerMotion( const LLUUID& id, LLMotionConstructor create); - // creates a new instance of a named motion - // returns NULL motion is not registered - LLMotion *createMotion( const LLUUID &id ); + // creates a new instance of a named motion + // returns NULL motion is not registered + LLMotion *createMotion( const LLUUID &id ); - // initialization of motion failed, don't try to create this motion again - void markBad( const LLUUID& id ); + // initialization of motion failed, don't try to create this motion again + void markBad( const LLUUID& id ); protected: - typedef std::map<LLUUID, LLMotionConstructor> motion_map_t; - motion_map_t mMotionTable; + typedef std::map<LLUUID, LLMotionConstructor> motion_map_t; + motion_map_t mMotionTable; }; //----------------------------------------------------------------------------- @@ -83,153 +83,153 @@ protected: class LLMotionController { public: - typedef std::list<LLMotion*> motion_list_t; - typedef std::set<LLMotion*> motion_set_t; - BOOL mIsSelf; - + typedef std::list<LLMotion*> motion_list_t; + typedef std::set<LLMotion*> motion_set_t; + BOOL mIsSelf; + public: - // Constructor - LLMotionController(); - - // Destructor - virtual ~LLMotionController(); - - // set associated character - // this must be called exactly once by the containing character class. - // this is generally done in the Character constructor - void setCharacter( LLCharacter *character ); - - // registers a motion with the controller - // (actually just forwards call to motion registry) - // returns true if successfull - BOOL registerMotion( const LLUUID& id, LLMotionConstructor create ); - - // creates a motion from the registry - LLMotion *createMotion( const LLUUID &id ); - - // unregisters a motion with the controller - // (actually just forwards call to motion registry) - // returns true if successfull - void removeMotion( const LLUUID& id ); - - // start motion - // begins playing the specified motion - // returns true if successful - BOOL startMotion( const LLUUID &id, F32 start_offset ); - - // stop motion - // stops a playing motion - // in reality, it begins the ease out transition phase - // returns true if successful - BOOL stopMotionLocally( const LLUUID &id, BOOL stop_immediate ); - - // Move motions from loading to loaded - void updateLoadingMotions(); - - // update motions - // invokes the update handlers for each active motion - // activates sequenced motions - // deactivates terminated motions` - void updateMotions(bool force_update = false); - - // minimal update (e.g. while hidden) - void updateMotionsMinimal(); - - void clearBlenders() { mPoseBlender.clearBlenders(); } - - // flush motions - // releases all motion instances - void flushAllMotions(); - - //Flush is a liar. - void deactivateAllMotions(); - - // pause and continue all motions - void pauseAllMotions(); - void unpauseAllMotions(); - BOOL isPaused() const { return mPaused; } + // Constructor + LLMotionController(); + + // Destructor + virtual ~LLMotionController(); + + // set associated character + // this must be called exactly once by the containing character class. + // this is generally done in the Character constructor + void setCharacter( LLCharacter *character ); + + // registers a motion with the controller + // (actually just forwards call to motion registry) + // returns true if successfull + BOOL registerMotion( const LLUUID& id, LLMotionConstructor create ); + + // creates a motion from the registry + LLMotion *createMotion( const LLUUID &id ); + + // unregisters a motion with the controller + // (actually just forwards call to motion registry) + // returns true if successfull + void removeMotion( const LLUUID& id ); + + // start motion + // begins playing the specified motion + // returns true if successful + BOOL startMotion( const LLUUID &id, F32 start_offset ); + + // stop motion + // stops a playing motion + // in reality, it begins the ease out transition phase + // returns true if successful + BOOL stopMotionLocally( const LLUUID &id, BOOL stop_immediate ); + + // Move motions from loading to loaded + void updateLoadingMotions(); + + // update motions + // invokes the update handlers for each active motion + // activates sequenced motions + // deactivates terminated motions` + void updateMotions(bool force_update = false); + + // minimal update (e.g. while hidden) + void updateMotionsMinimal(); + + void clearBlenders() { mPoseBlender.clearBlenders(); } + + // flush motions + // releases all motion instances + void flushAllMotions(); + + //Flush is a liar. + void deactivateAllMotions(); + + // pause and continue all motions + void pauseAllMotions(); + void unpauseAllMotions(); + BOOL isPaused() const { return mPaused; } S32 getPausedFrame() const { return mPausedFrame; } - void setTimeStep(F32 step); + void setTimeStep(F32 step); F32 getTimeStep() const { return mTimeStep; } - void setTimeFactor(F32 time_factor); - F32 getTimeFactor() const { return mTimeFactor; } + void setTimeFactor(F32 time_factor); + F32 getTimeFactor() const { return mTimeFactor; } F32 getAnimTime() const { return mAnimTime; } - - motion_list_t& getActiveMotions() { return mActiveMotions; } - void incMotionCounts(S32& num_motions, S32& num_loading_motions, S32& num_loaded_motions, S32& num_active_motions, S32& num_deprecated_motions); - + motion_list_t& getActiveMotions() { return mActiveMotions; } + + void incMotionCounts(S32& num_motions, S32& num_loading_motions, S32& num_loaded_motions, S32& num_active_motions, S32& num_deprecated_motions); + //protected: - bool isMotionActive( LLMotion *motion ); - bool isMotionLoading( LLMotion *motion ); - LLMotion *findMotion( const LLUUID& id ) const; + bool isMotionActive( LLMotion *motion ); + bool isMotionLoading( LLMotion *motion ); + LLMotion *findMotion( const LLUUID& id ) const; - void dumpMotions(); + void dumpMotions(); - const LLFrameTimer& getFrameTimer() { return mTimer; } + const LLFrameTimer& getFrameTimer() { return mTimer; } - static F32 getCurrentTimeFactor() { return sCurrentTimeFactor; }; - static void setCurrentTimeFactor(F32 factor) { sCurrentTimeFactor = factor; }; + static F32 getCurrentTimeFactor() { return sCurrentTimeFactor; }; + static void setCurrentTimeFactor(F32 factor) { sCurrentTimeFactor = factor; }; protected: - // internal operations act on motion instances directly - // as there can be duplicate motions per id during blending overlap - void deleteAllMotions(); - BOOL activateMotionInstance(LLMotion *motion, F32 time); - BOOL deactivateMotionInstance(LLMotion *motion); - void deprecateMotionInstance(LLMotion* motion); - BOOL stopMotionInstance(LLMotion *motion, BOOL stop_imemdiate); - void removeMotionInstance(LLMotion* motion); - void updateRegularMotions(); - void updateAdditiveMotions(); - void resetJointSignatures(); - void updateMotionsByType(LLMotion::LLMotionBlendType motion_type); - void updateIdleMotion(LLMotion* motionp); - void updateIdleActiveMotions(); - void purgeExcessMotions(); - void deactivateStoppedMotions(); + // internal operations act on motion instances directly + // as there can be duplicate motions per id during blending overlap + void deleteAllMotions(); + BOOL activateMotionInstance(LLMotion *motion, F32 time); + BOOL deactivateMotionInstance(LLMotion *motion); + void deprecateMotionInstance(LLMotion* motion); + BOOL stopMotionInstance(LLMotion *motion, BOOL stop_imemdiate); + void removeMotionInstance(LLMotion* motion); + void updateRegularMotions(); + void updateAdditiveMotions(); + void resetJointSignatures(); + void updateMotionsByType(LLMotion::LLMotionBlendType motion_type); + void updateIdleMotion(LLMotion* motionp); + void updateIdleActiveMotions(); + void purgeExcessMotions(); + void deactivateStoppedMotions(); protected: - F32 mTimeFactor; // 1.f for normal speed - static F32 sCurrentTimeFactor; // Value to use for initialization - static LLMotionRegistry sRegistry; - LLPoseBlender mPoseBlender; + F32 mTimeFactor; // 1.f for normal speed + static F32 sCurrentTimeFactor; // Value to use for initialization + static LLMotionRegistry sRegistry; + LLPoseBlender mPoseBlender; - LLCharacter *mCharacter; + LLCharacter *mCharacter; -// Life cycle of an animation: +// Life cycle of an animation: // -// Animations are instantiated and immediately put in the mAllMotions map for their entire lifetime. -// If the animations depend on any asset data, the appropriate data is fetched from the data server, -// and the animation is put on the mLoadingMotions list. -// Once an animations is loaded, it will be initialized and put on the mLoadedMotions list. -// Any animation that is currently playing also sits in the mActiveMotions list. - - typedef std::map<LLUUID, LLMotion*> motion_map_t; - motion_map_t mAllMotions; - - motion_set_t mLoadingMotions; - motion_set_t mLoadedMotions; - motion_list_t mActiveMotions; - motion_set_t mDeprecatedMotions; - - LLFrameTimer mTimer; - F32 mPrevTimerElapsed; - F32 mAnimTime; - F32 mLastTime; - BOOL mHasRunOnce; - BOOL mPaused; - S32 mPausedFrame; - F32 mTimeStep; - S32 mTimeStepCount; - F32 mLastInterp; - - U8 mJointSignature[2][LL_CHARACTER_MAX_ANIMATED_JOINTS]; +// Animations are instantiated and immediately put in the mAllMotions map for their entire lifetime. +// If the animations depend on any asset data, the appropriate data is fetched from the data server, +// and the animation is put on the mLoadingMotions list. +// Once an animations is loaded, it will be initialized and put on the mLoadedMotions list. +// Any animation that is currently playing also sits in the mActiveMotions list. + + typedef std::map<LLUUID, LLMotion*> motion_map_t; + motion_map_t mAllMotions; + + motion_set_t mLoadingMotions; + motion_set_t mLoadedMotions; + motion_list_t mActiveMotions; + motion_set_t mDeprecatedMotions; + + LLFrameTimer mTimer; + F32 mPrevTimerElapsed; + F32 mAnimTime; + F32 mLastTime; + BOOL mHasRunOnce; + BOOL mPaused; + S32 mPausedFrame; + F32 mTimeStep; + S32 mTimeStepCount; + F32 mLastInterp; + + U8 mJointSignature[2][LL_CHARACTER_MAX_ANIMATED_JOINTS]; private: - U32 mLastCountAfterPurge; //for logging and debugging purposes + U32 mLastCountAfterPurge; //for logging and debugging purposes }; //----------------------------------------------------------------------------- diff --git a/indra/llcharacter/llmultigesture.cpp b/indra/llcharacter/llmultigesture.cpp index 7ed242f90a..e5ca051f82 100644 --- a/indra/llcharacter/llmultigesture.cpp +++ b/indra/llcharacter/llmultigesture.cpp @@ -1,25 +1,25 @@ -/** +/** * @file llmultigesture.cpp * @brief Gestures that are asset-based and can have multiple steps. * * $LicenseInfo:firstyear=2004&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -42,204 +42,197 @@ const S32 GESTURE_VERSION = 2; // LLMultiGesture //--------------------------------------------------------------------------- LLMultiGesture::LLMultiGesture() -: mKey(), - mMask(), - mName(), - mTrigger(), - mReplaceText(), - mSteps(), - mPlaying(FALSE), - mCurrentStep(0), - mDoneCallback(NULL), - mCallbackData(NULL) { - reset(); + reset(); } LLMultiGesture::~LLMultiGesture() { - std::for_each(mSteps.begin(), mSteps.end(), DeletePointer()); - mSteps.clear(); + std::for_each(mSteps.begin(), mSteps.end(), DeletePointer()); + mSteps.clear(); } void LLMultiGesture::reset() { - mPlaying = FALSE; - mCurrentStep = 0; - mWaitTimer.reset(); - mWaitingTimer = FALSE; - mWaitingAnimations = FALSE; - mWaitingAtEnd = FALSE; - mRequestedAnimIDs.clear(); - mPlayingAnimIDs.clear(); + mPlaying = FALSE; + mCurrentStep = 0; + mWaitTimer.reset(); + mWaitingAnimations = FALSE; + mWaitingKeyRelease = FALSE; + mWaitingTimer = FALSE; + mTriggeredByKey = FALSE; + mKeyReleased = FALSE; + mWaitingAtEnd = FALSE; + mRequestedAnimIDs.clear(); + mPlayingAnimIDs.clear(); } S32 LLMultiGesture::getMaxSerialSize() const { - S32 max_size = 0; - - // ascii format, being very conservative about possible - // label lengths. - max_size += 64; // version S32 - max_size += 64; // key U8 - max_size += 64; // mask U32 - max_size += 256; // trigger string - max_size += 256; // replace string - - max_size += 64; // step count S32 - - for (LLGestureStep* step : mSteps) - { - max_size += 64; // type S32 - max_size += step->getMaxSerialSize(); - } - - /* binary format - max_size += sizeof(S32); // version - max_size += sizeof(mKey); - max_size += sizeof(mMask); - max_size += mTrigger.length() + 1; // for null - - max_size += sizeof(S32); // step count - - std::vector<LLGestureStep*>::const_iterator it; - for (it = mSteps.begin(); it != mSteps.end(); ++it) - { - LLGestureStep* step = *it; - max_size += sizeof(S32); // type - max_size += step->getMaxSerialSize(); - } - */ - - return max_size; + S32 max_size = 0; + + // ascii format, being very conservative about possible + // label lengths. + max_size += 64; // version S32 + max_size += 64; // key U8 + max_size += 64; // mask U32 + max_size += 256; // trigger string + max_size += 256; // replace string + + max_size += 64; // step count S32 + + for (LLGestureStep* step : mSteps) + { + max_size += 64; // type S32 + max_size += step->getMaxSerialSize(); + } + + /* binary format + max_size += sizeof(S32); // version + max_size += sizeof(mKey); + max_size += sizeof(mMask); + max_size += mTrigger.length() + 1; // for null + + max_size += sizeof(S32); // step count + + std::vector<LLGestureStep*>::const_iterator it; + for (it = mSteps.begin(); it != mSteps.end(); ++it) + { + LLGestureStep* step = *it; + max_size += sizeof(S32); // type + max_size += step->getMaxSerialSize(); + } + */ + + return max_size; } BOOL LLMultiGesture::serialize(LLDataPacker& dp) const { - dp.packS32(GESTURE_VERSION, "version"); - dp.packU8(mKey, "key"); - dp.packU32(mMask, "mask"); - dp.packString(mTrigger, "trigger"); - dp.packString(mReplaceText, "replace"); - - S32 count = (S32)mSteps.size(); - dp.packS32(count, "step_count"); - S32 i; - for (i = 0; i < count; ++i) - { - LLGestureStep* step = mSteps[i]; - - dp.packS32(step->getType(), "step_type"); - BOOL ok = step->serialize(dp); - if (!ok) - { - return FALSE; - } - } - return TRUE; + dp.packS32(GESTURE_VERSION, "version"); + dp.packU8(mKey, "key"); + dp.packU32(mMask, "mask"); + dp.packString(mTrigger, "trigger"); + dp.packString(mReplaceText, "replace"); + + S32 count = (S32)mSteps.size(); + dp.packS32(count, "step_count"); + S32 i; + for (i = 0; i < count; ++i) + { + LLGestureStep* step = mSteps[i]; + + dp.packS32(step->getType(), "step_type"); + BOOL ok = step->serialize(dp); + if (!ok) + { + return FALSE; + } + } + return TRUE; } BOOL LLMultiGesture::deserialize(LLDataPacker& dp) { - S32 version; - dp.unpackS32(version, "version"); - if (version != GESTURE_VERSION) - { - LL_WARNS() << "Bad LLMultiGesture version " << version - << " should be " << GESTURE_VERSION - << LL_ENDL; - return FALSE; - } - - dp.unpackU8(mKey, "key"); - dp.unpackU32(mMask, "mask"); - - - dp.unpackString(mTrigger, "trigger"); - - dp.unpackString(mReplaceText, "replace"); - - S32 count; - dp.unpackS32(count, "step_count"); - if (count < 0) - { - LL_WARNS() << "Bad LLMultiGesture step count " << count << LL_ENDL; - return FALSE; - } - - S32 i; - for (i = 0; i < count; ++i) - { - S32 type; - dp.unpackS32(type, "step_type"); - - EStepType step_type = (EStepType)type; - switch(step_type) - { - case STEP_ANIMATION: - { - LLGestureStepAnimation* step = new LLGestureStepAnimation(); - BOOL ok = step->deserialize(dp); - if (!ok) return FALSE; - mSteps.push_back(step); - break; - } - case STEP_SOUND: - { - LLGestureStepSound* step = new LLGestureStepSound(); - BOOL ok = step->deserialize(dp); - if (!ok) return FALSE; - mSteps.push_back(step); - break; - } - case STEP_CHAT: - { - LLGestureStepChat* step = new LLGestureStepChat(); - BOOL ok = step->deserialize(dp); - if (!ok) return FALSE; - mSteps.push_back(step); - break; - } - case STEP_WAIT: - { - LLGestureStepWait* step = new LLGestureStepWait(); - BOOL ok = step->deserialize(dp); - if (!ok) return FALSE; - mSteps.push_back(step); - break; - } - default: - { - LL_WARNS() << "Bad LLMultiGesture step type " << type << LL_ENDL; - return FALSE; - } - } - } - return TRUE; + S32 version; + dp.unpackS32(version, "version"); + if (version != GESTURE_VERSION) + { + LL_WARNS() << "Bad LLMultiGesture version " << version + << " should be " << GESTURE_VERSION + << LL_ENDL; + return FALSE; + } + + dp.unpackU8(mKey, "key"); + dp.unpackU32(mMask, "mask"); + + + dp.unpackString(mTrigger, "trigger"); + + dp.unpackString(mReplaceText, "replace"); + + S32 count; + dp.unpackS32(count, "step_count"); + if (count < 0) + { + LL_WARNS() << "Bad LLMultiGesture step count " << count << LL_ENDL; + return FALSE; + } + + S32 i; + for (i = 0; i < count; ++i) + { + S32 type; + dp.unpackS32(type, "step_type"); + + EStepType step_type = (EStepType)type; + switch(step_type) + { + case STEP_ANIMATION: + { + LLGestureStepAnimation* step = new LLGestureStepAnimation(); + BOOL ok = step->deserialize(dp); + if (!ok) return FALSE; + mSteps.push_back(step); + break; + } + case STEP_SOUND: + { + LLGestureStepSound* step = new LLGestureStepSound(); + BOOL ok = step->deserialize(dp); + if (!ok) return FALSE; + mSteps.push_back(step); + break; + } + case STEP_CHAT: + { + LLGestureStepChat* step = new LLGestureStepChat(); + BOOL ok = step->deserialize(dp); + if (!ok) return FALSE; + mSteps.push_back(step); + break; + } + case STEP_WAIT: + { + LLGestureStepWait* step = new LLGestureStepWait(); + BOOL ok = step->deserialize(dp); + if (!ok) return FALSE; + mSteps.push_back(step); + break; + } + default: + { + LL_WARNS() << "Bad LLMultiGesture step type " << type << LL_ENDL; + return FALSE; + } + } + } + return TRUE; } void LLMultiGesture::dump() { - LL_INFOS() << "key " << S32(mKey) << " mask " << U32(mMask) - << " trigger " << mTrigger - << " replace " << mReplaceText - << LL_ENDL; - U32 i; - for (i = 0; i < mSteps.size(); ++i) - { - LLGestureStep* step = mSteps[i]; - step->dump(); - } + LL_INFOS() << "key " << S32(mKey) << " mask " << U32(mMask) + << " trigger " << mTrigger + << " replace " << mReplaceText + << LL_ENDL; + U32 i; + for (i = 0; i < mSteps.size(); ++i) + { + LLGestureStep* step = mSteps[i]; + step->dump(); + } } //--------------------------------------------------------------------------- // LLGestureStepAnimation //--------------------------------------------------------------------------- LLGestureStepAnimation::LLGestureStepAnimation() -: LLGestureStep(), - mAnimName("None"), - mAnimAssetID(), - mFlags(0x0) +: LLGestureStep(), + mAnimName("None"), + mAnimAssetID(), + mFlags(0x0) { } LLGestureStepAnimation::~LLGestureStepAnimation() @@ -247,84 +240,84 @@ LLGestureStepAnimation::~LLGestureStepAnimation() S32 LLGestureStepAnimation::getMaxSerialSize() const { - S32 max_size = 0; - - // ascii - max_size += 256; // anim name - max_size += 64; // anim asset id - max_size += 64; // flags - - /* binary - max_size += mAnimName.length() + 1; - max_size += sizeof(mAnimAssetID); - max_size += sizeof(mFlags); - */ - return max_size; + S32 max_size = 0; + + // ascii + max_size += 256; // anim name + max_size += 64; // anim asset id + max_size += 64; // flags + + /* binary + max_size += mAnimName.length() + 1; + max_size += sizeof(mAnimAssetID); + max_size += sizeof(mFlags); + */ + return max_size; } BOOL LLGestureStepAnimation::serialize(LLDataPacker& dp) const { - dp.packString(mAnimName, "anim_name"); - dp.packUUID(mAnimAssetID, "asset_id"); - dp.packU32(mFlags, "flags"); - return TRUE; + dp.packString(mAnimName, "anim_name"); + dp.packUUID(mAnimAssetID, "asset_id"); + dp.packU32(mFlags, "flags"); + return TRUE; } BOOL LLGestureStepAnimation::deserialize(LLDataPacker& dp) { - dp.unpackString(mAnimName, "anim_name"); - - // Apparently an earlier version of the gesture code added \r to the end - // of the animation names. Get rid of it. JC - if (!mAnimName.empty() && mAnimName[mAnimName.length() - 1] == '\r') - { - // chop the last character - mAnimName.resize(mAnimName.length() - 1); - } - - dp.unpackUUID(mAnimAssetID, "asset_id"); - dp.unpackU32(mFlags, "flags"); - return TRUE; + dp.unpackString(mAnimName, "anim_name"); + + // Apparently an earlier version of the gesture code added \r to the end + // of the animation names. Get rid of it. JC + if (!mAnimName.empty() && mAnimName[mAnimName.length() - 1] == '\r') + { + // chop the last character + mAnimName.resize(mAnimName.length() - 1); + } + + dp.unpackUUID(mAnimAssetID, "asset_id"); + dp.unpackU32(mFlags, "flags"); + return TRUE; } // *NOTE: result is translated in LLPreviewGesture::getLabel() -std::vector<std::string> LLGestureStepAnimation::getLabel() const +std::vector<std::string> LLGestureStepAnimation::getLabel() const { - std::vector<std::string> strings; - -// std::string label; - if (mFlags & ANIM_FLAG_STOP) - { - strings.push_back( "AnimFlagStop"); - -// label = "Stop Animation: "; - } - else - { - strings.push_back( "AnimFlagStart"); - -// label = "Start Animation: "; - } - strings.push_back( mAnimName); -// label += mAnimName; - return strings; + std::vector<std::string> strings; + +// std::string label; + if (mFlags & ANIM_FLAG_STOP) + { + strings.push_back( "AnimFlagStop"); + +// label = "Stop Animation: "; + } + else + { + strings.push_back( "AnimFlagStart"); + +// label = "Start Animation: "; + } + strings.push_back( mAnimName); +// label += mAnimName; + return strings; } void LLGestureStepAnimation::dump() { - LL_INFOS() << "step animation " << mAnimName - << " id " << mAnimAssetID - << " flags " << mFlags - << LL_ENDL; + LL_INFOS() << "step animation " << mAnimName + << " id " << mAnimAssetID + << " flags " << mFlags + << LL_ENDL; } //--------------------------------------------------------------------------- // LLGestureStepSound //--------------------------------------------------------------------------- LLGestureStepSound::LLGestureStepSound() -: LLGestureStep(), - mSoundName("None"), - mSoundAssetID(), - mFlags(0x0) +: LLGestureStep(), + mSoundName("None"), + mSoundAssetID(), + mFlags(0x0) { } LLGestureStepSound::~LLGestureStepSound() @@ -332,51 +325,51 @@ LLGestureStepSound::~LLGestureStepSound() S32 LLGestureStepSound::getMaxSerialSize() const { - S32 max_size = 0; - max_size += 256; // sound name - max_size += 64; // sound asset id - max_size += 64; // flags - /* binary - max_size += mSoundName.length() + 1; - max_size += sizeof(mSoundAssetID); - max_size += sizeof(mFlags); - */ - return max_size; + S32 max_size = 0; + max_size += 256; // sound name + max_size += 64; // sound asset id + max_size += 64; // flags + /* binary + max_size += mSoundName.length() + 1; + max_size += sizeof(mSoundAssetID); + max_size += sizeof(mFlags); + */ + return max_size; } BOOL LLGestureStepSound::serialize(LLDataPacker& dp) const { - dp.packString(mSoundName, "sound_name"); - dp.packUUID(mSoundAssetID, "asset_id"); - dp.packU32(mFlags, "flags"); - return TRUE; + dp.packString(mSoundName, "sound_name"); + dp.packUUID(mSoundAssetID, "asset_id"); + dp.packU32(mFlags, "flags"); + return TRUE; } BOOL LLGestureStepSound::deserialize(LLDataPacker& dp) { - dp.unpackString(mSoundName, "sound_name"); + dp.unpackString(mSoundName, "sound_name"); - dp.unpackUUID(mSoundAssetID, "asset_id"); - dp.unpackU32(mFlags, "flags"); - return TRUE; + dp.unpackUUID(mSoundAssetID, "asset_id"); + dp.unpackU32(mFlags, "flags"); + return TRUE; } // *NOTE: result is translated in LLPreviewGesture::getLabel() std::vector<std::string> LLGestureStepSound::getLabel() const { - std::vector<std::string> strings; - strings.push_back( "Sound"); - strings.push_back( mSoundName); -// std::string label("Sound: "); -// label += mSoundName; - return strings; + std::vector<std::string> strings; + strings.push_back( "Sound"); + strings.push_back( mSoundName); +// std::string label("Sound: "); +// label += mSoundName; + return strings; } void LLGestureStepSound::dump() { - LL_INFOS() << "step sound " << mSoundName - << " id " << mSoundAssetID - << " flags " << mFlags - << LL_ENDL; + LL_INFOS() << "step sound " << mSoundName + << " id " << mSoundAssetID + << " flags " << mFlags + << LL_ENDL; } @@ -384,9 +377,9 @@ void LLGestureStepSound::dump() // LLGestureStepChat //--------------------------------------------------------------------------- LLGestureStepChat::LLGestureStepChat() -: LLGestureStep(), - mChatText(), - mFlags(0x0) +: LLGestureStep(), + mChatText(), + mFlags(0x0) { } LLGestureStepChat::~LLGestureStepChat() @@ -394,44 +387,44 @@ LLGestureStepChat::~LLGestureStepChat() S32 LLGestureStepChat::getMaxSerialSize() const { - S32 max_size = 0; - max_size += 256; // chat text - max_size += 64; // flags - /* binary - max_size += mChatText.length() + 1; - max_size += sizeof(mFlags); - */ - return max_size; + S32 max_size = 0; + max_size += 256; // chat text + max_size += 64; // flags + /* binary + max_size += mChatText.length() + 1; + max_size += sizeof(mFlags); + */ + return max_size; } BOOL LLGestureStepChat::serialize(LLDataPacker& dp) const { - dp.packString(mChatText, "chat_text"); - dp.packU32(mFlags, "flags"); - return TRUE; + dp.packString(mChatText, "chat_text"); + dp.packU32(mFlags, "flags"); + return TRUE; } BOOL LLGestureStepChat::deserialize(LLDataPacker& dp) { - dp.unpackString(mChatText, "chat_text"); + dp.unpackString(mChatText, "chat_text"); - dp.unpackU32(mFlags, "flags"); - return TRUE; + dp.unpackU32(mFlags, "flags"); + return TRUE; } // *NOTE: result is translated in LLPreviewGesture::getLabel() std::vector<std::string> LLGestureStepChat::getLabel() const { - std::vector<std::string> strings; - strings.push_back("Chat"); - strings.push_back(mChatText); - return strings; + std::vector<std::string> strings; + strings.push_back("Chat"); + strings.push_back(mChatText); + return strings; } void LLGestureStepChat::dump() { - LL_INFOS() << "step chat " << mChatText - << " flags " << mFlags - << LL_ENDL; + LL_INFOS() << "step chat " << mChatText + << " flags " << mFlags + << LL_ENDL; } @@ -439,9 +432,9 @@ void LLGestureStepChat::dump() // LLGestureStepWait //--------------------------------------------------------------------------- LLGestureStepWait::LLGestureStepWait() -: LLGestureStep(), - mWaitSeconds(0.f), - mFlags(0x0) +: LLGestureStep(), + mWaitSeconds(0.f), + mFlags(0x0) { } LLGestureStepWait::~LLGestureStepWait() @@ -449,60 +442,60 @@ LLGestureStepWait::~LLGestureStepWait() S32 LLGestureStepWait::getMaxSerialSize() const { - S32 max_size = 0; - max_size += 64; // wait seconds - max_size += 64; // flags - /* binary - max_size += sizeof(mWaitSeconds); - max_size += sizeof(mFlags); - */ - return max_size; + S32 max_size = 0; + max_size += 64; // wait seconds + max_size += 64; // flags + /* binary + max_size += sizeof(mWaitSeconds); + max_size += sizeof(mFlags); + */ + return max_size; } BOOL LLGestureStepWait::serialize(LLDataPacker& dp) const { - dp.packF32(mWaitSeconds, "wait_seconds"); - dp.packU32(mFlags, "flags"); - return TRUE; + dp.packF32(mWaitSeconds, "wait_seconds"); + dp.packU32(mFlags, "flags"); + return TRUE; } BOOL LLGestureStepWait::deserialize(LLDataPacker& dp) { - dp.unpackF32(mWaitSeconds, "wait_seconds"); - dp.unpackU32(mFlags, "flags"); - return TRUE; + dp.unpackF32(mWaitSeconds, "wait_seconds"); + dp.unpackU32(mFlags, "flags"); + return TRUE; } // *NOTE: result is translated in LLPreviewGesture::getLabel() std::vector<std::string> LLGestureStepWait::getLabel() const { - std::vector<std::string> strings; - strings.push_back( "Wait" ); - -// std::string label("--- Wait: "); - if (mFlags & WAIT_FLAG_TIME) - { - char buffer[64]; /* Flawfinder: ignore */ - snprintf(buffer, sizeof(buffer), "%.1f seconds", (double)mWaitSeconds); /* Flawfinder: ignore */ - strings.push_back(buffer); -// label += buffer; - } - else if (mFlags & WAIT_FLAG_ALL_ANIM) - { - strings.push_back("until animations are done"); - // label += "until animations are done"; - } - else - { - strings.push_back(""); - } - - return strings; + std::vector<std::string> strings; + strings.push_back( "Wait" ); + +// std::string label("--- Wait: "); + if (mFlags & WAIT_FLAG_TIME) + { + char buffer[64]; /* Flawfinder: ignore */ + snprintf(buffer, sizeof(buffer), "%.1f seconds", (double)mWaitSeconds); /* Flawfinder: ignore */ + strings.push_back(buffer); +// label += buffer; + } + else if (mFlags & WAIT_FLAG_ALL_ANIM) + { + strings.push_back("until animations are done"); + // label += "until animations are done"; + } + else + { + strings.push_back(""); + } + + return strings; } void LLGestureStepWait::dump() { - LL_INFOS() << "step wait " << mWaitSeconds - << " flags " << mFlags - << LL_ENDL; + LL_INFOS() << "step wait " << mWaitSeconds + << " flags " << mFlags + << LL_ENDL; } diff --git a/indra/llcharacter/llmultigesture.h b/indra/llcharacter/llmultigesture.h index 92820159d4..bc9963f2b1 100644 --- a/indra/llcharacter/llmultigesture.h +++ b/indra/llcharacter/llmultigesture.h @@ -1,25 +1,25 @@ -/** +/** * @file llmultigesture.h * @brief Gestures that are asset-based and can have multiple steps. * * $LicenseInfo:firstyear=2004&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -40,67 +40,76 @@ class LLGestureStep; class LLMultiGesture { public: - LLMultiGesture(); - virtual ~LLMultiGesture(); + LLMultiGesture(); + virtual ~LLMultiGesture(); - // Maximum number of bytes this could hold once serialized. - S32 getMaxSerialSize() const; + // Maximum number of bytes this could hold once serialized. + S32 getMaxSerialSize() const; - BOOL serialize(LLDataPacker& dp) const; - BOOL deserialize(LLDataPacker& dp); + BOOL serialize(LLDataPacker& dp) const; + BOOL deserialize(LLDataPacker& dp); - void dump(); + void dump(); - void reset(); + void reset(); - const std::string& getTrigger() const { return mTrigger; } + const std::string& getTrigger() const { return mTrigger; } protected: - LLMultiGesture(const LLMultiGesture& gest); - const LLMultiGesture& operator=(const LLMultiGesture& rhs); + LLMultiGesture(const LLMultiGesture& gest); + const LLMultiGesture& operator=(const LLMultiGesture& rhs); public: - KEY mKey; - MASK mMask; + KEY mKey { 0 }; + MASK mMask { 0 }; - // This name can be empty if the inventory item is not around and + // This name can be empty if the inventory item is not around and // the gesture manager has not yet set the name - std::string mName; + std::string mName; + + // String, like "/foo" or "hello" that makes it play + std::string mTrigger; + + // Replaces the trigger substring with this text + std::string mReplaceText; + + std::vector<LLGestureStep*> mSteps; - // String, like "/foo" or "hello" that makes it play - std::string mTrigger; + // Is the gesture currently playing? + BOOL mPlaying { FALSE }; - // Replaces the trigger substring with this text - std::string mReplaceText; + // "instruction pointer" for steps + S32 mCurrentStep { 0 }; - std::vector<LLGestureStep*> mSteps; + // We're waiting for triggered animations to stop playing + BOOL mWaitingAnimations { FALSE }; - // Is the gesture currently playing? - BOOL mPlaying; + // We're waiting for key release + BOOL mWaitingKeyRelease { FALSE }; - // "instruction pointer" for steps - S32 mCurrentStep; + // We're waiting a fixed amount of time + BOOL mWaitingTimer { FALSE }; - // We're waiting for triggered animations to stop playing - BOOL mWaitingAnimations; + // We're waiting for triggered animations to stop playing + BOOL mTriggeredByKey { FALSE }; - // We're waiting a fixed amount of time - BOOL mWaitingTimer; + // Has the key been released? + BOOL mKeyReleased { FALSE }; - // Waiting after the last step played for all animations to complete - BOOL mWaitingAtEnd; + // Waiting after the last step played for all animations to complete + BOOL mWaitingAtEnd { FALSE }; - // Timer for waiting - LLFrameTimer mWaitTimer; + // Timer for waiting + LLFrameTimer mWaitTimer; - void (*mDoneCallback)(LLMultiGesture* gesture, void* data); - void* mCallbackData; + void (*mDoneCallback)(LLMultiGesture* gesture, void* data) { NULL }; + void* mCallbackData { NULL }; - // Animations that we requested to start - std::set<LLUUID> mRequestedAnimIDs; + // Animations that we requested to start + std::set<LLUUID> mRequestedAnimIDs; - // Once the animation starts playing (sim says to start playing) - // the ID is moved from mRequestedAnimIDs to here. - std::set<LLUUID> mPlayingAnimIDs; + // Once the animation starts playing (sim says to start playing) + // the ID is moved from mRequestedAnimIDs to here. + std::set<LLUUID> mPlayingAnimIDs; }; @@ -108,31 +117,31 @@ public: enum EStepType { - STEP_ANIMATION = 0, - STEP_SOUND = 1, - STEP_CHAT = 2, - STEP_WAIT = 3, + STEP_ANIMATION = 0, + STEP_SOUND = 1, + STEP_CHAT = 2, + STEP_WAIT = 3, - STEP_EOF = 4 + STEP_EOF = 4 }; class LLGestureStep { public: - LLGestureStep() {} - virtual ~LLGestureStep() {} + LLGestureStep() {} + virtual ~LLGestureStep() {} - virtual EStepType getType() = 0; + virtual EStepType getType() = 0; - // Return a user-readable label for this step - virtual std::vector<std::string> getLabel() const = 0; + // Return a user-readable label for this step + virtual std::vector<std::string> getLabel() const = 0; - virtual S32 getMaxSerialSize() const = 0; - virtual BOOL serialize(LLDataPacker& dp) const = 0; - virtual BOOL deserialize(LLDataPacker& dp) = 0; + virtual S32 getMaxSerialSize() const = 0; + virtual BOOL serialize(LLDataPacker& dp) const = 0; + virtual BOOL deserialize(LLDataPacker& dp) = 0; - virtual void dump() = 0; + virtual void dump() = 0; }; @@ -143,93 +152,94 @@ const U32 ANIM_FLAG_STOP = 0x01; class LLGestureStepAnimation : public LLGestureStep { public: - LLGestureStepAnimation(); - virtual ~LLGestureStepAnimation(); + LLGestureStepAnimation(); + virtual ~LLGestureStepAnimation(); - virtual EStepType getType() { return STEP_ANIMATION; } + virtual EStepType getType() { return STEP_ANIMATION; } - virtual std::vector<std::string> getLabel() const; + virtual std::vector<std::string> getLabel() const; - virtual S32 getMaxSerialSize() const; - virtual BOOL serialize(LLDataPacker& dp) const; - virtual BOOL deserialize(LLDataPacker& dp); + virtual S32 getMaxSerialSize() const; + virtual BOOL serialize(LLDataPacker& dp) const; + virtual BOOL deserialize(LLDataPacker& dp); - virtual void dump(); + virtual void dump(); public: - std::string mAnimName; - LLUUID mAnimAssetID; - U32 mFlags; + std::string mAnimName; + LLUUID mAnimAssetID; + U32 mFlags; }; class LLGestureStepSound : public LLGestureStep { public: - LLGestureStepSound(); - virtual ~LLGestureStepSound(); + LLGestureStepSound(); + virtual ~LLGestureStepSound(); - virtual EStepType getType() { return STEP_SOUND; } + virtual EStepType getType() { return STEP_SOUND; } - virtual std::vector<std::string> getLabel() const; + virtual std::vector<std::string> getLabel() const; - virtual S32 getMaxSerialSize() const; - virtual BOOL serialize(LLDataPacker& dp) const; - virtual BOOL deserialize(LLDataPacker& dp); + virtual S32 getMaxSerialSize() const; + virtual BOOL serialize(LLDataPacker& dp) const; + virtual BOOL deserialize(LLDataPacker& dp); - virtual void dump(); + virtual void dump(); public: - std::string mSoundName; - LLUUID mSoundAssetID; - U32 mFlags; + std::string mSoundName; + LLUUID mSoundAssetID; + U32 mFlags; }; class LLGestureStepChat : public LLGestureStep { public: - LLGestureStepChat(); - virtual ~LLGestureStepChat(); + LLGestureStepChat(); + virtual ~LLGestureStepChat(); - virtual EStepType getType() { return STEP_CHAT; } + virtual EStepType getType() { return STEP_CHAT; } - virtual std::vector<std::string> getLabel() const; + virtual std::vector<std::string> getLabel() const; - virtual S32 getMaxSerialSize() const; - virtual BOOL serialize(LLDataPacker& dp) const; - virtual BOOL deserialize(LLDataPacker& dp); + virtual S32 getMaxSerialSize() const; + virtual BOOL serialize(LLDataPacker& dp) const; + virtual BOOL deserialize(LLDataPacker& dp); - virtual void dump(); + virtual void dump(); public: - std::string mChatText; - U32 mFlags; + std::string mChatText; + U32 mFlags; }; -const U32 WAIT_FLAG_TIME = 0x01; -const U32 WAIT_FLAG_ALL_ANIM = 0x02; +const U32 WAIT_FLAG_TIME = 0x01; +const U32 WAIT_FLAG_ALL_ANIM = 0x02; +const U32 WAIT_FLAG_KEY_RELEASE = 0x04; class LLGestureStepWait : public LLGestureStep { public: - LLGestureStepWait(); - virtual ~LLGestureStepWait(); + LLGestureStepWait(); + virtual ~LLGestureStepWait(); - virtual EStepType getType() { return STEP_WAIT; } + virtual EStepType getType() { return STEP_WAIT; } - virtual std::vector<std::string> getLabel() const; + virtual std::vector<std::string> getLabel() const; - virtual S32 getMaxSerialSize() const; - virtual BOOL serialize(LLDataPacker& dp) const; - virtual BOOL deserialize(LLDataPacker& dp); + virtual S32 getMaxSerialSize() const; + virtual BOOL serialize(LLDataPacker& dp) const; + virtual BOOL deserialize(LLDataPacker& dp); - virtual void dump(); + virtual void dump(); public: - F32 mWaitSeconds; - U32 mFlags; + F32 mWaitSeconds; + U32 mFlags; }; #endif diff --git a/indra/llcharacter/llpose.cpp b/indra/llcharacter/llpose.cpp index 6f41a0e747..723b68b0a3 100644 --- a/indra/llcharacter/llpose.cpp +++ b/indra/llcharacter/llpose.cpp @@ -1,25 +1,25 @@ -/** +/** * @file llpose.cpp * @brief Implementation of LLPose class. * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -51,15 +51,15 @@ LLPose::~LLPose() //----------------------------------------------------------------------------- LLJointState* LLPose::getFirstJointState() { - mListIter = mJointMap.begin(); - if (mListIter == mJointMap.end()) - { - return NULL; - } - else - { - return mListIter->second; - } + mListIter = mJointMap.begin(); + if (mListIter == mJointMap.end()) + { + return NULL; + } + else + { + return mListIter->second; + } } //----------------------------------------------------------------------------- @@ -67,15 +67,15 @@ LLJointState* LLPose::getFirstJointState() //----------------------------------------------------------------------------- LLJointState *LLPose::getNextJointState() { - mListIter++; - if (mListIter == mJointMap.end()) - { - return NULL; - } - else - { - return mListIter->second; - } + mListIter++; + if (mListIter == mJointMap.end()) + { + return NULL; + } + else + { + return mListIter->second; + } } //----------------------------------------------------------------------------- @@ -83,11 +83,11 @@ LLJointState *LLPose::getNextJointState() //----------------------------------------------------------------------------- BOOL LLPose::addJointState(const LLPointer<LLJointState>& jointState) { - if (mJointMap.find(jointState->getJoint()->getName()) == mJointMap.end()) - { - mJointMap[jointState->getJoint()->getName()] = jointState; - } - return TRUE; + if (mJointMap.find(jointState->getJoint()->getName()) == mJointMap.end()) + { + mJointMap[jointState->getJoint()->getName()] = jointState; + } + return TRUE; } //----------------------------------------------------------------------------- @@ -95,8 +95,8 @@ BOOL LLPose::addJointState(const LLPointer<LLJointState>& jointState) //----------------------------------------------------------------------------- BOOL LLPose::removeJointState(const LLPointer<LLJointState>& jointState) { - mJointMap.erase(jointState->getJoint()->getName()); - return TRUE; + mJointMap.erase(jointState->getJoint()->getName()); + return TRUE; } //----------------------------------------------------------------------------- @@ -104,8 +104,8 @@ BOOL LLPose::removeJointState(const LLPointer<LLJointState>& jointState) //----------------------------------------------------------------------------- BOOL LLPose::removeAllJointStates() { - mJointMap.clear(); - return TRUE; + mJointMap.clear(); + return TRUE; } //----------------------------------------------------------------------------- @@ -113,16 +113,16 @@ BOOL LLPose::removeAllJointStates() //----------------------------------------------------------------------------- LLJointState* LLPose::findJointState(LLJoint *joint) { - joint_map_iterator iter = mJointMap.find(joint->getName()); - - if (iter == mJointMap.end()) - { - return NULL; - } - else - { - return iter->second; - } + joint_map_iterator iter = mJointMap.find(joint->getName()); + + if (iter == mJointMap.end()) + { + return NULL; + } + else + { + return iter->second; + } } //----------------------------------------------------------------------------- @@ -130,16 +130,16 @@ LLJointState* LLPose::findJointState(LLJoint *joint) //----------------------------------------------------------------------------- LLJointState* LLPose::findJointState(const std::string &name) { - joint_map_iterator iter = mJointMap.find(name); - - if (iter == mJointMap.end()) - { - return NULL; - } - else - { - return iter->second; - } + joint_map_iterator iter = mJointMap.find(name); + + if (iter == mJointMap.end()) + { + return NULL; + } + else + { + return iter->second; + } } //----------------------------------------------------------------------------- @@ -147,12 +147,12 @@ LLJointState* LLPose::findJointState(const std::string &name) //----------------------------------------------------------------------------- void LLPose::setWeight(F32 weight) { - joint_map_iterator iter; - for (joint_map_value_type& joint_pair : mJointMap) - { - joint_pair.second->setWeight(weight); - } - mWeight = weight; + joint_map_iterator iter; + for (joint_map_value_type& joint_pair : mJointMap) + { + joint_pair.second->setWeight(weight); + } + mWeight = weight; } //----------------------------------------------------------------------------- @@ -160,7 +160,7 @@ void LLPose::setWeight(F32 weight) //----------------------------------------------------------------------------- F32 LLPose::getWeight() const { - return mWeight; + return mWeight; } //----------------------------------------------------------------------------- @@ -168,7 +168,7 @@ F32 LLPose::getWeight() const //----------------------------------------------------------------------------- S32 LLPose::getNumJointStates() const { - return (S32)mJointMap.size(); + return (S32)mJointMap.size(); } //----------------------------------------------------------------------------- @@ -177,17 +177,17 @@ S32 LLPose::getNumJointStates() const LLJointStateBlender::LLJointStateBlender() { - for(S32 i = 0; i < JSB_NUM_JOINT_STATES; i++) - { - mJointStates[i] = NULL; - mPriorities[i] = S32_MIN; - mAdditiveBlends[i] = FALSE; - } + for(S32 i = 0; i < JSB_NUM_JOINT_STATES; i++) + { + mJointStates[i] = NULL; + mPriorities[i] = S32_MIN; + mAdditiveBlends[i] = FALSE; + } } LLJointStateBlender::~LLJointStateBlender() { - + } //----------------------------------------------------------------------------- @@ -195,41 +195,41 @@ LLJointStateBlender::~LLJointStateBlender() //----------------------------------------------------------------------------- BOOL LLJointStateBlender::addJointState(const LLPointer<LLJointState>& joint_state, S32 priority, BOOL additive_blend) { - llassert(joint_state); - - if (!joint_state->getJoint()) - // this joint state doesn't point to an actual joint, so we don't care about applying it - return FALSE; - - for(S32 i = 0; i < JSB_NUM_JOINT_STATES; i++) - { - if (mJointStates[i].isNull()) - { - mJointStates[i] = joint_state; - mPriorities[i] = priority; - mAdditiveBlends[i] = additive_blend; - return TRUE; - } - else if (priority > mPriorities[i]) - { - // we're at a higher priority than the current joint state in this slot - // so shift everyone over - // previous joint states (newer motions) with same priority should stay in place - for (S32 j = JSB_NUM_JOINT_STATES - 1; j > i; j--) - { - mJointStates[j] = mJointStates[j - 1]; - mPriorities[j] = mPriorities[j - 1]; - mAdditiveBlends[j] = mAdditiveBlends[j - 1]; - } - // now store ourselves in this slot - mJointStates[i] = joint_state; - mPriorities[i] = priority; - mAdditiveBlends[i] = additive_blend; - return TRUE; - } - } - - return FALSE; + llassert(joint_state); + + if (!joint_state->getJoint()) + // this joint state doesn't point to an actual joint, so we don't care about applying it + return FALSE; + + for(S32 i = 0; i < JSB_NUM_JOINT_STATES; i++) + { + if (mJointStates[i].isNull()) + { + mJointStates[i] = joint_state; + mPriorities[i] = priority; + mAdditiveBlends[i] = additive_blend; + return TRUE; + } + else if (priority > mPriorities[i]) + { + // we're at a higher priority than the current joint state in this slot + // so shift everyone over + // previous joint states (newer motions) with same priority should stay in place + for (S32 j = JSB_NUM_JOINT_STATES - 1; j > i; j--) + { + mJointStates[j] = mJointStates[j - 1]; + mPriorities[j] = mPriorities[j - 1]; + mAdditiveBlends[j] = mAdditiveBlends[j - 1]; + } + // now store ourselves in this slot + mJointStates[i] = joint_state; + mPriorities[i] = priority; + mAdditiveBlends[i] = additive_blend; + return TRUE; + } + } + + return FALSE; } //----------------------------------------------------------------------------- @@ -237,166 +237,166 @@ BOOL LLJointStateBlender::addJointState(const LLPointer<LLJointState>& joint_sta //----------------------------------------------------------------------------- void LLJointStateBlender::blendJointStates(BOOL apply_now) { - // we need at least one joint to blend - // if there is one, it will be in slot zero according to insertion logic - // instead of resetting joint state to default, just leave it unchanged from last frame - if (mJointStates[0].isNull()) - { - return; - } - - LLJoint* target_joint = apply_now ? mJointStates[0]->getJoint() : &mJointCache; - - const S32 POS_WEIGHT = 0; - const S32 ROT_WEIGHT = 1; - const S32 SCALE_WEIGHT = 2; - - F32 sum_weights[3]; - U32 sum_usage = 0; - - LLVector3 blended_pos = target_joint->getPosition(); - LLQuaternion blended_rot = target_joint->getRotation(); - LLVector3 blended_scale = target_joint->getScale(); - - LLVector3 added_pos; - LLQuaternion added_rot; - LLVector3 added_scale; - - //S32 joint_state_index; - - sum_weights[POS_WEIGHT] = 0.f; - sum_weights[ROT_WEIGHT] = 0.f; - sum_weights[SCALE_WEIGHT] = 0.f; - - for(S32 joint_state_index = 0; - joint_state_index < JSB_NUM_JOINT_STATES && mJointStates[joint_state_index].notNull(); - joint_state_index++) - { - LLJointState* jsp = mJointStates[joint_state_index]; - U32 current_usage = jsp->getUsage(); - F32 current_weight = jsp->getWeight(); - - if (current_weight == 0.f) - { - continue; - } - - if (mAdditiveBlends[joint_state_index]) - { - if(current_usage & LLJointState::POS) - { - F32 new_weight_sum = llmin(1.f, current_weight + sum_weights[POS_WEIGHT]); - - // add in pos for this jointstate modulated by weight - added_pos += jsp->getPosition() * (new_weight_sum - sum_weights[POS_WEIGHT]); - } - - if(current_usage & LLJointState::SCALE) - { - F32 new_weight_sum = llmin(1.f, current_weight + sum_weights[SCALE_WEIGHT]); - - // add in scale for this jointstate modulated by weight - added_scale += jsp->getScale() * (new_weight_sum - sum_weights[SCALE_WEIGHT]); - } - - if (current_usage & LLJointState::ROT) - { - F32 new_weight_sum = llmin(1.f, current_weight + sum_weights[ROT_WEIGHT]); - - // add in rotation for this jointstate modulated by weight - added_rot = nlerp((new_weight_sum - sum_weights[ROT_WEIGHT]), added_rot, jsp->getRotation()) * added_rot; - } - } - else - { - // blend two jointstates together - - // blend position - if(current_usage & LLJointState::POS) - { - if(sum_usage & LLJointState::POS) - { - F32 new_weight_sum = llmin(1.f, current_weight + sum_weights[POS_WEIGHT]); - - // blend positions from both - blended_pos = lerp(jsp->getPosition(), blended_pos, sum_weights[POS_WEIGHT] / new_weight_sum); - sum_weights[POS_WEIGHT] = new_weight_sum; - } - else - { - // copy position from current - blended_pos = jsp->getPosition(); - sum_weights[POS_WEIGHT] = current_weight; - } - } - - // now do scale - if(current_usage & LLJointState::SCALE) - { - if(sum_usage & LLJointState::SCALE) - { - F32 new_weight_sum = llmin(1.f, current_weight + sum_weights[SCALE_WEIGHT]); - - // blend scales from both - blended_scale = lerp(jsp->getScale(), blended_scale, sum_weights[SCALE_WEIGHT] / new_weight_sum); - sum_weights[SCALE_WEIGHT] = new_weight_sum; - } - else - { - // copy scale from current - blended_scale = jsp->getScale(); - sum_weights[SCALE_WEIGHT] = current_weight; - } - } - - // rotation - if (current_usage & LLJointState::ROT) - { - if(sum_usage & LLJointState::ROT) - { - F32 new_weight_sum = llmin(1.f, current_weight + sum_weights[ROT_WEIGHT]); - - // blend rotations from both - blended_rot = nlerp(sum_weights[ROT_WEIGHT] / new_weight_sum, jsp->getRotation(), blended_rot); - sum_weights[ROT_WEIGHT] = new_weight_sum; - } - else - { - // copy rotation from current - blended_rot = jsp->getRotation(); - sum_weights[ROT_WEIGHT] = current_weight; - } - } - - // update resulting usage mask - sum_usage = sum_usage | current_usage; - } - } - - if (!added_scale.isFinite()) - { - added_scale.clearVec(); - } - - if (!blended_scale.isFinite()) - { - blended_scale.setVec(1,1,1); - } - - // apply transforms + // we need at least one joint to blend + // if there is one, it will be in slot zero according to insertion logic + // instead of resetting joint state to default, just leave it unchanged from last frame + if (mJointStates[0].isNull()) + { + return; + } + + LLJoint* target_joint = apply_now ? mJointStates[0]->getJoint() : &mJointCache; + + const S32 POS_WEIGHT = 0; + const S32 ROT_WEIGHT = 1; + const S32 SCALE_WEIGHT = 2; + + F32 sum_weights[3]; + U32 sum_usage = 0; + + LLVector3 blended_pos = target_joint->getPosition(); + LLQuaternion blended_rot = target_joint->getRotation(); + LLVector3 blended_scale = target_joint->getScale(); + + LLVector3 added_pos; + LLQuaternion added_rot; + LLVector3 added_scale; + + //S32 joint_state_index; + + sum_weights[POS_WEIGHT] = 0.f; + sum_weights[ROT_WEIGHT] = 0.f; + sum_weights[SCALE_WEIGHT] = 0.f; + + for(S32 joint_state_index = 0; + joint_state_index < JSB_NUM_JOINT_STATES && mJointStates[joint_state_index].notNull(); + joint_state_index++) + { + LLJointState* jsp = mJointStates[joint_state_index]; + U32 current_usage = jsp->getUsage(); + F32 current_weight = jsp->getWeight(); + + if (current_weight == 0.f) + { + continue; + } + + if (mAdditiveBlends[joint_state_index]) + { + if(current_usage & LLJointState::POS) + { + F32 new_weight_sum = llmin(1.f, current_weight + sum_weights[POS_WEIGHT]); + + // add in pos for this jointstate modulated by weight + added_pos += jsp->getPosition() * (new_weight_sum - sum_weights[POS_WEIGHT]); + } + + if(current_usage & LLJointState::SCALE) + { + F32 new_weight_sum = llmin(1.f, current_weight + sum_weights[SCALE_WEIGHT]); + + // add in scale for this jointstate modulated by weight + added_scale += jsp->getScale() * (new_weight_sum - sum_weights[SCALE_WEIGHT]); + } + + if (current_usage & LLJointState::ROT) + { + F32 new_weight_sum = llmin(1.f, current_weight + sum_weights[ROT_WEIGHT]); + + // add in rotation for this jointstate modulated by weight + added_rot = nlerp((new_weight_sum - sum_weights[ROT_WEIGHT]), added_rot, jsp->getRotation()) * added_rot; + } + } + else + { + // blend two jointstates together + + // blend position + if(current_usage & LLJointState::POS) + { + if(sum_usage & LLJointState::POS) + { + F32 new_weight_sum = llmin(1.f, current_weight + sum_weights[POS_WEIGHT]); + + // blend positions from both + blended_pos = lerp(jsp->getPosition(), blended_pos, sum_weights[POS_WEIGHT] / new_weight_sum); + sum_weights[POS_WEIGHT] = new_weight_sum; + } + else + { + // copy position from current + blended_pos = jsp->getPosition(); + sum_weights[POS_WEIGHT] = current_weight; + } + } + + // now do scale + if(current_usage & LLJointState::SCALE) + { + if(sum_usage & LLJointState::SCALE) + { + F32 new_weight_sum = llmin(1.f, current_weight + sum_weights[SCALE_WEIGHT]); + + // blend scales from both + blended_scale = lerp(jsp->getScale(), blended_scale, sum_weights[SCALE_WEIGHT] / new_weight_sum); + sum_weights[SCALE_WEIGHT] = new_weight_sum; + } + else + { + // copy scale from current + blended_scale = jsp->getScale(); + sum_weights[SCALE_WEIGHT] = current_weight; + } + } + + // rotation + if (current_usage & LLJointState::ROT) + { + if(sum_usage & LLJointState::ROT) + { + F32 new_weight_sum = llmin(1.f, current_weight + sum_weights[ROT_WEIGHT]); + + // blend rotations from both + blended_rot = nlerp(sum_weights[ROT_WEIGHT] / new_weight_sum, jsp->getRotation(), blended_rot); + sum_weights[ROT_WEIGHT] = new_weight_sum; + } + else + { + // copy rotation from current + blended_rot = jsp->getRotation(); + sum_weights[ROT_WEIGHT] = current_weight; + } + } + + // update resulting usage mask + sum_usage = sum_usage | current_usage; + } + } + + if (!added_scale.isFinite()) + { + added_scale.clearVec(); + } + + if (!blended_scale.isFinite()) + { + blended_scale.setVec(1,1,1); + } + + // apply transforms // SL-315 - target_joint->setPosition(blended_pos + added_pos); - target_joint->setScale(blended_scale + added_scale); - target_joint->setRotation(added_rot * blended_rot); - - if (apply_now) - { - // now clear joint states - for(S32 i = 0; i < JSB_NUM_JOINT_STATES; i++) - { - mJointStates[i] = NULL; - } - } + target_joint->setPosition(blended_pos + added_pos); + target_joint->setScale(blended_scale + added_scale); + target_joint->setRotation(added_rot * blended_rot); + + if (apply_now) + { + // now clear joint states + for(S32 i = 0; i < JSB_NUM_JOINT_STATES; i++) + { + mJointStates[i] = NULL; + } + } } //----------------------------------------------------------------------------- @@ -404,22 +404,22 @@ void LLJointStateBlender::blendJointStates(BOOL apply_now) //----------------------------------------------------------------------------- void LLJointStateBlender::interpolate(F32 u) { - // only interpolate if we have a joint state - if (!mJointStates[0]) - { - return; - } - LLJoint* target_joint = mJointStates[0]->getJoint(); - - if (!target_joint) - { - return; - } + // only interpolate if we have a joint state + if (!mJointStates[0]) + { + return; + } + LLJoint* target_joint = mJointStates[0]->getJoint(); + + if (!target_joint) + { + return; + } // SL-315 - target_joint->setPosition(lerp(target_joint->getPosition(), mJointCache.getPosition(), u)); - target_joint->setScale(lerp(target_joint->getScale(), mJointCache.getScale(), u)); - target_joint->setRotation(nlerp(u, target_joint->getRotation(), mJointCache.getRotation())); + target_joint->setPosition(lerp(target_joint->getPosition(), mJointCache.getPosition(), u)); + target_joint->setScale(lerp(target_joint->getScale(), mJointCache.getScale(), u)); + target_joint->setRotation(nlerp(u, target_joint->getRotation(), mJointCache.getRotation())); } //----------------------------------------------------------------------------- @@ -427,11 +427,11 @@ void LLJointStateBlender::interpolate(F32 u) //----------------------------------------------------------------------------- void LLJointStateBlender::clear() { - // now clear joint states - for(S32 i = 0; i < JSB_NUM_JOINT_STATES; i++) - { - mJointStates[i] = NULL; - } + // now clear joint states + for(S32 i = 0; i < JSB_NUM_JOINT_STATES; i++) + { + mJointStates[i] = NULL; + } } //----------------------------------------------------------------------------- @@ -439,15 +439,15 @@ void LLJointStateBlender::clear() //----------------------------------------------------------------------------- void LLJointStateBlender::resetCachedJoint() { - if (!mJointStates[0]) - { - return; - } - LLJoint* source_joint = mJointStates[0]->getJoint(); + if (!mJointStates[0]) + { + return; + } + LLJoint* source_joint = mJointStates[0]->getJoint(); // SL-315 - mJointCache.setPosition(source_joint->getPosition()); - mJointCache.setScale(source_joint->getScale()); - mJointCache.setRotation(source_joint->getRotation()); + mJointCache.setPosition(source_joint->getPosition()); + mJointCache.setScale(source_joint->getScale()); + mJointCache.setRotation(source_joint->getRotation()); } //----------------------------------------------------------------------------- @@ -455,14 +455,14 @@ void LLJointStateBlender::resetCachedJoint() //----------------------------------------------------------------------------- LLPoseBlender::LLPoseBlender() - : mNextPoseSlot(0) + : mNextPoseSlot(0) { } LLPoseBlender::~LLPoseBlender() { - for_each(mJointStateBlenderPool.begin(), mJointStateBlenderPool.end(), DeletePairedPointer()); - mJointStateBlenderPool.clear(); + for_each(mJointStateBlenderPool.begin(), mJointStateBlenderPool.end(), DeletePairedPointer()); + mJointStateBlenderPool.clear(); } //----------------------------------------------------------------------------- @@ -470,40 +470,40 @@ LLPoseBlender::~LLPoseBlender() //----------------------------------------------------------------------------- BOOL LLPoseBlender::addMotion(LLMotion* motion) { - LLPose* pose = motion->getPose(); - - for(LLJointState* jsp = pose->getFirstJointState(); jsp; jsp = pose->getNextJointState()) - { - LLJoint *jointp = jsp->getJoint(); - LLJointStateBlender* joint_blender; - if (mJointStateBlenderPool.find(jointp) == mJointStateBlenderPool.end()) - { - // this is the first time we are animating this joint - // so create new jointblender and add it to our pool - joint_blender = new LLJointStateBlender(); - mJointStateBlenderPool[jointp] = joint_blender; - } - else - { - joint_blender = mJointStateBlenderPool[jointp]; - } - - if (jsp->getPriority() == LLJoint::USE_MOTION_PRIORITY) - { - joint_blender->addJointState(jsp, motion->getPriority(), motion->getBlendType() == LLMotion::ADDITIVE_BLEND); - } - else - { - joint_blender->addJointState(jsp, jsp->getPriority(), motion->getBlendType() == LLMotion::ADDITIVE_BLEND); - } - - // add it to our list of active blenders - if (std::find(mActiveBlenders.begin(), mActiveBlenders.end(), joint_blender) == mActiveBlenders.end()) - { - mActiveBlenders.push_front(joint_blender); - } - } - return TRUE; + LLPose* pose = motion->getPose(); + + for(LLJointState* jsp = pose->getFirstJointState(); jsp; jsp = pose->getNextJointState()) + { + LLJoint *jointp = jsp->getJoint(); + LLJointStateBlender* joint_blender; + if (mJointStateBlenderPool.find(jointp) == mJointStateBlenderPool.end()) + { + // this is the first time we are animating this joint + // so create new jointblender and add it to our pool + joint_blender = new LLJointStateBlender(); + mJointStateBlenderPool[jointp] = joint_blender; + } + else + { + joint_blender = mJointStateBlenderPool[jointp]; + } + + if (jsp->getPriority() == LLJoint::USE_MOTION_PRIORITY) + { + joint_blender->addJointState(jsp, motion->getPriority(), motion->getBlendType() == LLMotion::ADDITIVE_BLEND); + } + else + { + joint_blender->addJointState(jsp, jsp->getPriority(), motion->getBlendType() == LLMotion::ADDITIVE_BLEND); + } + + // add it to our list of active blenders + if (std::find(mActiveBlenders.begin(), mActiveBlenders.end(), joint_blender) == mActiveBlenders.end()) + { + mActiveBlenders.push_front(joint_blender); + } + } + return TRUE; } //----------------------------------------------------------------------------- @@ -511,15 +511,15 @@ BOOL LLPoseBlender::addMotion(LLMotion* motion) //----------------------------------------------------------------------------- void LLPoseBlender::blendAndApply() { - for (blender_list_t::iterator iter = mActiveBlenders.begin(); - iter != mActiveBlenders.end(); ) - { - LLJointStateBlender* jsbp = *iter++; - jsbp->blendJointStates(); - } - - // we're done now so there are no more active blenders for this frame - mActiveBlenders.clear(); + for (blender_list_t::iterator iter = mActiveBlenders.begin(); + iter != mActiveBlenders.end(); ) + { + LLJointStateBlender* jsbp = *iter++; + jsbp->blendJointStates(); + } + + // we're done now so there are no more active blenders for this frame + mActiveBlenders.clear(); } //----------------------------------------------------------------------------- @@ -527,16 +527,16 @@ void LLPoseBlender::blendAndApply() //----------------------------------------------------------------------------- void LLPoseBlender::blendAndCache(BOOL reset_cached_joints) { - for (blender_list_t::iterator iter = mActiveBlenders.begin(); - iter != mActiveBlenders.end(); ++iter) - { - LLJointStateBlender* jsbp = *iter; - if (reset_cached_joints) - { - jsbp->resetCachedJoint(); - } - jsbp->blendJointStates(FALSE); - } + for (blender_list_t::iterator iter = mActiveBlenders.begin(); + iter != mActiveBlenders.end(); ++iter) + { + LLJointStateBlender* jsbp = *iter; + if (reset_cached_joints) + { + jsbp->resetCachedJoint(); + } + jsbp->blendJointStates(FALSE); + } } //----------------------------------------------------------------------------- @@ -544,12 +544,12 @@ void LLPoseBlender::blendAndCache(BOOL reset_cached_joints) //----------------------------------------------------------------------------- void LLPoseBlender::interpolate(F32 u) { - for (blender_list_t::iterator iter = mActiveBlenders.begin(); - iter != mActiveBlenders.end(); ++iter) - { - LLJointStateBlender* jsbp = *iter; - jsbp->interpolate(u); - } + for (blender_list_t::iterator iter = mActiveBlenders.begin(); + iter != mActiveBlenders.end(); ++iter) + { + LLJointStateBlender* jsbp = *iter; + jsbp->interpolate(u); + } } //----------------------------------------------------------------------------- @@ -557,13 +557,13 @@ void LLPoseBlender::interpolate(F32 u) //----------------------------------------------------------------------------- void LLPoseBlender::clearBlenders() { - for (blender_list_t::iterator iter = mActiveBlenders.begin(); - iter != mActiveBlenders.end(); ++iter) - { - LLJointStateBlender* jsbp = *iter; - jsbp->clear(); - } - - mActiveBlenders.clear(); + for (blender_list_t::iterator iter = mActiveBlenders.begin(); + iter != mActiveBlenders.end(); ++iter) + { + LLJointStateBlender* jsbp = *iter; + jsbp->clear(); + } + + mActiveBlenders.clear(); } diff --git a/indra/llcharacter/llpose.h b/indra/llcharacter/llpose.h index 1405f1e053..8b488a8218 100644 --- a/indra/llcharacter/llpose.h +++ b/indra/llcharacter/llpose.h @@ -1,25 +1,25 @@ -/** +/** * @file llpose.h * @brief Implementation of LLPose class. * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -44,38 +44,38 @@ //----------------------------------------------------------------------------- class LLPose { - friend class LLPoseBlender; + friend class LLPoseBlender; protected: - typedef std::map<std::string, LLPointer<LLJointState> > joint_map; - typedef joint_map::iterator joint_map_iterator; - typedef joint_map::value_type joint_map_value_type; - - joint_map mJointMap; - F32 mWeight; - joint_map_iterator mListIter; + typedef std::map<std::string, LLPointer<LLJointState> > joint_map; + typedef joint_map::iterator joint_map_iterator; + typedef joint_map::value_type joint_map_value_type; + + joint_map mJointMap; + F32 mWeight; + joint_map_iterator mListIter; public: - // Iterate through jointStates - LLJointState* getFirstJointState(); - LLJointState* getNextJointState(); - LLJointState* findJointState(LLJoint *joint); - LLJointState* findJointState(const std::string &name); + // Iterate through jointStates + LLJointState* getFirstJointState(); + LLJointState* getNextJointState(); + LLJointState* findJointState(LLJoint *joint); + LLJointState* findJointState(const std::string &name); public: - // Constructor - LLPose() : mWeight(0.f) {} - // Destructor - ~LLPose(); - // add a joint state in this pose - BOOL addJointState(const LLPointer<LLJointState>& jointState); - // remove a joint state from this pose - BOOL removeJointState(const LLPointer<LLJointState>& jointState); - // removes all joint states from this pose - BOOL removeAllJointStates(); - // set weight for all joint states in this pose - void setWeight(F32 weight); - // get weight for this pose - F32 getWeight() const; - // returns number of joint states stored in this pose - S32 getNumJointStates() const; + // Constructor + LLPose() : mWeight(0.f) {} + // Destructor + ~LLPose(); + // add a joint state in this pose + BOOL addJointState(const LLPointer<LLJointState>& jointState); + // remove a joint state from this pose + BOOL removeJointState(const LLPointer<LLJointState>& jointState); + // removes all joint states from this pose + BOOL removeAllJointStates(); + // set weight for all joint states in this pose + void setWeight(F32 weight); + // get weight for this pose + F32 getWeight() const; + // returns number of joint states stored in this pose + S32 getNumJointStates() const; }; const S32 JSB_NUM_JOINT_STATES = 6; @@ -85,20 +85,20 @@ class LLJointStateBlender { LL_ALIGN_NEW protected: - LLPointer<LLJointState> mJointStates[JSB_NUM_JOINT_STATES]; - S32 mPriorities[JSB_NUM_JOINT_STATES]; - BOOL mAdditiveBlends[JSB_NUM_JOINT_STATES]; + LLPointer<LLJointState> mJointStates[JSB_NUM_JOINT_STATES]; + S32 mPriorities[JSB_NUM_JOINT_STATES]; + BOOL mAdditiveBlends[JSB_NUM_JOINT_STATES]; public: - LLJointStateBlender(); - ~LLJointStateBlender(); - void blendJointStates(BOOL apply_now = TRUE); - BOOL addJointState(const LLPointer<LLJointState>& joint_state, S32 priority, BOOL additive_blend); - void interpolate(F32 u); - void clear(); - void resetCachedJoint(); + LLJointStateBlender(); + ~LLJointStateBlender(); + void blendJointStates(BOOL apply_now = TRUE); + BOOL addJointState(const LLPointer<LLJointState>& joint_state, S32 priority, BOOL additive_blend); + void interpolate(F32 u); + void clear(); + void resetCachedJoint(); public: - LL_ALIGN_16(LLJoint mJointCache); + LL_ALIGN_16(LLJoint mJointCache); } LL_ALIGN_POSTFIX(16); class LLMotion; @@ -106,35 +106,35 @@ class LLMotion; class LLPoseBlender { protected: - typedef std::list<LLJointStateBlender*> blender_list_t; - typedef std::map<LLJoint*,LLJointStateBlender*> blender_map_t; - blender_map_t mJointStateBlenderPool; - blender_list_t mActiveBlenders; + typedef std::list<LLJointStateBlender*> blender_list_t; + typedef std::map<LLJoint*,LLJointStateBlender*> blender_map_t; + blender_map_t mJointStateBlenderPool; + blender_list_t mActiveBlenders; - S32 mNextPoseSlot; - LLPose mBlendedPose; + S32 mNextPoseSlot; + LLPose mBlendedPose; public: - // Constructor - LLPoseBlender(); - // Destructor - ~LLPoseBlender(); - - // request motion joint states to be added to pose blender joint state records - BOOL addMotion(LLMotion* motion); + // Constructor + LLPoseBlender(); + // Destructor + ~LLPoseBlender(); + + // request motion joint states to be added to pose blender joint state records + BOOL addMotion(LLMotion* motion); - // blend all joint states and apply to skeleton - void blendAndApply(); + // blend all joint states and apply to skeleton + void blendAndApply(); - // removes all joint state blenders from last time - void clearBlenders(); + // removes all joint state blenders from last time + void clearBlenders(); - // blend all joint states and cache results - void blendAndCache(BOOL reset_cached_joints); + // blend all joint states and cache results + void blendAndCache(BOOL reset_cached_joints); - // interpolate all joints towards cached values - void interpolate(F32 u); + // interpolate all joints towards cached values + void interpolate(F32 u); - LLPose* getBlendedPose() { return &mBlendedPose; } + LLPose* getBlendedPose() { return &mBlendedPose; } }; #endif // LL_LLPOSE_H diff --git a/indra/llcharacter/llstatemachine.cpp b/indra/llcharacter/llstatemachine.cpp index 2e8214ffaf..beee6f386b 100644 --- a/indra/llcharacter/llstatemachine.cpp +++ b/indra/llcharacter/llstatemachine.cpp @@ -1,25 +1,25 @@ -/** +/** * @file llstatemachine.cpp * @brief LLStateMachine implementation file. * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -33,14 +33,14 @@ U32 LLUniqueID::sNextID = 0; -bool operator==(const LLUniqueID &a, const LLUniqueID &b) +bool operator==(const LLUniqueID &a, const LLUniqueID &b) { - return (a.mId == b.mId); + return (a.mId == b.mId); } -bool operator!=(const LLUniqueID &a, const LLUniqueID &b) +bool operator!=(const LLUniqueID &a, const LLUniqueID &b) { - return (a.mId != b.mId); + return (a.mId != b.mId); } //----------------------------------------------------------------------------- @@ -48,8 +48,8 @@ bool operator!=(const LLUniqueID &a, const LLUniqueID &b) //----------------------------------------------------------------------------- LLStateDiagram::LLStateDiagram() { - mDefaultState = NULL; - mUseDefaultState = FALSE; + mDefaultState = NULL; + mUseDefaultState = FALSE; } LLStateDiagram::~LLStateDiagram() @@ -60,221 +60,221 @@ LLStateDiagram::~LLStateDiagram() // add a state to the state graph BOOL LLStateDiagram::addState(LLFSMState *state) { - mStates[state] = Transitions(); - return TRUE; + mStates[state] = Transitions(); + return TRUE; } // add a directed transition between 2 states BOOL LLStateDiagram::addTransition(LLFSMState& start_state, LLFSMState& end_state, LLFSMTransition& transition) { - StateMap::iterator state_it; - state_it = mStates.find(&start_state); - Transitions* state_transitions = NULL; - if (state_it == mStates.end() ) - { - addState(&start_state); - state_transitions = &mStates[&start_state]; - } - else - { - state_transitions = &state_it->second; - } - state_it = mStates.find(&end_state); - if (state_it == mStates.end() ) - { - addState(&end_state); - } - - Transitions::iterator transition_it = state_transitions->find(&transition); - if (transition_it != state_transitions->end()) - { - LL_ERRS() << "LLStateTable::addDirectedTransition() : transition already exists" << LL_ENDL; - return FALSE; // transition already exists - } - - (*state_transitions)[&transition] = &end_state; - return TRUE; + StateMap::iterator state_it; + state_it = mStates.find(&start_state); + Transitions* state_transitions = NULL; + if (state_it == mStates.end() ) + { + addState(&start_state); + state_transitions = &mStates[&start_state]; + } + else + { + state_transitions = &state_it->second; + } + state_it = mStates.find(&end_state); + if (state_it == mStates.end() ) + { + addState(&end_state); + } + + Transitions::iterator transition_it = state_transitions->find(&transition); + if (transition_it != state_transitions->end()) + { + LL_ERRS() << "LLStateTable::addDirectedTransition() : transition already exists" << LL_ENDL; + return FALSE; // transition already exists + } + + (*state_transitions)[&transition] = &end_state; + return TRUE; } // add an undirected transition between 2 states BOOL LLStateDiagram::addUndirectedTransition(LLFSMState& start_state, LLFSMState& end_state, LLFSMTransition& transition) { - BOOL result; - result = addTransition(start_state, end_state, transition); - if (result) - { - result = addTransition(end_state, start_state, transition); - } - return result; + BOOL result; + result = addTransition(start_state, end_state, transition); + if (result) + { + result = addTransition(end_state, start_state, transition); + } + return result; } // add a transition that exists for every state void LLStateDiagram::addDefaultTransition(LLFSMState& end_state, LLFSMTransition& transition) { - mDefaultTransitions[&transition] = &end_state; + mDefaultTransitions[&transition] = &end_state; } // process a possible transition, and get the resulting state LLFSMState* LLStateDiagram::processTransition(LLFSMState& start_state, LLFSMTransition& transition) { - // look up transition - //LLFSMState** dest_state = (mStates.getValue(&start_state))->getValue(&transition); - LLFSMState* dest_state = NULL; - StateMap::iterator state_it = mStates.find(&start_state); - if (state_it == mStates.end()) - { - return NULL; - } - Transitions::iterator transition_it = state_it->second.find(&transition); - - // try default transitions if state-specific transition not found - if (transition_it == state_it->second.end()) - { - dest_state = mDefaultTransitions[&transition]; - } - else - { - dest_state = transition_it->second; - } - - // if we have a destination state... - if (NULL != dest_state) - { - // ...return it... - return dest_state; - } - // ... otherwise ... - else - { - // ...look for default state... - if (mUseDefaultState) - { - // ...return it if we have it... - return mDefaultState; - } - else - { - // ...or else we're still in the same state. - return &start_state; - } - } + // look up transition + //LLFSMState** dest_state = (mStates.getValue(&start_state))->getValue(&transition); + LLFSMState* dest_state = NULL; + StateMap::iterator state_it = mStates.find(&start_state); + if (state_it == mStates.end()) + { + return NULL; + } + Transitions::iterator transition_it = state_it->second.find(&transition); + + // try default transitions if state-specific transition not found + if (transition_it == state_it->second.end()) + { + dest_state = mDefaultTransitions[&transition]; + } + else + { + dest_state = transition_it->second; + } + + // if we have a destination state... + if (NULL != dest_state) + { + // ...return it... + return dest_state; + } + // ... otherwise ... + else + { + // ...look for default state... + if (mUseDefaultState) + { + // ...return it if we have it... + return mDefaultState; + } + else + { + // ...or else we're still in the same state. + return &start_state; + } + } } void LLStateDiagram::setDefaultState(LLFSMState& default_state) { - mUseDefaultState = TRUE; - mDefaultState = &default_state; + mUseDefaultState = TRUE; + mDefaultState = &default_state; } S32 LLStateDiagram::numDeadendStates() { - S32 numDeadends = 0; - for (StateMap::value_type& state_pair : mStates) - { - if (state_pair.second.size() == 0) - { - numDeadends++; - } - } - return numDeadends; + S32 numDeadends = 0; + for (StateMap::value_type& state_pair : mStates) + { + if (state_pair.second.size() == 0) + { + numDeadends++; + } + } + return numDeadends; } BOOL LLStateDiagram::stateIsValid(LLFSMState& state) { - if (mStates.find(&state) != mStates.end()) - { - return TRUE; - } - return FALSE; + if (mStates.find(&state) != mStates.end()) + { + return TRUE; + } + return FALSE; } LLFSMState* LLStateDiagram::getState(U32 state_id) { - for (StateMap::value_type& state_pair : mStates) - { - if (state_pair.first->getID() == state_id) - { - return state_pair.first; - } - } - return NULL; + for (StateMap::value_type& state_pair : mStates) + { + if (state_pair.first->getID() == state_id) + { + return state_pair.first; + } + } + return NULL; } BOOL LLStateDiagram::saveDotFile(const std::string& filename) { - LLAPRFile outfile ; - outfile.open(filename, LL_APR_W); - apr_file_t* dot_file = outfile.getFileHandle() ; - - if (!dot_file) - { - LL_WARNS() << "LLStateDiagram::saveDotFile() : Couldn't open " << filename << " to save state diagram." << LL_ENDL; - return FALSE; - } - apr_file_printf(dot_file, "digraph StateMachine {\n\tsize=\"100,100\";\n\tfontsize=40;\n\tlabel=\"Finite State Machine\";\n\torientation=landscape\n\tratio=.77\n"); - - for (StateMap::value_type& state_pair : mStates) - { - apr_file_printf(dot_file, "\t\"%s\" [fontsize=28,shape=box]\n", state_pair.first->getName().c_str()); - } - apr_file_printf(dot_file, "\t\"All States\" [fontsize=30,style=bold,shape=box]\n"); - - for (Transitions::value_type& transition_pair : mDefaultTransitions) - { - apr_file_printf(dot_file, "\t\"All States\" -> \"%s\" [label = \"%s\",fontsize=24];\n", transition_pair.second->getName().c_str(), - transition_pair.second->getName().c_str()); - } - - if (mDefaultState) - { - apr_file_printf(dot_file, "\t\"All States\" -> \"%s\";\n", mDefaultState->getName().c_str()); - } - - - for (StateMap::value_type& state_pair : mStates) - { - LLFSMState *state = state_pair.first; - - for (Transitions::value_type& transition_pair : state_pair.second) - { - std::string state_name = state->getName(); - std::string target_name = transition_pair.second->getName(); - std::string transition_name = transition_pair.first->getName(); - apr_file_printf(dot_file, "\t\"%s\" -> \"%s\" [label = \"%s\",fontsize=24];\n", state->getName().c_str(), - target_name.c_str(), - transition_name.c_str()); - } - } - - apr_file_printf(dot_file, "}\n"); - - return TRUE; + LLAPRFile outfile ; + outfile.open(filename, LL_APR_W); + apr_file_t* dot_file = outfile.getFileHandle() ; + + if (!dot_file) + { + LL_WARNS() << "LLStateDiagram::saveDotFile() : Couldn't open " << filename << " to save state diagram." << LL_ENDL; + return FALSE; + } + apr_file_printf(dot_file, "digraph StateMachine {\n\tsize=\"100,100\";\n\tfontsize=40;\n\tlabel=\"Finite State Machine\";\n\torientation=landscape\n\tratio=.77\n"); + + for (StateMap::value_type& state_pair : mStates) + { + apr_file_printf(dot_file, "\t\"%s\" [fontsize=28,shape=box]\n", state_pair.first->getName().c_str()); + } + apr_file_printf(dot_file, "\t\"All States\" [fontsize=30,style=bold,shape=box]\n"); + + for (Transitions::value_type& transition_pair : mDefaultTransitions) + { + apr_file_printf(dot_file, "\t\"All States\" -> \"%s\" [label = \"%s\",fontsize=24];\n", transition_pair.second->getName().c_str(), + transition_pair.second->getName().c_str()); + } + + if (mDefaultState) + { + apr_file_printf(dot_file, "\t\"All States\" -> \"%s\";\n", mDefaultState->getName().c_str()); + } + + + for (StateMap::value_type& state_pair : mStates) + { + LLFSMState *state = state_pair.first; + + for (Transitions::value_type& transition_pair : state_pair.second) + { + std::string state_name = state->getName(); + std::string target_name = transition_pair.second->getName(); + std::string transition_name = transition_pair.first->getName(); + apr_file_printf(dot_file, "\t\"%s\" -> \"%s\" [label = \"%s\",fontsize=24];\n", state->getName().c_str(), + target_name.c_str(), + transition_name.c_str()); + } + } + + apr_file_printf(dot_file, "}\n"); + + return TRUE; } std::ostream& operator<<(std::ostream &s, LLStateDiagram &FSM) { - if (FSM.mDefaultState) - { - s << "Default State: " << FSM.mDefaultState->getName() << "\n"; - } - - for (LLStateDiagram::Transitions::value_type& transition_pair : FSM.mDefaultTransitions) - { - s << "Any State -- " << transition_pair.first->getName() - << " --> " << transition_pair.second->getName() << "\n"; - } - - for (LLStateDiagram::StateMap::value_type& state_pair : FSM.mStates) - { - for (LLStateDiagram::Transitions::value_type& transition_pair : state_pair.second) - { - s << state_pair.first->getName() << " -- " << transition_pair.first->getName() - << " --> " << transition_pair.second->getName() << "\n"; - } - s << "\n"; - } - - return s; + if (FSM.mDefaultState) + { + s << "Default State: " << FSM.mDefaultState->getName() << "\n"; + } + + for (LLStateDiagram::Transitions::value_type& transition_pair : FSM.mDefaultTransitions) + { + s << "Any State -- " << transition_pair.first->getName() + << " --> " << transition_pair.second->getName() << "\n"; + } + + for (LLStateDiagram::StateMap::value_type& state_pair : FSM.mStates) + { + for (LLStateDiagram::Transitions::value_type& transition_pair : state_pair.second) + { + s << state_pair.first->getName() << " -- " << transition_pair.first->getName() + << " --> " << transition_pair.second->getName() << "\n"; + } + s << "\n"; + } + + return s; } //----------------------------------------------------------------------------- @@ -283,11 +283,11 @@ std::ostream& operator<<(std::ostream &s, LLStateDiagram &FSM) LLStateMachine::LLStateMachine() { - // we haven't received a starting state yet - mCurrentState = NULL; - mLastState = NULL; - mLastTransition = NULL; - mStateDiagram = NULL; + // we haven't received a starting state yet + mCurrentState = NULL; + mLastState = NULL; + mLastTransition = NULL; + mStateDiagram = NULL; } LLStateMachine::~LLStateMachine() @@ -296,89 +296,89 @@ LLStateMachine::~LLStateMachine() } // returns current state -LLFSMState* LLStateMachine::getCurrentState() const +LLFSMState* LLStateMachine::getCurrentState() const { - return mCurrentState; + return mCurrentState; } // executes current state void LLStateMachine::runCurrentState(void *data) { - mCurrentState->execute(data); + mCurrentState->execute(data); } // set current state BOOL LLStateMachine::setCurrentState(LLFSMState *initial_state, void* user_data, BOOL skip_entry) { - llassert(mStateDiagram); - - if (mStateDiagram->stateIsValid(*initial_state)) - { - mLastState = mCurrentState = initial_state; - if (!skip_entry) - { - initial_state->onEntry(user_data); - } - return TRUE; - } - - return FALSE; + llassert(mStateDiagram); + + if (mStateDiagram->stateIsValid(*initial_state)) + { + mLastState = mCurrentState = initial_state; + if (!skip_entry) + { + initial_state->onEntry(user_data); + } + return TRUE; + } + + return FALSE; } BOOL LLStateMachine::setCurrentState(U32 state_id, void* user_data, BOOL skip_entry) { - llassert(mStateDiagram); + llassert(mStateDiagram); - LLFSMState* state = mStateDiagram->getState(state_id); + LLFSMState* state = mStateDiagram->getState(state_id); - if (state) - { - mLastState = mCurrentState = state; - if (!skip_entry) - { - state->onEntry(user_data); - } - return TRUE; - } + if (state) + { + mLastState = mCurrentState = state; + if (!skip_entry) + { + state->onEntry(user_data); + } + return TRUE; + } - return FALSE; + return FALSE; } void LLStateMachine::processTransition(LLFSMTransition& transition, void* user_data) { - llassert(mStateDiagram); - - if (NULL == mCurrentState) - { - LL_WARNS() << "mCurrentState == NULL; aborting processTransition()" << LL_ENDL; - return; - } - - LLFSMState* new_state = mStateDiagram->processTransition(*mCurrentState, transition); - - if (NULL == new_state) - { - LL_WARNS() << "new_state == NULL; aborting processTransition()" << LL_ENDL; - return; - } - - mLastTransition = &transition; - mLastState = mCurrentState; - - if (*mCurrentState != *new_state) - { - mCurrentState->onExit(user_data); - mCurrentState = new_state; - mCurrentState->onEntry(user_data); + llassert(mStateDiagram); + + if (NULL == mCurrentState) + { + LL_WARNS() << "mCurrentState == NULL; aborting processTransition()" << LL_ENDL; + return; + } + + LLFSMState* new_state = mStateDiagram->processTransition(*mCurrentState, transition); + + if (NULL == new_state) + { + LL_WARNS() << "new_state == NULL; aborting processTransition()" << LL_ENDL; + return; + } + + mLastTransition = &transition; + mLastState = mCurrentState; + + if (*mCurrentState != *new_state) + { + mCurrentState->onExit(user_data); + mCurrentState = new_state; + mCurrentState->onEntry(user_data); #if FSM_PRINT_STATE_TRANSITIONS - LL_INFOS() << "Entering state " << mCurrentState->getName() << - " on transition " << transition.getName() << " from state " << - mLastState->getName() << LL_ENDL; + LL_INFOS() << "Entering state " << mCurrentState->getName() << + " on transition " << transition.getName() << " from state " << + mLastState->getName() << LL_ENDL; #endif - } + } } void LLStateMachine::setStateDiagram(LLStateDiagram* diagram) { - mStateDiagram = diagram; + mStateDiagram = diagram; } diff --git a/indra/llcharacter/llstatemachine.h b/indra/llcharacter/llstatemachine.h index a2f7e59bd2..2dfd106b18 100644 --- a/indra/llcharacter/llstatemachine.h +++ b/indra/llcharacter/llstatemachine.h @@ -1,25 +1,25 @@ -/** +/** * @file llstatemachine.h * @brief LLStateMachine class header file. * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -34,32 +34,32 @@ class LLUniqueID { - friend bool operator==(const LLUniqueID &a, const LLUniqueID &b); - friend bool operator!=(const LLUniqueID &a, const LLUniqueID &b); + friend bool operator==(const LLUniqueID &a, const LLUniqueID &b); + friend bool operator!=(const LLUniqueID &a, const LLUniqueID &b); protected: - static U32 sNextID; - U32 mId; + static U32 sNextID; + U32 mId; public: - LLUniqueID(){mId = sNextID++;} - virtual ~LLUniqueID(){} - U32 getID() {return mId;} + LLUniqueID(){mId = sNextID++;} + virtual ~LLUniqueID(){} + U32 getID() {return mId;} }; class LLFSMTransition : public LLUniqueID { public: - LLFSMTransition() : LLUniqueID(){}; - virtual std::string getName()const { return "unnamed"; } + LLFSMTransition() : LLUniqueID(){}; + virtual std::string getName()const { return "unnamed"; } }; class LLFSMState : public LLUniqueID { public: - LLFSMState() : LLUniqueID(){}; - virtual void onEntry(void *){}; - virtual void onExit(void *){}; - virtual void execute(void *){}; - virtual std::string getName() const { return "unnamed"; } + LLFSMState() : LLUniqueID(){}; + virtual void onEntry(void *){}; + virtual void onExit(void *){}; + virtual void execute(void *){}; + virtual std::string getName() const { return "unnamed"; } }; class LLStateDiagram @@ -70,78 +70,78 @@ friend std::ostream& operator<<(std::ostream &s, LLStateDiagram &FSM); friend class LLStateMachine; protected: - typedef std::map<LLFSMState*, Transitions> StateMap; - StateMap mStates; - Transitions mDefaultTransitions; - LLFSMState* mDefaultState; - BOOL mUseDefaultState; + typedef std::map<LLFSMState*, Transitions> StateMap; + StateMap mStates; + Transitions mDefaultTransitions; + LLFSMState* mDefaultState; + BOOL mUseDefaultState; public: - LLStateDiagram(); - virtual ~LLStateDiagram(); + LLStateDiagram(); + virtual ~LLStateDiagram(); protected: - // add a state to the state graph, executed implicitly when adding transitions - BOOL addState(LLFSMState *state); + // add a state to the state graph, executed implicitly when adding transitions + BOOL addState(LLFSMState *state); - // add a directed transition between 2 states - BOOL addTransition(LLFSMState& start_state, LLFSMState& end_state, LLFSMTransition& transition); + // add a directed transition between 2 states + BOOL addTransition(LLFSMState& start_state, LLFSMState& end_state, LLFSMTransition& transition); - // add an undirected transition between 2 states - BOOL addUndirectedTransition(LLFSMState& start_state, LLFSMState& end_state, LLFSMTransition& transition); + // add an undirected transition between 2 states + BOOL addUndirectedTransition(LLFSMState& start_state, LLFSMState& end_state, LLFSMTransition& transition); - // add a transition that is taken if none other exist - void addDefaultTransition(LLFSMState& end_state, LLFSMTransition& transition); + // add a transition that is taken if none other exist + void addDefaultTransition(LLFSMState& end_state, LLFSMTransition& transition); - // process a possible transition, and get the resulting state - LLFSMState* processTransition(LLFSMState& start_state, LLFSMTransition& transition); + // process a possible transition, and get the resulting state + LLFSMState* processTransition(LLFSMState& start_state, LLFSMTransition& transition); - // add a transition that exists for every state - void setDefaultState(LLFSMState& default_state); + // add a transition that exists for every state + void setDefaultState(LLFSMState& default_state); - // return total number of states with no outgoing transitions - S32 numDeadendStates(); + // return total number of states with no outgoing transitions + S32 numDeadendStates(); - // does this state exist in the state diagram? - BOOL stateIsValid(LLFSMState& state); + // does this state exist in the state diagram? + BOOL stateIsValid(LLFSMState& state); - // get a state pointer by ID - LLFSMState* getState(U32 state_id); + // get a state pointer by ID + LLFSMState* getState(U32 state_id); public: - // save the graph in a DOT file for rendering and visualization - BOOL saveDotFile(const std::string& filename); + // save the graph in a DOT file for rendering and visualization + BOOL saveDotFile(const std::string& filename); }; class LLStateMachine { protected: - LLFSMState* mCurrentState; - LLFSMState* mLastState; - LLFSMTransition* mLastTransition; - LLStateDiagram* mStateDiagram; + LLFSMState* mCurrentState; + LLFSMState* mLastState; + LLFSMTransition* mLastTransition; + LLStateDiagram* mStateDiagram; public: - LLStateMachine(); - virtual ~LLStateMachine(); + LLStateMachine(); + virtual ~LLStateMachine(); - // set state diagram - void setStateDiagram(LLStateDiagram* diagram); + // set state diagram + void setStateDiagram(LLStateDiagram* diagram); - // process this transition - void processTransition(LLFSMTransition &transition, void* user_data); + // process this transition + void processTransition(LLFSMTransition &transition, void* user_data); - // returns current state - LLFSMState* getCurrentState() const; + // returns current state + LLFSMState* getCurrentState() const; - // execute current state - void runCurrentState(void *data); + // execute current state + void runCurrentState(void *data); - // set state by state pointer - BOOL setCurrentState(LLFSMState *initial_state, void* user_data, BOOL skip_entry = TRUE); + // set state by state pointer + BOOL setCurrentState(LLFSMState *initial_state, void* user_data, BOOL skip_entry = TRUE); - // set state by unique ID - BOOL setCurrentState(U32 state_id, void* user_data, BOOL skip_entry = TRUE); + // set state by unique ID + BOOL setCurrentState(U32 state_id, void* user_data, BOOL skip_entry = TRUE); }; #endif //_LL_LLSTATEMACHINE_H diff --git a/indra/llcharacter/lltargetingmotion.cpp b/indra/llcharacter/lltargetingmotion.cpp index ec75212a40..38cba7b778 100644 --- a/indra/llcharacter/lltargetingmotion.cpp +++ b/indra/llcharacter/lltargetingmotion.cpp @@ -1,25 +1,25 @@ -/** +/** * @file lltargetingmotion.cpp * @brief Implementation of LLTargetingMotion class. * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -45,10 +45,10 @@ const F32 TORSO_TARGET_HALF_LIFE = 0.25f; //----------------------------------------------------------------------------- LLTargetingMotion::LLTargetingMotion(const LLUUID &id) : LLMotion(id) { - mCharacter = NULL; - mName = "targeting"; + mCharacter = NULL; + mName = "targeting"; - mTorsoState = new LLJointState; + mTorsoState = new LLJointState; } @@ -65,29 +65,29 @@ LLTargetingMotion::~LLTargetingMotion() //----------------------------------------------------------------------------- LLMotion::LLMotionInitStatus LLTargetingMotion::onInitialize(LLCharacter *character) { - // save character for future use - mCharacter = character; + // save character for future use + mCharacter = character; - mPelvisJoint = mCharacter->getJoint("mPelvis"); - mTorsoJoint = mCharacter->getJoint("mTorso"); - mRightHandJoint = mCharacter->getJoint("mWristRight"); + mPelvisJoint = mCharacter->getJoint("mPelvis"); + mTorsoJoint = mCharacter->getJoint("mTorso"); + mRightHandJoint = mCharacter->getJoint("mWristRight"); - // make sure character skeleton is copacetic - if (!mPelvisJoint || - !mTorsoJoint || - !mRightHandJoint) - { - LL_WARNS() << "Invalid skeleton for targeting motion!" << LL_ENDL; - return STATUS_FAILURE; - } + // make sure character skeleton is copacetic + if (!mPelvisJoint || + !mTorsoJoint || + !mRightHandJoint) + { + LL_WARNS() << "Invalid skeleton for targeting motion!" << LL_ENDL; + return STATUS_FAILURE; + } - mTorsoState->setJoint( mTorsoJoint ); + mTorsoState->setJoint( mTorsoJoint ); - // add joint states to the pose - mTorsoState->setUsage(LLJointState::ROT); - addJointState( mTorsoState ); + // add joint states to the pose + mTorsoState->setUsage(LLJointState::ROT); + addJointState( mTorsoState ); - return STATUS_SUCCESS; + return STATUS_SUCCESS; } //----------------------------------------------------------------------------- @@ -95,7 +95,7 @@ LLMotion::LLMotionInitStatus LLTargetingMotion::onInitialize(LLCharacter *charac //----------------------------------------------------------------------------- BOOL LLTargetingMotion::onActivate() { - return TRUE; + return TRUE; } //----------------------------------------------------------------------------- @@ -104,58 +104,58 @@ BOOL LLTargetingMotion::onActivate() BOOL LLTargetingMotion::onUpdate(F32 time, U8* joint_mask) { LL_PROFILE_ZONE_SCOPED; - F32 slerp_amt = LLSmoothInterpolation::getInterpolant(TORSO_TARGET_HALF_LIFE); - - LLVector3 target; - LLVector3* lookAtPoint = (LLVector3*)mCharacter->getAnimationData("LookAtPoint"); - - BOOL result = TRUE; - - if (!lookAtPoint) - { - return TRUE; - } - else - { - target = *lookAtPoint; - target.normVec(); - } - - //LLVector3 target_plane_normal = LLVector3(1.f, 0.f, 0.f) * mPelvisJoint->getWorldRotation(); - //LLVector3 torso_dir = LLVector3(1.f, 0.f, 0.f) * (mTorsoJoint->getWorldRotation() * mTorsoState->getRotation()); - - LLVector3 skyward(0.f, 0.f, 1.f); - LLVector3 left(skyward % target); - left.normVec(); - LLVector3 up(target % left); - up.normVec(); - LLQuaternion target_aim_rot(target, left, up); - - LLQuaternion cur_torso_rot = mTorsoJoint->getWorldRotation(); - - LLVector3 right_hand_at = LLVector3(0.f, -1.f, 0.f) * mRightHandJoint->getWorldRotation(); - left.setVec(skyward % right_hand_at); - left.normVec(); - up.setVec(right_hand_at % left); - up.normVec(); - LLQuaternion right_hand_rot(right_hand_at, left, up); - - LLQuaternion new_torso_rot = (cur_torso_rot * ~right_hand_rot) * target_aim_rot; - - // find ideal additive rotation to make torso point in correct direction - new_torso_rot = new_torso_rot * ~cur_torso_rot; - - // slerp from current additive rotation to ideal additive rotation - new_torso_rot = nlerp(slerp_amt, mTorsoState->getRotation(), new_torso_rot); - - // constraint overall torso rotation - LLQuaternion total_rot = new_torso_rot * mTorsoJoint->getRotation(); - total_rot.constrain(F_PI_BY_TWO * 0.8f); - new_torso_rot = total_rot * ~mTorsoJoint->getRotation(); - - mTorsoState->setRotation(new_torso_rot); - - return result; + F32 slerp_amt = LLSmoothInterpolation::getInterpolant(TORSO_TARGET_HALF_LIFE); + + LLVector3 target; + LLVector3* lookAtPoint = (LLVector3*)mCharacter->getAnimationData("LookAtPoint"); + + BOOL result = TRUE; + + if (!lookAtPoint) + { + return TRUE; + } + else + { + target = *lookAtPoint; + target.normVec(); + } + + //LLVector3 target_plane_normal = LLVector3(1.f, 0.f, 0.f) * mPelvisJoint->getWorldRotation(); + //LLVector3 torso_dir = LLVector3(1.f, 0.f, 0.f) * (mTorsoJoint->getWorldRotation() * mTorsoState->getRotation()); + + LLVector3 skyward(0.f, 0.f, 1.f); + LLVector3 left(skyward % target); + left.normVec(); + LLVector3 up(target % left); + up.normVec(); + LLQuaternion target_aim_rot(target, left, up); + + LLQuaternion cur_torso_rot = mTorsoJoint->getWorldRotation(); + + LLVector3 right_hand_at = LLVector3(0.f, -1.f, 0.f) * mRightHandJoint->getWorldRotation(); + left.setVec(skyward % right_hand_at); + left.normVec(); + up.setVec(right_hand_at % left); + up.normVec(); + LLQuaternion right_hand_rot(right_hand_at, left, up); + + LLQuaternion new_torso_rot = (cur_torso_rot * ~right_hand_rot) * target_aim_rot; + + // find ideal additive rotation to make torso point in correct direction + new_torso_rot = new_torso_rot * ~cur_torso_rot; + + // slerp from current additive rotation to ideal additive rotation + new_torso_rot = nlerp(slerp_amt, mTorsoState->getRotation(), new_torso_rot); + + // constraint overall torso rotation + LLQuaternion total_rot = new_torso_rot * mTorsoJoint->getRotation(); + total_rot.constrain(F_PI_BY_TWO * 0.8f); + new_torso_rot = total_rot * ~mTorsoJoint->getRotation(); + + mTorsoState->setRotation(new_torso_rot); + + return result; } //----------------------------------------------------------------------------- diff --git a/indra/llcharacter/lltargetingmotion.h b/indra/llcharacter/lltargetingmotion.h index 0971417e1e..7a3f5566ac 100644 --- a/indra/llcharacter/lltargetingmotion.h +++ b/indra/llcharacter/lltargetingmotion.h @@ -1,25 +1,25 @@ -/** +/** * @file lltargetingmotion.h * @brief Implementation of LLTargetingMotion class. * * $LicenseInfo:firstyear=2002&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -32,7 +32,7 @@ //----------------------------------------------------------------------------- #include "llmotion.h" -#define TARGETING_EASEIN_DURATION 0.3f +#define TARGETING_EASEIN_DURATION 0.3f #define TARGETING_EASEOUT_DURATION 0.5f #define TARGETING_PRIORITY LLJoint::HIGH_PRIORITY #define MIN_REQUIRED_PIXEL_AREA_TARGETING 1000.f; @@ -42,74 +42,74 @@ // class LLTargetingMotion //----------------------------------------------------------------------------- class LLTargetingMotion : - public LLMotion + public LLMotion { public: - // Constructor - LLTargetingMotion(const LLUUID &id); + // Constructor + LLTargetingMotion(const LLUUID &id); - // Destructor - virtual ~LLTargetingMotion(); + // Destructor + virtual ~LLTargetingMotion(); public: - //------------------------------------------------------------------------- - // functions to support MotionController and MotionRegistry - //------------------------------------------------------------------------- + //------------------------------------------------------------------------- + // functions to support MotionController and MotionRegistry + //------------------------------------------------------------------------- - // static constructor - // all subclasses must implement such a function and register it - static LLMotion *create(const LLUUID &id) { return new LLTargetingMotion(id); } + // static constructor + // all subclasses must implement such a function and register it + static LLMotion *create(const LLUUID &id) { return new LLTargetingMotion(id); } public: - //------------------------------------------------------------------------- - // animation callbacks to be implemented by subclasses - //------------------------------------------------------------------------- + //------------------------------------------------------------------------- + // animation callbacks to be implemented by subclasses + //------------------------------------------------------------------------- - // motions must specify whether or not they loop - virtual BOOL getLoop() { return TRUE; } + // motions must specify whether or not they loop + virtual BOOL getLoop() { return TRUE; } - // motions must report their total duration - virtual F32 getDuration() { return 0.0; } + // motions must report their total duration + virtual F32 getDuration() { return 0.0; } - // motions must report their "ease in" duration - virtual F32 getEaseInDuration() { return TARGETING_EASEIN_DURATION; } + // motions must report their "ease in" duration + virtual F32 getEaseInDuration() { return TARGETING_EASEIN_DURATION; } - // motions must report their "ease out" duration. - virtual F32 getEaseOutDuration() { return TARGETING_EASEOUT_DURATION; } + // motions must report their "ease out" duration. + virtual F32 getEaseOutDuration() { return TARGETING_EASEOUT_DURATION; } - // motions must report their priority - virtual LLJoint::JointPriority getPriority() { return TARGETING_PRIORITY; } + // motions must report their priority + virtual LLJoint::JointPriority getPriority() { return TARGETING_PRIORITY; } - virtual LLMotionBlendType getBlendType() { return ADDITIVE_BLEND; } + virtual LLMotionBlendType getBlendType() { return ADDITIVE_BLEND; } - // called to determine when a motion should be activated/deactivated based on avatar pixel coverage - virtual F32 getMinPixelArea() { return MIN_REQUIRED_PIXEL_AREA_TARGETING; } + // called to determine when a motion should be activated/deactivated based on avatar pixel coverage + virtual F32 getMinPixelArea() { return MIN_REQUIRED_PIXEL_AREA_TARGETING; } - // run-time (post constructor) initialization, - // called after parameters have been set - // must return true to indicate success and be available for activation - virtual LLMotionInitStatus onInitialize(LLCharacter *character); + // run-time (post constructor) initialization, + // called after parameters have been set + // must return true to indicate success and be available for activation + virtual LLMotionInitStatus onInitialize(LLCharacter *character); - // called when a motion is activated - // must return TRUE to indicate success, or else - // it will be deactivated - virtual BOOL onActivate(); + // called when a motion is activated + // must return TRUE to indicate success, or else + // it will be deactivated + virtual BOOL onActivate(); - // called per time step - // must return TRUE while it is active, and - // must return FALSE when the motion is completed. - virtual BOOL onUpdate(F32 time, U8* joint_mask); + // called per time step + // must return TRUE while it is active, and + // must return FALSE when the motion is completed. + virtual BOOL onUpdate(F32 time, U8* joint_mask); - // called when a motion is deactivated - virtual void onDeactivate(); + // called when a motion is deactivated + virtual void onDeactivate(); public: - LLCharacter *mCharacter; - LLPointer<LLJointState> mTorsoState; - LLJoint* mPelvisJoint; - LLJoint* mTorsoJoint; - LLJoint* mRightHandJoint; + LLCharacter *mCharacter; + LLPointer<LLJointState> mTorsoState; + LLJoint* mPelvisJoint; + LLJoint* mTorsoJoint; + LLJoint* mRightHandJoint; }; #endif // LL_LLTARGETINGMOTION_H diff --git a/indra/llcharacter/llvisualparam.cpp b/indra/llcharacter/llvisualparam.cpp index 2235496ac5..3dbab7f081 100644 --- a/indra/llcharacter/llvisualparam.cpp +++ b/indra/llcharacter/llvisualparam.cpp @@ -1,25 +1,25 @@ -/** +/** * @file llvisualparam.cpp * @brief Implementation of LLPolyMesh class. * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -35,13 +35,13 @@ // LLVisualParamInfo() //----------------------------------------------------------------------------- LLVisualParamInfo::LLVisualParamInfo() - : - mID( -1 ), - mGroup( VISUAL_PARAM_GROUP_TWEAKABLE ), - mMinWeight( 0.f ), - mMaxWeight( 1.f ), - mDefaultWeight( 0.f ), - mSex( SEX_BOTH ) + : + mID( -1 ), + mGroup( VISUAL_PARAM_GROUP_TWEAKABLE ), + mMinWeight( 0.f ), + mMaxWeight( 1.f ), + mDefaultWeight( 0.f ), + mSex( SEX_BOTH ) { } @@ -50,125 +50,125 @@ LLVisualParamInfo::LLVisualParamInfo() //----------------------------------------------------------------------------- BOOL LLVisualParamInfo::parseXml(LLXmlTreeNode *node) { - // attribute: id - static LLStdStringHandle id_string = LLXmlTree::addAttributeString("id"); - node->getFastAttributeS32( id_string, mID ); - - // attribute: group - U32 group = 0; - static LLStdStringHandle group_string = LLXmlTree::addAttributeString("group"); - if( node->getFastAttributeU32( group_string, group ) ) - { - if( group < NUM_VISUAL_PARAM_GROUPS ) - { - mGroup = (EVisualParamGroup)group; - } - } - - // attribute: value_min, value_max - static LLStdStringHandle value_min_string = LLXmlTree::addAttributeString("value_min"); - static LLStdStringHandle value_max_string = LLXmlTree::addAttributeString("value_max"); - node->getFastAttributeF32( value_min_string, mMinWeight ); - node->getFastAttributeF32( value_max_string, mMaxWeight ); - - // attribute: value_default - F32 default_weight = 0; - static LLStdStringHandle value_default_string = LLXmlTree::addAttributeString("value_default"); - if( node->getFastAttributeF32( value_default_string, default_weight ) ) - { - mDefaultWeight = llclamp( default_weight, mMinWeight, mMaxWeight ); - if( default_weight != mDefaultWeight ) - { - LL_WARNS() << "value_default attribute is out of range in node " << mName << " " << default_weight << LL_ENDL; - } - } - - // attribute: sex - std::string sex = "both"; - static LLStdStringHandle sex_string = LLXmlTree::addAttributeString("sex"); - node->getFastAttributeString( sex_string, sex ); // optional - if( sex == "both" ) - { - mSex = SEX_BOTH; - } - else if( sex == "male" ) - { - mSex = SEX_MALE; - } - else if( sex == "female" ) - { - mSex = SEX_FEMALE; - } - else - { - LL_WARNS() << "Avatar file: <param> has invalid sex attribute: " << sex << LL_ENDL; - return FALSE; - } - - // attribute: name - static LLStdStringHandle name_string = LLXmlTree::addAttributeString("name"); - if( !node->getFastAttributeString( name_string, mName ) ) - { - LL_WARNS() << "Avatar file: <param> is missing name attribute" << LL_ENDL; - return FALSE; - } - - // attribute: label - static LLStdStringHandle label_string = LLXmlTree::addAttributeString("label"); - if( !node->getFastAttributeString( label_string, mDisplayName ) ) - { - mDisplayName = mName; - } - - // JC - make sure the display name includes the capitalization in the XML file, - // not the lowercased version. - LLStringUtil::toLower(mName); - - // attribute: label_min - static LLStdStringHandle label_min_string = LLXmlTree::addAttributeString("label_min"); - if( !node->getFastAttributeString( label_min_string, mMinName ) ) - { - mMinName = "Less"; - } - - // attribute: label_max - static LLStdStringHandle label_max_string = LLXmlTree::addAttributeString("label_max"); - if( !node->getFastAttributeString( label_max_string, mMaxName ) ) - { - mMaxName = "More"; - } - - return TRUE; + // attribute: id + static LLStdStringHandle id_string = LLXmlTree::addAttributeString("id"); + node->getFastAttributeS32( id_string, mID ); + + // attribute: group + U32 group = 0; + static LLStdStringHandle group_string = LLXmlTree::addAttributeString("group"); + if( node->getFastAttributeU32( group_string, group ) ) + { + if( group < NUM_VISUAL_PARAM_GROUPS ) + { + mGroup = (EVisualParamGroup)group; + } + } + + // attribute: value_min, value_max + static LLStdStringHandle value_min_string = LLXmlTree::addAttributeString("value_min"); + static LLStdStringHandle value_max_string = LLXmlTree::addAttributeString("value_max"); + node->getFastAttributeF32( value_min_string, mMinWeight ); + node->getFastAttributeF32( value_max_string, mMaxWeight ); + + // attribute: value_default + F32 default_weight = 0; + static LLStdStringHandle value_default_string = LLXmlTree::addAttributeString("value_default"); + if( node->getFastAttributeF32( value_default_string, default_weight ) ) + { + mDefaultWeight = llclamp( default_weight, mMinWeight, mMaxWeight ); + if( default_weight != mDefaultWeight ) + { + LL_WARNS() << "value_default attribute is out of range in node " << mName << " " << default_weight << LL_ENDL; + } + } + + // attribute: sex + std::string sex = "both"; + static LLStdStringHandle sex_string = LLXmlTree::addAttributeString("sex"); + node->getFastAttributeString( sex_string, sex ); // optional + if( sex == "both" ) + { + mSex = SEX_BOTH; + } + else if( sex == "male" ) + { + mSex = SEX_MALE; + } + else if( sex == "female" ) + { + mSex = SEX_FEMALE; + } + else + { + LL_WARNS() << "Avatar file: <param> has invalid sex attribute: " << sex << LL_ENDL; + return FALSE; + } + + // attribute: name + static LLStdStringHandle name_string = LLXmlTree::addAttributeString("name"); + if( !node->getFastAttributeString( name_string, mName ) ) + { + LL_WARNS() << "Avatar file: <param> is missing name attribute" << LL_ENDL; + return FALSE; + } + + // attribute: label + static LLStdStringHandle label_string = LLXmlTree::addAttributeString("label"); + if( !node->getFastAttributeString( label_string, mDisplayName ) ) + { + mDisplayName = mName; + } + + // JC - make sure the display name includes the capitalization in the XML file, + // not the lowercased version. + LLStringUtil::toLower(mName); + + // attribute: label_min + static LLStdStringHandle label_min_string = LLXmlTree::addAttributeString("label_min"); + if( !node->getFastAttributeString( label_min_string, mMinName ) ) + { + mMinName = "Less"; + } + + // attribute: label_max + static LLStdStringHandle label_max_string = LLXmlTree::addAttributeString("label_max"); + if( !node->getFastAttributeString( label_max_string, mMaxName ) ) + { + mMaxName = "More"; + } + + return TRUE; } //virtual void LLVisualParamInfo::toStream(std::ostream &out) { - out << mID << "\t"; - out << mName << "\t"; - out << mDisplayName << "\t"; - out << mMinName << "\t"; - out << mMaxName << "\t"; - out << mGroup << "\t"; - out << mMinWeight << "\t"; - out << mMaxWeight << "\t"; - out << mDefaultWeight << "\t"; - out << mSex << "\t"; + out << mID << "\t"; + out << mName << "\t"; + out << mDisplayName << "\t"; + out << mMinName << "\t"; + out << mMaxName << "\t"; + out << mGroup << "\t"; + out << mMinWeight << "\t"; + out << mMaxWeight << "\t"; + out << mDefaultWeight << "\t"; + out << mSex << "\t"; } //----------------------------------------------------------------------------- // LLVisualParam() //----------------------------------------------------------------------------- LLVisualParam::LLVisualParam() - : mCurWeight( 0.f ), - mLastWeight( 0.f ), - mNext( NULL ), - mTargetWeight( 0.f ), - mIsAnimating( FALSE ), - mIsDummy(FALSE), - mID( -1 ), - mInfo( 0 ), - mParamLocation(LOC_UNKNOWN) + : mCurWeight( 0.f ), + mLastWeight( 0.f ), + mNext( NULL ), + mTargetWeight( 0.f ), + mIsAnimating( FALSE ), + mIsDummy(FALSE), + mID( -1 ), + mInfo( 0 ), + mParamLocation(LOC_UNKNOWN) { } @@ -176,15 +176,15 @@ LLVisualParam::LLVisualParam() // LLVisualParam() //----------------------------------------------------------------------------- LLVisualParam::LLVisualParam(const LLVisualParam& pOther) - : mCurWeight(pOther.mCurWeight), - mLastWeight(pOther.mLastWeight), - mNext(pOther.mNext), - mTargetWeight(pOther.mTargetWeight), - mIsAnimating(pOther.mIsAnimating), - mIsDummy(pOther.mIsDummy), - mID(pOther.mID), - mInfo(pOther.mInfo), - mParamLocation(pOther.mParamLocation) + : mCurWeight(pOther.mCurWeight), + mLastWeight(pOther.mLastWeight), + mNext(pOther.mNext), + mTargetWeight(pOther.mTargetWeight), + mIsAnimating(pOther.mIsAnimating), + mIsDummy(pOther.mIsDummy), + mID(pOther.mID), + mInfo(pOther.mInfo), + mParamLocation(pOther.mParamLocation) { } @@ -193,8 +193,8 @@ LLVisualParam::LLVisualParam(const LLVisualParam& pOther) //----------------------------------------------------------------------------- LLVisualParam::~LLVisualParam() { - delete mNext; - mNext = NULL; + delete mNext; + mNext = NULL; } /* @@ -209,13 +209,13 @@ LLVisualParam::~LLVisualParam() BOOL LLVisualParam::setInfo(LLVisualParamInfo *info) { - llassert(mInfo == NULL); - if (info->mID < 0) - return FALSE; - mInfo = info; - mID = info->mID; - setWeight(getDefaultWeight(), FALSE ); - return TRUE; + llassert(mInfo == NULL); + if (info->mID < 0) + return FALSE; + mInfo = info; + mID = info->mID; + setWeight(getDefaultWeight(), FALSE ); + return TRUE; } //----------------------------------------------------------------------------- @@ -223,13 +223,13 @@ BOOL LLVisualParam::setInfo(LLVisualParamInfo *info) //----------------------------------------------------------------------------- BOOL LLVisualParam::parseData(LLXmlTreeNode *node) { - LLVisualParamInfo *info = new LLVisualParamInfo; + LLVisualParamInfo *info = new LLVisualParamInfo; - info->parseXml(node); - if (!setInfo(info)) - return FALSE; - - return TRUE; + info->parseXml(node); + if (!setInfo(info)) + return FALSE; + + return TRUE; } */ @@ -238,24 +238,24 @@ BOOL LLVisualParam::parseData(LLXmlTreeNode *node) //----------------------------------------------------------------------------- void LLVisualParam::setWeight(F32 weight) { - if (mIsAnimating) - { - //RN: allow overshoot - mCurWeight = weight; - } - else if (mInfo) - { - mCurWeight = llclamp(weight, mInfo->mMinWeight, mInfo->mMaxWeight); - } - else - { - mCurWeight = weight; - } - - if (mNext) - { - mNext->setWeight(weight); - } + if (mIsAnimating) + { + //RN: allow overshoot + mCurWeight = weight; + } + else if (mInfo) + { + mCurWeight = llclamp(weight, mInfo->mMinWeight, mInfo->mMaxWeight); + } + else + { + mCurWeight = weight; + } + + if (mNext) + { + mNext->setWeight(weight); + } } //----------------------------------------------------------------------------- @@ -263,31 +263,31 @@ void LLVisualParam::setWeight(F32 weight) //----------------------------------------------------------------------------- void LLVisualParam::setAnimationTarget(F32 target_value) { - // don't animate dummy parameters - if (mIsDummy) - { - setWeight(target_value); - mTargetWeight = mCurWeight; - return; - } - - if (mInfo) - { - if (isTweakable()) - { - mTargetWeight = llclamp(target_value, mInfo->mMinWeight, mInfo->mMaxWeight); - } - } - else - { - mTargetWeight = target_value; - } - mIsAnimating = TRUE; - - if (mNext) - { - mNext->setAnimationTarget(target_value); - } + // don't animate dummy parameters + if (mIsDummy) + { + setWeight(target_value); + mTargetWeight = mCurWeight; + return; + } + + if (mInfo) + { + if (isTweakable()) + { + mTargetWeight = llclamp(target_value, mInfo->mMinWeight, mInfo->mMaxWeight); + } + } + else + { + mTargetWeight = target_value; + } + mIsAnimating = TRUE; + + if (mNext) + { + mNext->setAnimationTarget(target_value); + } } //----------------------------------------------------------------------------- @@ -295,9 +295,9 @@ void LLVisualParam::setAnimationTarget(F32 target_value) //----------------------------------------------------------------------------- void LLVisualParam::setNextParam( LLVisualParam *next ) { - llassert(!mNext); - llassert(getWeight() == getDefaultWeight()); // need to establish mNext before we start changing values on this, else initial value won't get mirrored (we can fix that, but better to forbid this pattern) - mNext = next; + llassert(!mNext); + llassert(getWeight() == getDefaultWeight()); // need to establish mNext before we start changing values on this, else initial value won't get mirrored (we can fix that, but better to forbid this pattern) + mNext = next; } //----------------------------------------------------------------------------- @@ -305,7 +305,7 @@ void LLVisualParam::setNextParam( LLVisualParam *next ) //----------------------------------------------------------------------------- void LLVisualParam::clearNextParam() { - mNext = NULL; + mNext = NULL; } //----------------------------------------------------------------------------- @@ -313,64 +313,64 @@ void LLVisualParam::clearNextParam() //----------------------------------------------------------------------------- void LLVisualParam::animate( F32 delta) { - if (mIsAnimating) - { - F32 new_weight = ((mTargetWeight - mCurWeight) * delta) + mCurWeight; - setWeight(new_weight); - } + if (mIsAnimating) + { + F32 new_weight = ((mTargetWeight - mCurWeight) * delta) + mCurWeight; + setWeight(new_weight); + } } //----------------------------------------------------------------------------- // stopAnimating() //----------------------------------------------------------------------------- void LLVisualParam::stopAnimating() -{ - if (mIsAnimating && isTweakable()) - { - mIsAnimating = FALSE; - setWeight(mTargetWeight); - } +{ + if (mIsAnimating && isTweakable()) + { + mIsAnimating = FALSE; + setWeight(mTargetWeight); + } } //virtual BOOL LLVisualParam::linkDrivenParams(visual_param_mapper mapper, BOOL only_cross_params) { - // nothing to do for non-driver parameters - return TRUE; + // nothing to do for non-driver parameters + return TRUE; } -//virtual +//virtual void LLVisualParam::resetDrivenParams() { - // nothing to do for non-driver parameters - return; + // nothing to do for non-driver parameters + return; } const std::string param_location_name(const EParamLocation& loc) { - switch (loc) - { - case LOC_UNKNOWN: return "unknown"; - case LOC_AV_SELF: return "self"; - case LOC_AV_OTHER: return "other"; - case LOC_WEARABLE: return "wearable"; - default: return "error"; - } + switch (loc) + { + case LOC_UNKNOWN: return "unknown"; + case LOC_AV_SELF: return "self"; + case LOC_AV_OTHER: return "other"; + case LOC_WEARABLE: return "wearable"; + default: return "error"; + } } void LLVisualParam::setParamLocation(EParamLocation loc) { - if (mParamLocation == LOC_UNKNOWN || loc == LOC_UNKNOWN) - { - mParamLocation = loc; - } - else if (mParamLocation == loc) - { - // no action - } - else - { - LL_DEBUGS() << "param location is already " << mParamLocation << ", not slamming to " << loc << LL_ENDL; - } + if (mParamLocation == LOC_UNKNOWN || loc == LOC_UNKNOWN) + { + mParamLocation = loc; + } + else if (mParamLocation == loc) + { + // no action + } + else + { + LL_DEBUGS() << "param location is already " << mParamLocation << ", not slamming to " << loc << LL_ENDL; + } } diff --git a/indra/llcharacter/llvisualparam.h b/indra/llcharacter/llvisualparam.h index 0ad063fd1e..4d760ed6fa 100644 --- a/indra/llcharacter/llvisualparam.h +++ b/indra/llcharacter/llvisualparam.h @@ -1,25 +1,25 @@ -/** +/** * @file llvisualparam.h * @brief Implementation of LLPolyMesh class. * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -37,26 +37,26 @@ class LLXmlTreeNode; enum ESex { - SEX_FEMALE = 0x01, - SEX_MALE = 0x02, - SEX_BOTH = 0x03 // values chosen to allow use as a bit field. + SEX_FEMALE = 0x01, + SEX_MALE = 0x02, + SEX_BOTH = 0x03 // values chosen to allow use as a bit field. }; enum EVisualParamGroup { - VISUAL_PARAM_GROUP_TWEAKABLE, - VISUAL_PARAM_GROUP_ANIMATABLE, - VISUAL_PARAM_GROUP_TWEAKABLE_NO_TRANSMIT, - VISUAL_PARAM_GROUP_TRANSMIT_NOT_TWEAKABLE, // deprecated params that used to be tweakable. - NUM_VISUAL_PARAM_GROUPS + VISUAL_PARAM_GROUP_TWEAKABLE, + VISUAL_PARAM_GROUP_ANIMATABLE, + VISUAL_PARAM_GROUP_TWEAKABLE_NO_TRANSMIT, + VISUAL_PARAM_GROUP_TRANSMIT_NOT_TWEAKABLE, // deprecated params that used to be tweakable. + NUM_VISUAL_PARAM_GROUPS }; enum EParamLocation { - LOC_UNKNOWN, - LOC_AV_SELF, - LOC_AV_OTHER, - LOC_WEARABLE + LOC_UNKNOWN, + LOC_AV_SELF, + LOC_AV_OTHER, + LOC_WEARABLE }; const std::string param_location_name(const EParamLocation& loc); @@ -69,29 +69,29 @@ const S32 MAX_TRANSMITTED_VISUAL_PARAMS = 255; //----------------------------------------------------------------------------- class LLVisualParamInfo { - friend class LLVisualParam; + friend class LLVisualParam; public: - LLVisualParamInfo(); - virtual ~LLVisualParamInfo() {}; + LLVisualParamInfo(); + virtual ~LLVisualParamInfo() {}; + + virtual BOOL parseXml(LLXmlTreeNode *node); - virtual BOOL parseXml(LLXmlTreeNode *node); + S32 getID() const { return mID; } - S32 getID() const { return mID; } + virtual void toStream(std::ostream &out); - virtual void toStream(std::ostream &out); - protected: - S32 mID; // ID associated with VisualParam - - std::string mName; // name (for internal purposes) - std::string mDisplayName; // name displayed to the user - std::string mMinName; // name associated with minimum value - std::string mMaxName; // name associated with maximum value - EVisualParamGroup mGroup; // morph group for separating UI controls - F32 mMinWeight; // minimum weight that can be assigned to this morph target - F32 mMaxWeight; // maximum weight that can be assigned to this morph target - F32 mDefaultWeight; - ESex mSex; // Which gender(s) this param applies to. + S32 mID; // ID associated with VisualParam + + std::string mName; // name (for internal purposes) + std::string mDisplayName; // name displayed to the user + std::string mMinName; // name associated with minimum value + std::string mMaxName; // name associated with maximum value + EVisualParamGroup mGroup; // morph group for separating UI controls + F32 mMinWeight; // minimum weight that can be assigned to this morph target + F32 mMaxWeight; // maximum weight that can be assigned to this morph target + F32 mDefaultWeight; + ESex mSex; // Which gender(s) this param applies to. }; //----------------------------------------------------------------------------- @@ -104,82 +104,82 @@ LL_ALIGN_PREFIX(16) class LLVisualParam { public: - typedef boost::function<LLVisualParam*(S32)> visual_param_mapper; - - LLVisualParam(); - virtual ~LLVisualParam(); - - // Special: These functions are overridden by child classes - // (They can not be virtual because they use specific derived Info classes) - LLVisualParamInfo* getInfo() const { return mInfo; } - // This sets mInfo and calls initialization functions - BOOL setInfo(LLVisualParamInfo *info); - - // Virtual functions - // Pure virtuals - //virtual BOOL parseData( LLXmlTreeNode *node ) = 0; - virtual void apply( ESex avatar_sex ) = 0; - // Default functions - virtual void setWeight(F32 weight); - virtual void setAnimationTarget( F32 target_value); - virtual void animate(F32 delta); - virtual void stopAnimating(); - - virtual BOOL linkDrivenParams(visual_param_mapper mapper, BOOL only_cross_params); - virtual void resetDrivenParams(); - - // Interface methods - S32 getID() const { return mID; } - void setID(S32 id) { llassert(!mInfo); mID = id; } - - const std::string& getName() const { return mInfo->mName; } - const std::string& getDisplayName() const { return mInfo->mDisplayName; } - const std::string& getMaxDisplayName() const { return mInfo->mMaxName; } - const std::string& getMinDisplayName() const { return mInfo->mMinName; } - - void setDisplayName(const std::string& s) { mInfo->mDisplayName = s; } - void setMaxDisplayName(const std::string& s) { mInfo->mMaxName = s; } - void setMinDisplayName(const std::string& s) { mInfo->mMinName = s; } - - EVisualParamGroup getGroup() const { return mInfo->mGroup; } - F32 getMinWeight() const { return mInfo->mMinWeight; } - F32 getMaxWeight() const { return mInfo->mMaxWeight; } - F32 getDefaultWeight() const { return mInfo->mDefaultWeight; } - ESex getSex() const { return mInfo->mSex; } - - F32 getWeight() const { return mIsAnimating ? mTargetWeight : mCurWeight; } - F32 getCurrentWeight() const { return mCurWeight; } - F32 getLastWeight() const { return mLastWeight; } - void setLastWeight(F32 val) { mLastWeight = val; } - BOOL isAnimating() const { return mIsAnimating; } - BOOL isTweakable() const { return (getGroup() == VISUAL_PARAM_GROUP_TWEAKABLE) || (getGroup() == VISUAL_PARAM_GROUP_TWEAKABLE_NO_TRANSMIT); } - - LLVisualParam* getNextParam() { return mNext; } - void setNextParam( LLVisualParam *next ); - void clearNextParam(); - - virtual void setAnimating(BOOL is_animating) { mIsAnimating = is_animating && !mIsDummy; } - BOOL getAnimating() const { return mIsAnimating; } - - void setIsDummy(BOOL is_dummy) { mIsDummy = is_dummy; } - - void setParamLocation(EParamLocation loc); - EParamLocation getParamLocation() const { return mParamLocation; } + typedef boost::function<LLVisualParam*(S32)> visual_param_mapper; + + LLVisualParam(); + virtual ~LLVisualParam(); + + // Special: These functions are overridden by child classes + // (They can not be virtual because they use specific derived Info classes) + LLVisualParamInfo* getInfo() const { return mInfo; } + // This sets mInfo and calls initialization functions + BOOL setInfo(LLVisualParamInfo *info); + + // Virtual functions + // Pure virtuals + //virtual BOOL parseData( LLXmlTreeNode *node ) = 0; + virtual void apply( ESex avatar_sex ) = 0; + // Default functions + virtual void setWeight(F32 weight); + virtual void setAnimationTarget( F32 target_value); + virtual void animate(F32 delta); + virtual void stopAnimating(); + + virtual BOOL linkDrivenParams(visual_param_mapper mapper, BOOL only_cross_params); + virtual void resetDrivenParams(); + + // Interface methods + S32 getID() const { return mID; } + void setID(S32 id) { llassert(!mInfo); mID = id; } + + const std::string& getName() const { return mInfo->mName; } + const std::string& getDisplayName() const { return mInfo->mDisplayName; } + const std::string& getMaxDisplayName() const { return mInfo->mMaxName; } + const std::string& getMinDisplayName() const { return mInfo->mMinName; } + + void setDisplayName(const std::string& s) { mInfo->mDisplayName = s; } + void setMaxDisplayName(const std::string& s) { mInfo->mMaxName = s; } + void setMinDisplayName(const std::string& s) { mInfo->mMinName = s; } + + EVisualParamGroup getGroup() const { return mInfo->mGroup; } + F32 getMinWeight() const { return mInfo->mMinWeight; } + F32 getMaxWeight() const { return mInfo->mMaxWeight; } + F32 getDefaultWeight() const { return mInfo->mDefaultWeight; } + ESex getSex() const { return mInfo->mSex; } + + F32 getWeight() const { return mIsAnimating ? mTargetWeight : mCurWeight; } + F32 getCurrentWeight() const { return mCurWeight; } + F32 getLastWeight() const { return mLastWeight; } + void setLastWeight(F32 val) { mLastWeight = val; } + BOOL isAnimating() const { return mIsAnimating; } + BOOL isTweakable() const { return (getGroup() == VISUAL_PARAM_GROUP_TWEAKABLE) || (getGroup() == VISUAL_PARAM_GROUP_TWEAKABLE_NO_TRANSMIT); } + + LLVisualParam* getNextParam() { return mNext; } + void setNextParam( LLVisualParam *next ); + void clearNextParam(); + + virtual void setAnimating(BOOL is_animating) { mIsAnimating = is_animating && !mIsDummy; } + BOOL getAnimating() const { return mIsAnimating; } + + void setIsDummy(BOOL is_dummy) { mIsDummy = is_dummy; } + + void setParamLocation(EParamLocation loc); + EParamLocation getParamLocation() const { return mParamLocation; } protected: - LLVisualParam(const LLVisualParam& pOther); + LLVisualParam(const LLVisualParam& pOther); - F32 mCurWeight; // current weight - F32 mLastWeight; // last weight - LLVisualParam* mNext; // next param in a shared chain - F32 mTargetWeight; // interpolation target - BOOL mIsAnimating; // this value has been given an interpolation target - BOOL mIsDummy; // this is used to prevent dummy visual params from animating + F32 mCurWeight; // current weight + F32 mLastWeight; // last weight + LLVisualParam* mNext; // next param in a shared chain + F32 mTargetWeight; // interpolation target + BOOL mIsAnimating; // this value has been given an interpolation target + BOOL mIsDummy; // this is used to prevent dummy visual params from animating - S32 mID; // id for storing weight/morphtarget compares compactly - LLVisualParamInfo *mInfo; - EParamLocation mParamLocation; // where does this visual param live? + S32 mID; // id for storing weight/morphtarget compares compactly + LLVisualParamInfo *mInfo; + EParamLocation mParamLocation; // where does this visual param live? } LL_ALIGN_POSTFIX(16); #endif // LL_LLVisualParam_H diff --git a/indra/llcharacter/tests/lljoint_test.cpp b/indra/llcharacter/tests/lljoint_test.cpp index 617f31b0e4..5a813bac4a 100644 --- a/indra/llcharacter/tests/lljoint_test.cpp +++ b/indra/llcharacter/tests/lljoint_test.cpp @@ -7,21 +7,21 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -37,199 +37,199 @@ namespace tut { - struct lljoint_data - { - }; - typedef test_group<lljoint_data> lljoint_test; - typedef lljoint_test::object lljoint_object; - tut::lljoint_test lljoint_testcase("LLJoint"); - - template<> template<> - void lljoint_object::test<1>() - { - LLJoint lljoint; - LLJoint* jnt = lljoint.getParent(); - ensure("getParent() failed ", (NULL == jnt)); - ensure("getRoot() failed ", (&lljoint == lljoint.getRoot())); - } - - template<> template<> - void lljoint_object::test<2>() - { - std::string str = "LLJoint"; - LLJoint parent(str), child; - child.setup(str, &parent); - LLJoint* jnt = child.getParent(); - ensure("setup() failed ", (&parent == jnt)); - } - - template<> template<> - void lljoint_object::test<3>() - { - LLJoint parent, child; - std::string str = "LLJoint"; - child.setup(str, &parent); - LLJoint* jnt = parent.findJoint(str); - ensure("findJoint() failed ", (&child == jnt)); - } - - template<> template<> - void lljoint_object::test<4>() - { - LLJoint parent; - std::string str1 = "LLJoint", str2; - parent.setName(str1); - str2 = parent.getName(); - ensure("setName() failed ", (str1 == str2)); - } - - template<> template<> - void lljoint_object::test<5>() - { - LLJoint lljoint; - LLVector3 vec3(2.3f,30.f,10.f); - // SL-315 - lljoint.setPosition(vec3); - LLVector3 pos = lljoint.getPosition(); - ensure("setPosition()/getPosition() failed ", (vec3 == pos)); - } - - template<> template<> - void lljoint_object::test<6>() - { - LLJoint lljoint; - LLVector3 vec3(2.3f,30.f,10.f); - // SL-315 - lljoint.setWorldPosition(vec3); - LLVector3 pos = lljoint.getWorldPosition(); - ensure("1:setWorldPosition()/getWorldPosition() failed ", (vec3 == pos)); - LLVector3 lastPos = lljoint.getLastWorldPosition(); - ensure("2:getLastWorldPosition failed ", (vec3 == lastPos)); - } - - template<> template<> - void lljoint_object::test<7>() - { - LLJoint lljoint("LLJoint"); - LLQuaternion q(2.3f,30.f,10.f,1.f); - lljoint.setRotation(q); - LLQuaternion rot = lljoint.getRotation(); - ensure("setRotation()/getRotation() failed ", (q == rot)); - } - template<> template<> - void lljoint_object::test<8>() - { - LLJoint lljoint("LLJoint"); - LLQuaternion q(2.3f,30.f,10.f,1.f); - lljoint.setWorldRotation(q); - LLQuaternion rot = lljoint.getWorldRotation(); - ensure("1:setWorldRotation()/getWorldRotation() failed ", (q == rot)); - LLQuaternion lastRot = lljoint.getLastWorldRotation(); - ensure("2:getLastWorldRotation failed ", (q == lastRot)); - } - - template<> template<> - void lljoint_object::test<9>() - { - LLJoint lljoint; - LLVector3 vec3(2.3f,30.f,10.f); - lljoint.setScale(vec3); - LLVector3 scale = lljoint.getScale(); - ensure("setScale()/getScale failed ", (vec3 == scale)); - } - - template<> template<> - void lljoint_object::test<10>() - { - LLJoint lljoint("LLJoint"); - LLMatrix4 mat; - mat.setIdentity(); - lljoint.setWorldMatrix(mat);//giving warning setWorldMatrix not correctly implemented; - LLMatrix4 mat4 = lljoint.getWorldMatrix(); - ensure("setWorldMatrix()/getWorldMatrix failed ", (mat4 == mat)); - } - - template<> template<> - void lljoint_object::test<11>() - { - S32 joint_num = 12; - LLJoint lljoint(joint_num); - lljoint.setName("parent"); - S32 jointNum = lljoint.getJointNum(); - ensure("getJointNum failed ", (jointNum == joint_num)); - } - - template<> template<> - void lljoint_object::test<12>() - { - LLJoint lljoint; - LLVector3 vec3(2.3f,30.f,10.f); - lljoint.setSkinOffset(vec3); - LLVector3 offset = lljoint.getSkinOffset(); - ensure("1:setSkinOffset()/getSkinOffset() failed ", (vec3 == offset)); - } - - template<> template<> - void lljoint_object::test<13>() - { - LLJoint lljointgp("gparent"); - LLJoint lljoint("parent"); - LLJoint lljoint1("child1"); - lljoint.addChild(&lljoint1); - LLJoint lljoint2("child2"); - lljoint.addChild(&lljoint2); - LLJoint lljoint3("child3"); - lljoint.addChild(&lljoint3); - - LLJoint* jnt = NULL; - jnt = lljoint2.getParent(); - ensure("addChild() failed ", (&lljoint == jnt)); - LLJoint* jnt1 = lljoint.findJoint("child3"); - ensure("findJoint() failed ", (&lljoint3 == jnt1)); - lljoint.removeChild(&lljoint3); - LLJoint* jnt2 = lljoint.findJoint("child3"); - ensure("removeChild() failed ", (NULL == jnt2)); - - lljointgp.addChild(&lljoint); - ensure("GetParent() failed ", (&lljoint== lljoint2.getParent())); - ensure("getRoot() failed ", (&lljointgp == lljoint2.getRoot())); - - ensure("getRoot() failed ", &lljoint1 == lljoint.findJoint("child1")); - - lljointgp.removeAllChildren(); - // parent removed from grandparent - so should not be able to locate child - ensure("removeAllChildren() failed ", (NULL == lljointgp.findJoint("child1"))); - // it should still exist in parent though - ensure("removeAllChildren() failed ", (&lljoint1 == lljoint.findJoint("child1"))); - } - - template<> template<> - void lljoint_object::test<14>() - { - LLJoint lljointgp("gparent"); - - LLJoint llparent1("parent1"); - LLJoint llparent2("parent2"); - - LLJoint llchild("child1"); - LLJoint lladoptedchild("child2"); - llparent1.addChild(&llchild); - llparent1.addChild(&lladoptedchild); - - llparent2.addChild(&lladoptedchild); - ensure("1. addChild failed to remove prior parent", lladoptedchild.getParent() == &llparent2); - ensure("2. addChild failed to remove prior parent", llparent1.findJoint("child2") == NULL); - } - - - /* - Test cases for the following not added. They perform operations - on underlying LLXformMatrix and LLVector3 elements which have - been unit tested separately. - Unit Testing these functions will basically require re-implementing - logic of these function in the test case itself - - 1) void WorldMatrixChildren(); + struct lljoint_data + { + }; + typedef test_group<lljoint_data> lljoint_test; + typedef lljoint_test::object lljoint_object; + tut::lljoint_test lljoint_testcase("LLJoint"); + + template<> template<> + void lljoint_object::test<1>() + { + LLJoint lljoint; + LLJoint* jnt = lljoint.getParent(); + ensure("getParent() failed ", (NULL == jnt)); + ensure("getRoot() failed ", (&lljoint == lljoint.getRoot())); + } + + template<> template<> + void lljoint_object::test<2>() + { + std::string str = "LLJoint"; + LLJoint parent(str), child; + child.setup(str, &parent); + LLJoint* jnt = child.getParent(); + ensure("setup() failed ", (&parent == jnt)); + } + + template<> template<> + void lljoint_object::test<3>() + { + LLJoint parent, child; + std::string str = "LLJoint"; + child.setup(str, &parent); + LLJoint* jnt = parent.findJoint(str); + ensure("findJoint() failed ", (&child == jnt)); + } + + template<> template<> + void lljoint_object::test<4>() + { + LLJoint parent; + std::string str1 = "LLJoint", str2; + parent.setName(str1); + str2 = parent.getName(); + ensure("setName() failed ", (str1 == str2)); + } + + template<> template<> + void lljoint_object::test<5>() + { + LLJoint lljoint; + LLVector3 vec3(2.3f,30.f,10.f); + // SL-315 + lljoint.setPosition(vec3); + LLVector3 pos = lljoint.getPosition(); + ensure("setPosition()/getPosition() failed ", (vec3 == pos)); + } + + template<> template<> + void lljoint_object::test<6>() + { + LLJoint lljoint; + LLVector3 vec3(2.3f,30.f,10.f); + // SL-315 + lljoint.setWorldPosition(vec3); + LLVector3 pos = lljoint.getWorldPosition(); + ensure("1:setWorldPosition()/getWorldPosition() failed ", (vec3 == pos)); + LLVector3 lastPos = lljoint.getLastWorldPosition(); + ensure("2:getLastWorldPosition failed ", (vec3 == lastPos)); + } + + template<> template<> + void lljoint_object::test<7>() + { + LLJoint lljoint("LLJoint"); + LLQuaternion q(2.3f,30.f,10.f,1.f); + lljoint.setRotation(q); + LLQuaternion rot = lljoint.getRotation(); + ensure("setRotation()/getRotation() failed ", (q == rot)); + } + template<> template<> + void lljoint_object::test<8>() + { + LLJoint lljoint("LLJoint"); + LLQuaternion q(2.3f,30.f,10.f,1.f); + lljoint.setWorldRotation(q); + LLQuaternion rot = lljoint.getWorldRotation(); + ensure("1:setWorldRotation()/getWorldRotation() failed ", (q == rot)); + LLQuaternion lastRot = lljoint.getLastWorldRotation(); + ensure("2:getLastWorldRotation failed ", (q == lastRot)); + } + + template<> template<> + void lljoint_object::test<9>() + { + LLJoint lljoint; + LLVector3 vec3(2.3f,30.f,10.f); + lljoint.setScale(vec3); + LLVector3 scale = lljoint.getScale(); + ensure("setScale()/getScale failed ", (vec3 == scale)); + } + + template<> template<> + void lljoint_object::test<10>() + { + LLJoint lljoint("LLJoint"); + LLMatrix4 mat; + mat.setIdentity(); + lljoint.setWorldMatrix(mat);//giving warning setWorldMatrix not correctly implemented; + LLMatrix4 mat4 = lljoint.getWorldMatrix(); + ensure("setWorldMatrix()/getWorldMatrix failed ", (mat4 == mat)); + } + + template<> template<> + void lljoint_object::test<11>() + { + S32 joint_num = 12; + LLJoint lljoint(joint_num); + lljoint.setName("parent"); + S32 jointNum = lljoint.getJointNum(); + ensure("getJointNum failed ", (jointNum == joint_num)); + } + + template<> template<> + void lljoint_object::test<12>() + { + LLJoint lljoint; + LLVector3 vec3(2.3f,30.f,10.f); + lljoint.setSkinOffset(vec3); + LLVector3 offset = lljoint.getSkinOffset(); + ensure("1:setSkinOffset()/getSkinOffset() failed ", (vec3 == offset)); + } + + template<> template<> + void lljoint_object::test<13>() + { + LLJoint lljointgp("gparent"); + LLJoint lljoint("parent"); + LLJoint lljoint1("child1"); + lljoint.addChild(&lljoint1); + LLJoint lljoint2("child2"); + lljoint.addChild(&lljoint2); + LLJoint lljoint3("child3"); + lljoint.addChild(&lljoint3); + + LLJoint* jnt = NULL; + jnt = lljoint2.getParent(); + ensure("addChild() failed ", (&lljoint == jnt)); + LLJoint* jnt1 = lljoint.findJoint("child3"); + ensure("findJoint() failed ", (&lljoint3 == jnt1)); + lljoint.removeChild(&lljoint3); + LLJoint* jnt2 = lljoint.findJoint("child3"); + ensure("removeChild() failed ", (NULL == jnt2)); + + lljointgp.addChild(&lljoint); + ensure("GetParent() failed ", (&lljoint== lljoint2.getParent())); + ensure("getRoot() failed ", (&lljointgp == lljoint2.getRoot())); + + ensure("getRoot() failed ", &lljoint1 == lljoint.findJoint("child1")); + + lljointgp.removeAllChildren(); + // parent removed from grandparent - so should not be able to locate child + ensure("removeAllChildren() failed ", (NULL == lljointgp.findJoint("child1"))); + // it should still exist in parent though + ensure("removeAllChildren() failed ", (&lljoint1 == lljoint.findJoint("child1"))); + } + + template<> template<> + void lljoint_object::test<14>() + { + LLJoint lljointgp("gparent"); + + LLJoint llparent1("parent1"); + LLJoint llparent2("parent2"); + + LLJoint llchild("child1"); + LLJoint lladoptedchild("child2"); + llparent1.addChild(&llchild); + llparent1.addChild(&lladoptedchild); + + llparent2.addChild(&lladoptedchild); + ensure("1. addChild failed to remove prior parent", lladoptedchild.getParent() == &llparent2); + ensure("2. addChild failed to remove prior parent", llparent1.findJoint("child2") == NULL); + } + + + /* + Test cases for the following not added. They perform operations + on underlying LLXformMatrix and LLVector3 elements which have + been unit tested separately. + Unit Testing these functions will basically require re-implementing + logic of these function in the test case itself + + 1) void WorldMatrixChildren(); 2) void updateWorldMatrixParent(); 3) void updateWorldPRSParent(); 4) void updateWorldMatrix(); @@ -237,6 +237,6 @@ namespace tut 6) void setConstraintSilhouette(LLDynamicArray<LLVector3>& silhouette); 7) void clampRotation(LLQuaternion old_rot, LLQuaternion new_rot); - */ + */ } |