diff options
Diffstat (limited to 'indra/llcharacter')
46 files changed, 2773 insertions, 1970 deletions
diff --git a/indra/llcharacter/CMakeLists.txt b/indra/llcharacter/CMakeLists.txt new file mode 100644 index 0000000000..14841b5d3d --- /dev/null +++ b/indra/llcharacter/CMakeLists.txt @@ -0,0 +1,88 @@ +# -*- cmake -*- + +project(llcharacter) + +include(00-Common) +include(LLCommon) +include(LLMath) +include(LLMessage) +include(LLVFS) +include(LLXML) + +include_directories( + ${LLCOMMON_INCLUDE_DIRS} + ${LLMATH_INCLUDE_DIRS} + ${LLMESSAGE_INCLUDE_DIRS} + ${LLVFS_INCLUDE_DIRS} + ${LLXML_INCLUDE_DIRS} + ) + +set(llcharacter_SOURCE_FILES + llanimationstates.cpp + llbvhloader.cpp + llcharacter.cpp + lleditingmotion.cpp + llgesture.cpp + llhandmotion.cpp + llheadrotmotion.cpp + lljoint.cpp + lljointsolverrp3.cpp + llkeyframefallmotion.cpp + llkeyframemotion.cpp + llkeyframemotionparam.cpp + llkeyframestandmotion.cpp + llkeyframewalkmotion.cpp + llmotioncontroller.cpp + llmotion.cpp + llmultigesture.cpp + llpose.cpp + llstatemachine.cpp + lltargetingmotion.cpp + llvisualparam.cpp + ) + +set(llcharacter_HEADER_FILES + CMakeLists.txt + + llanimationstates.h + llbvhloader.h + llbvhconsts.h + llcharacter.h + lleditingmotion.h + llgesture.h + llhandmotion.h + llheadrotmotion.h + lljoint.h + lljointsolverrp3.h + lljointstate.h + llkeyframefallmotion.h + llkeyframemotion.h + llkeyframemotionparam.h + llkeyframestandmotion.h + llkeyframewalkmotion.h + llmotion.h + llmotioncontroller.h + llmultigesture.h + llpose.h + llstatemachine.h + lltargetingmotion.h + llvisualparam.h + ) + +set_source_files_properties(${llcharacter_HEADER_FILES} + PROPERTIES HEADER_FILE_ONLY TRUE) + +list(APPEND llcharacter_SOURCE_FILES ${llcharacter_HEADER_FILES}) + +add_library (llcharacter ${llcharacter_SOURCE_FILES}) + + +if(LL_TESTS) + # Add tests + include(LLAddBuildTest) + # UNIT TESTS + SET(llcharacter_TEST_SOURCE_FILES + lljoint.cpp + ) + LL_ADD_PROJECT_UNIT_TESTS(llcharacter "${llcharacter_TEST_SOURCE_FILES}") +endif(LL_TESTS) diff --git a/indra/llcharacter/llanimationstates.cpp b/indra/llcharacter/llanimationstates.cpp index 3e5a1e6705..a30113a478 100644 --- a/indra/llcharacter/llanimationstates.cpp +++ b/indra/llcharacter/llanimationstates.cpp @@ -2,30 +2,25 @@ * @file llanimationstates.cpp * @brief Implementation of animation state related functions. * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2007, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlife.com/developers/opensource/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at http://secondlife.com/developers/opensource/flossexception + * 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. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * 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. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * 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,20 +33,160 @@ #include "llanimationstates.h" #include "llstring.h" +const LLUUID ANIM_AGENT_AFRAID = LLUUID("6b61c8e8-4747-0d75-12d7-e49ff207a4ca"); +const LLUUID ANIM_AGENT_AIM_BAZOOKA_R = LLUUID("b5b4a67d-0aee-30d2-72cd-77b333e932ef"); +const LLUUID ANIM_AGENT_AIM_BOW_L = LLUUID("46bb4359-de38-4ed8-6a22-f1f52fe8f506"); +const LLUUID ANIM_AGENT_AIM_HANDGUN_R = LLUUID("3147d815-6338-b932-f011-16b56d9ac18b"); +const LLUUID ANIM_AGENT_AIM_RIFLE_R = LLUUID("ea633413-8006-180a-c3ba-96dd1d756720"); +const LLUUID ANIM_AGENT_ANGRY = LLUUID("5747a48e-073e-c331-f6f3-7c2149613d3e"); +const LLUUID ANIM_AGENT_AWAY = LLUUID("fd037134-85d4-f241-72c6-4f42164fedee"); +const LLUUID ANIM_AGENT_BACKFLIP = LLUUID("c4ca6188-9127-4f31-0158-23c4e2f93304"); +const LLUUID ANIM_AGENT_BELLY_LAUGH = LLUUID("18b3a4b5-b463-bd48-e4b6-71eaac76c515"); +const LLUUID ANIM_AGENT_BLOW_KISS = LLUUID("db84829b-462c-ee83-1e27-9bbee66bd624"); +const LLUUID ANIM_AGENT_BORED = LLUUID("b906c4ba-703b-1940-32a3-0c7f7d791510"); +const LLUUID ANIM_AGENT_BOW = LLUUID("82e99230-c906-1403-4d9c-3889dd98daba"); +const LLUUID ANIM_AGENT_BRUSH = LLUUID("349a3801-54f9-bf2c-3bd0-1ac89772af01"); +const LLUUID ANIM_AGENT_BUSY = LLUUID("efcf670c-2d18-8128-973a-034ebc806b67"); +const LLUUID ANIM_AGENT_CLAP = LLUUID("9b0c1c4e-8ac7-7969-1494-28c874c4f668"); +const LLUUID ANIM_AGENT_COURTBOW = LLUUID("9ba1c942-08be-e43a-fb29-16ad440efc50"); +const LLUUID ANIM_AGENT_CROUCH = LLUUID("201f3fdf-cb1f-dbec-201f-7333e328ae7c"); +const LLUUID ANIM_AGENT_CROUCHWALK = LLUUID("47f5f6fb-22e5-ae44-f871-73aaaf4a6022"); +const LLUUID ANIM_AGENT_CRY = LLUUID("92624d3e-1068-f1aa-a5ec-8244585193ed"); +const LLUUID ANIM_AGENT_CUSTOMIZE = LLUUID("038fcec9-5ebd-8a8e-0e2e-6e71a0a1ac53"); +const LLUUID ANIM_AGENT_CUSTOMIZE_DONE = LLUUID("6883a61a-b27b-5914-a61e-dda118a9ee2c"); +const LLUUID ANIM_AGENT_DANCE1 = LLUUID("b68a3d7c-de9e-fc87-eec8-543d787e5b0d"); +const LLUUID ANIM_AGENT_DANCE2 = LLUUID("928cae18-e31d-76fd-9cc9-2f55160ff818"); +const LLUUID ANIM_AGENT_DANCE3 = LLUUID("30047778-10ea-1af7-6881-4db7a3a5a114"); +const LLUUID ANIM_AGENT_DANCE4 = LLUUID("951469f4-c7b2-c818-9dee-ad7eea8c30b7"); +const LLUUID ANIM_AGENT_DANCE5 = LLUUID("4bd69a1d-1114-a0b4-625f-84e0a5237155"); +const LLUUID ANIM_AGENT_DANCE6 = LLUUID("cd28b69b-9c95-bb78-3f94-8d605ff1bb12"); +const LLUUID ANIM_AGENT_DANCE7 = LLUUID("a54d8ee2-28bb-80a9-7f0c-7afbbe24a5d6"); +const LLUUID ANIM_AGENT_DANCE8 = LLUUID("b0dc417c-1f11-af36-2e80-7e7489fa7cdc"); +const LLUUID ANIM_AGENT_DEAD = LLUUID("57abaae6-1d17-7b1b-5f98-6d11a6411276"); +const LLUUID ANIM_AGENT_DRINK = LLUUID("0f86e355-dd31-a61c-fdb0-3a96b9aad05f"); +const LLUUID ANIM_AGENT_EMBARRASSED = LLUUID("514af488-9051-044a-b3fc-d4dbf76377c6"); +const LLUUID ANIM_AGENT_EXPRESS_AFRAID = LLUUID("aa2df84d-cf8f-7218-527b-424a52de766e"); +const LLUUID ANIM_AGENT_EXPRESS_ANGER = LLUUID("1a03b575-9634-b62a-5767-3a679e81f4de"); +const LLUUID ANIM_AGENT_EXPRESS_BORED = LLUUID("214aa6c1-ba6a-4578-f27c-ce7688f61d0d"); +const LLUUID ANIM_AGENT_EXPRESS_CRY = LLUUID("d535471b-85bf-3b4d-a542-93bea4f59d33"); +const LLUUID ANIM_AGENT_EXPRESS_DISDAIN = LLUUID("d4416ff1-09d3-300f-4183-1b68a19b9fc1"); +const LLUUID ANIM_AGENT_EXPRESS_EMBARRASSED = LLUUID("0b8c8211-d78c-33e8-fa28-c51a9594e424"); +const LLUUID ANIM_AGENT_EXPRESS_FROWN = LLUUID("fee3df48-fa3d-1015-1e26-a205810e3001"); +const LLUUID ANIM_AGENT_EXPRESS_KISS = LLUUID("1e8d90cc-a84e-e135-884c-7c82c8b03a14"); +const LLUUID ANIM_AGENT_EXPRESS_LAUGH = LLUUID("62570842-0950-96f8-341c-809e65110823"); +const LLUUID ANIM_AGENT_EXPRESS_OPEN_MOUTH = LLUUID("d63bc1f9-fc81-9625-a0c6-007176d82eb7"); +const LLUUID ANIM_AGENT_EXPRESS_REPULSED = LLUUID("f76cda94-41d4-a229-2872-e0296e58afe1"); +const LLUUID ANIM_AGENT_EXPRESS_SAD = LLUUID("eb6ebfb2-a4b3-a19c-d388-4dd5c03823f7"); +const LLUUID ANIM_AGENT_EXPRESS_SHRUG = LLUUID("a351b1bc-cc94-aac2-7bea-a7e6ebad15ef"); +const LLUUID ANIM_AGENT_EXPRESS_SMILE = LLUUID("b7c7c833-e3d3-c4e3-9fc0-131237446312"); +const LLUUID ANIM_AGENT_EXPRESS_SURPRISE = LLUUID("728646d9-cc79-08b2-32d6-937f0a835c24"); +const LLUUID ANIM_AGENT_EXPRESS_TONGUE_OUT = LLUUID("835965c6-7f2f-bda2-5deb-2478737f91bf"); +const LLUUID ANIM_AGENT_EXPRESS_TOOTHSMILE = LLUUID("b92ec1a5-e7ce-a76b-2b05-bcdb9311417e"); +const LLUUID ANIM_AGENT_EXPRESS_WINK = LLUUID("da020525-4d94-59d6-23d7-81fdebf33148"); +const LLUUID ANIM_AGENT_EXPRESS_WORRY = LLUUID("9c05e5c7-6f07-6ca4-ed5a-b230390c3950"); +const LLUUID ANIM_AGENT_FALLDOWN = LLUUID("666307d9-a860-572d-6fd4-c3ab8865c094"); +const LLUUID ANIM_AGENT_FEMALE_RUN_NEW = LLUUID("85995026-eade-5d78-d364-94a64512cb66"); +const LLUUID ANIM_AGENT_FEMALE_WALK = LLUUID("f5fc7433-043d-e819-8298-f519a119b688"); +const LLUUID ANIM_AGENT_FEMALE_WALK_NEW = LLUUID("d60c41d2-7c24-7074-d3fa-6101cea22a51"); +const LLUUID ANIM_AGENT_FINGER_WAG = LLUUID("c1bc7f36-3ba0-d844-f93c-93be945d644f"); +const LLUUID ANIM_AGENT_FIST_PUMP = LLUUID("7db00ccd-f380-f3ee-439d-61968ec69c8a"); +const LLUUID ANIM_AGENT_FLY = LLUUID("aec4610c-757f-bc4e-c092-c6e9caf18daf"); +const LLUUID ANIM_AGENT_FLYSLOW = LLUUID("2b5a38b2-5e00-3a97-a495-4c826bc443e6"); +const LLUUID ANIM_AGENT_HELLO = LLUUID("9b29cd61-c45b-5689-ded2-91756b8d76a9"); +const LLUUID ANIM_AGENT_HOLD_BAZOOKA_R = LLUUID("ef62d355-c815-4816-2474-b1acc21094a6"); +const LLUUID ANIM_AGENT_HOLD_BOW_L = LLUUID("8b102617-bcba-037b-86c1-b76219f90c88"); +const LLUUID ANIM_AGENT_HOLD_HANDGUN_R = LLUUID("efdc1727-8b8a-c800-4077-975fc27ee2f2"); +const LLUUID ANIM_AGENT_HOLD_RIFLE_R = LLUUID("3d94bad0-c55b-7dcc-8763-033c59405d33"); +const LLUUID ANIM_AGENT_HOLD_THROW_R = LLUUID("7570c7b5-1f22-56dd-56ef-a9168241bbb6"); +const LLUUID ANIM_AGENT_HOVER = LLUUID("4ae8016b-31b9-03bb-c401-b1ea941db41d"); +const LLUUID ANIM_AGENT_HOVER_DOWN = LLUUID("20f063ea-8306-2562-0b07-5c853b37b31e"); +const LLUUID ANIM_AGENT_HOVER_UP = LLUUID("62c5de58-cb33-5743-3d07-9e4cd4352864"); +const LLUUID ANIM_AGENT_IMPATIENT = LLUUID("5ea3991f-c293-392e-6860-91dfa01278a3"); +const LLUUID ANIM_AGENT_JUMP = LLUUID("2305bd75-1ca9-b03b-1faa-b176b8a8c49e"); +const LLUUID ANIM_AGENT_JUMP_FOR_JOY = LLUUID("709ea28e-1573-c023-8bf8-520c8bc637fa"); +const LLUUID ANIM_AGENT_KISS_MY_BUTT = LLUUID("19999406-3a3a-d58c-a2ac-d72e555dcf51"); +const LLUUID ANIM_AGENT_LAND = LLUUID("7a17b059-12b2-41b1-570a-186368b6aa6f"); +const LLUUID ANIM_AGENT_LAUGH_SHORT = LLUUID("ca5b3f14-3194-7a2b-c894-aa699b718d1f"); +const LLUUID ANIM_AGENT_MEDIUM_LAND = LLUUID("f4f00d6e-b9fe-9292-f4cb-0ae06ea58d57"); +const LLUUID ANIM_AGENT_MOTORCYCLE_SIT = LLUUID("08464f78-3a8e-2944-cba5-0c94aff3af29"); +const LLUUID ANIM_AGENT_MUSCLE_BEACH = LLUUID("315c3a41-a5f3-0ba4-27da-f893f769e69b"); +const LLUUID ANIM_AGENT_NO = LLUUID("5a977ed9-7f72-44e9-4c4c-6e913df8ae74"); +const LLUUID ANIM_AGENT_NO_UNHAPPY = LLUUID("d83fa0e5-97ed-7eb2-e798-7bd006215cb4"); +const LLUUID ANIM_AGENT_NYAH_NYAH = LLUUID("f061723d-0a18-754f-66ee-29a44795a32f"); +const LLUUID ANIM_AGENT_ONETWO_PUNCH = LLUUID("eefc79be-daae-a239-8c04-890f5d23654a"); +const LLUUID ANIM_AGENT_PEACE = LLUUID("b312b10e-65ab-a0a4-8b3c-1326ea8e3ed9"); +const LLUUID ANIM_AGENT_POINT_ME = LLUUID("17c024cc-eef2-f6a0-3527-9869876d7752"); +const LLUUID ANIM_AGENT_POINT_YOU = LLUUID("ec952cca-61ef-aa3b-2789-4d1344f016de"); +const LLUUID ANIM_AGENT_PRE_JUMP = LLUUID("7a4e87fe-de39-6fcb-6223-024b00893244"); +const LLUUID ANIM_AGENT_PUNCH_LEFT = LLUUID("f3300ad9-3462-1d07-2044-0fef80062da0"); +const LLUUID ANIM_AGENT_PUNCH_RIGHT = LLUUID("c8e42d32-7310-6906-c903-cab5d4a34656"); +const LLUUID ANIM_AGENT_REPULSED = LLUUID("36f81a92-f076-5893-dc4b-7c3795e487cf"); +const LLUUID ANIM_AGENT_ROUNDHOUSE_KICK = LLUUID("49aea43b-5ac3-8a44-b595-96100af0beda"); +const LLUUID ANIM_AGENT_RPS_COUNTDOWN = LLUUID("35db4f7e-28c2-6679-cea9-3ee108f7fc7f"); +const LLUUID ANIM_AGENT_RPS_PAPER = LLUUID("0836b67f-7f7b-f37b-c00a-460dc1521f5a"); +const LLUUID ANIM_AGENT_RPS_ROCK = LLUUID("42dd95d5-0bc6-6392-f650-777304946c0f"); +const LLUUID ANIM_AGENT_RPS_SCISSORS = LLUUID("16803a9f-5140-e042-4d7b-d28ba247c325"); +const LLUUID ANIM_AGENT_RUN = LLUUID("05ddbff8-aaa9-92a1-2b74-8fe77a29b445"); +const LLUUID ANIM_AGENT_RUN_NEW = LLUUID("1ab1b236-cd08-21e6-0cbc-0d923fc6eca2"); +const LLUUID ANIM_AGENT_SAD = LLUUID("0eb702e2-cc5a-9a88-56a5-661a55c0676a"); +const LLUUID ANIM_AGENT_SALUTE = LLUUID("cd7668a6-7011-d7e2-ead8-fc69eff1a104"); +const LLUUID ANIM_AGENT_SHOOT_BOW_L = LLUUID("e04d450d-fdb5-0432-fd68-818aaf5935f8"); +const LLUUID ANIM_AGENT_SHOUT = LLUUID("6bd01860-4ebd-127a-bb3d-d1427e8e0c42"); +const LLUUID ANIM_AGENT_SHRUG = LLUUID("70ea714f-3a97-d742-1b01-590a8fcd1db5"); +const LLUUID ANIM_AGENT_SIT = LLUUID("1a5fe8ac-a804-8a5d-7cbd-56bd83184568"); +const LLUUID ANIM_AGENT_SIT_FEMALE = LLUUID("b1709c8d-ecd3-54a1-4f28-d55ac0840782"); +const LLUUID ANIM_AGENT_SIT_GENERIC = LLUUID("245f3c54-f1c0-bf2e-811f-46d8eeb386e7"); +const LLUUID ANIM_AGENT_SIT_GROUND = LLUUID("1c7600d6-661f-b87b-efe2-d7421eb93c86"); +const LLUUID ANIM_AGENT_SIT_GROUND_CONSTRAINED = LLUUID("1a2bd58e-87ff-0df8-0b4c-53e047b0bb6e"); +const LLUUID ANIM_AGENT_SIT_TO_STAND = LLUUID("a8dee56f-2eae-9e7a-05a2-6fb92b97e21e"); +const LLUUID ANIM_AGENT_SLEEP = LLUUID("f2bed5f9-9d44-39af-b0cd-257b2a17fe40"); +const LLUUID ANIM_AGENT_SMOKE_IDLE = LLUUID("d2f2ee58-8ad1-06c9-d8d3-3827ba31567a"); +const LLUUID ANIM_AGENT_SMOKE_INHALE = LLUUID("6802d553-49da-0778-9f85-1599a2266526"); +const LLUUID ANIM_AGENT_SMOKE_THROW_DOWN = LLUUID("0a9fb970-8b44-9114-d3a9-bf69cfe804d6"); +const LLUUID ANIM_AGENT_SNAPSHOT = LLUUID("eae8905b-271a-99e2-4c0e-31106afd100c"); +const LLUUID ANIM_AGENT_STAND = LLUUID("2408fe9e-df1d-1d7d-f4ff-1384fa7b350f"); +const LLUUID ANIM_AGENT_STANDUP = LLUUID("3da1d753-028a-5446-24f3-9c9b856d9422"); +const LLUUID ANIM_AGENT_STAND_1 = LLUUID("15468e00-3400-bb66-cecc-646d7c14458e"); +const LLUUID ANIM_AGENT_STAND_2 = LLUUID("370f3a20-6ca6-9971-848c-9a01bc42ae3c"); +const LLUUID ANIM_AGENT_STAND_3 = LLUUID("42b46214-4b44-79ae-deb8-0df61424ff4b"); +const LLUUID ANIM_AGENT_STAND_4 = LLUUID("f22fed8b-a5ed-2c93-64d5-bdd8b93c889f"); +const LLUUID ANIM_AGENT_STRETCH = LLUUID("80700431-74ec-a008-14f8-77575e73693f"); +const LLUUID ANIM_AGENT_STRIDE = LLUUID("1cb562b0-ba21-2202-efb3-30f82cdf9595"); +const LLUUID ANIM_AGENT_SURF = LLUUID("41426836-7437-7e89-025d-0aa4d10f1d69"); +const LLUUID ANIM_AGENT_SURPRISE = LLUUID("313b9881-4302-73c0-c7d0-0e7a36b6c224"); +const LLUUID ANIM_AGENT_SWORD_STRIKE = LLUUID("85428680-6bf9-3e64-b489-6f81087c24bd"); +const LLUUID ANIM_AGENT_TALK = LLUUID("5c682a95-6da4-a463-0bf6-0f5b7be129d1"); +const LLUUID ANIM_AGENT_TANTRUM = LLUUID("11000694-3f41-adc2-606b-eee1d66f3724"); +const LLUUID ANIM_AGENT_THROW_R = LLUUID("aa134404-7dac-7aca-2cba-435f9db875ca"); +const LLUUID ANIM_AGENT_TRYON_SHIRT = LLUUID("83ff59fe-2346-f236-9009-4e3608af64c1"); +const LLUUID ANIM_AGENT_TURNLEFT = LLUUID("56e0ba0d-4a9f-7f27-6117-32f2ebbf6135"); +const LLUUID ANIM_AGENT_TURNRIGHT = LLUUID("2d6daa51-3192-6794-8e2e-a15f8338ec30"); +const LLUUID ANIM_AGENT_TYPE = LLUUID("c541c47f-e0c0-058b-ad1a-d6ae3a4584d9"); +const LLUUID ANIM_AGENT_WALK = LLUUID("6ed24bd8-91aa-4b12-ccc7-c97c857ab4e0"); +const LLUUID ANIM_AGENT_WALK_NEW = LLUUID("33339176-7ddc-9397-94a4-bf3403cbc8f5"); +const LLUUID ANIM_AGENT_WHISPER = LLUUID("7693f268-06c7-ea71-fa21-2b30d6533f8f"); +const LLUUID ANIM_AGENT_WHISTLE = LLUUID("b1ed7982-c68e-a982-7561-52a88a5298c0"); +const LLUUID ANIM_AGENT_WINK = LLUUID("869ecdad-a44b-671e-3266-56aef2e3ac2e"); +const LLUUID ANIM_AGENT_WINK_HOLLYWOOD = LLUUID("c0c4030f-c02b-49de-24ba-2331f43fe41c"); +const LLUUID ANIM_AGENT_WORRY = LLUUID("9f496bd2-589a-709f-16cc-69bf7df1d36c"); +const LLUUID ANIM_AGENT_YES = LLUUID("15dd911d-be82-2856-26db-27659b142875"); +const LLUUID ANIM_AGENT_YES_HAPPY = LLUUID("b8c8b2a3-9008-1771-3bfc-90924955ab2d"); +const LLUUID ANIM_AGENT_YOGA_FLOAT = LLUUID("42ecd00b-9947-a97c-400a-bbc9174c7aeb"); + LLUUID AGENT_WALK_ANIMS[] = {ANIM_AGENT_WALK, ANIM_AGENT_RUN, ANIM_AGENT_CROUCHWALK, ANIM_AGENT_TURNLEFT, ANIM_AGENT_TURNRIGHT}; -S32 NUM_AGENT_WALK_ANIMS = sizeof(AGENT_WALK_ANIMS) / sizeof(LLUUID); +S32 NUM_AGENT_WALK_ANIMS = LL_ARRAY_SIZE(AGENT_WALK_ANIMS); LLUUID AGENT_GUN_HOLD_ANIMS[] = {ANIM_AGENT_HOLD_RIFLE_R, ANIM_AGENT_HOLD_HANDGUN_R, ANIM_AGENT_HOLD_BAZOOKA_R, ANIM_AGENT_HOLD_BOW_L}; -S32 NUM_AGENT_GUN_HOLD_ANIMS = sizeof(AGENT_GUN_HOLD_ANIMS) / sizeof(LLUUID); +S32 NUM_AGENT_GUN_HOLD_ANIMS = LL_ARRAY_SIZE(AGENT_GUN_HOLD_ANIMS); LLUUID AGENT_GUN_AIM_ANIMS[] = {ANIM_AGENT_AIM_RIFLE_R, ANIM_AGENT_AIM_HANDGUN_R, ANIM_AGENT_AIM_BAZOOKA_R, ANIM_AGENT_AIM_BOW_L}; -S32 NUM_AGENT_GUN_AIM_ANIMS = sizeof(AGENT_GUN_AIM_ANIMS) / sizeof(LLUUID); +S32 NUM_AGENT_GUN_AIM_ANIMS = LL_ARRAY_SIZE(AGENT_GUN_AIM_ANIMS); LLUUID AGENT_NO_ROTATE_ANIMS[] = {ANIM_AGENT_SIT_GROUND, ANIM_AGENT_SIT_GROUND_CONSTRAINED, ANIM_AGENT_STANDUP}; -S32 NUM_AGENT_NO_ROTATE_ANIMS = sizeof(AGENT_NO_ROTATE_ANIMS) / sizeof(LLUUID); +S32 NUM_AGENT_NO_ROTATE_ANIMS = LL_ARRAY_SIZE(AGENT_NO_ROTATE_ANIMS); LLUUID AGENT_STAND_ANIMS[] = {ANIM_AGENT_STAND, ANIM_AGENT_STAND_1, ANIM_AGENT_STAND_2, ANIM_AGENT_STAND_3, ANIM_AGENT_STAND_4}; -S32 NUM_AGENT_STAND_ANIMS = sizeof(AGENT_STAND_ANIMS) / sizeof(LLUUID); +S32 NUM_AGENT_STAND_ANIMS = LL_ARRAY_SIZE(AGENT_STAND_ANIMS); LLAnimationLibrary gAnimLibrary; @@ -115,7 +250,9 @@ LLAnimationLibrary::LLAnimationLibrary() : 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"); @@ -155,6 +292,7 @@ LLAnimationLibrary::LLAnimationLibrary() : 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"); @@ -190,6 +328,7 @@ LLAnimationLibrary::LLAnimationLibrary() : 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"); @@ -228,10 +367,10 @@ const char *LLAnimationLibrary::animStateToString( const LLUUID& state ) //----------------------------------------------------------------------------- // Return the animation state for a given name //----------------------------------------------------------------------------- -LLUUID LLAnimationLibrary::stringToAnimState( const char *name, BOOL allow_ids ) +LLUUID LLAnimationLibrary::stringToAnimState( const std::string& name, BOOL allow_ids ) { - LLString lower_case_name(name); - LLString::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()); @@ -259,81 +398,98 @@ LLUUID LLAnimationLibrary::stringToAnimState( const char *name, BOOL allow_ids ) return id; } +//----------------------------------------------------------------------------- +// Associate an anim state with a name +//----------------------------------------------------------------------------- +void LLAnimationLibrary::animStateSetString( const LLUUID& state, const std::string& 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("]"); +} + // 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("Afraid", "express_afraid", ANIM_AGENT_AFRAID), - LLAnimStateEntry("Angry", "express_anger", ANIM_AGENT_ANGRY), - LLAnimStateEntry("Away", "away", ANIM_AGENT_AWAY), - LLAnimStateEntry("Backflip", "backflip", ANIM_AGENT_BACKFLIP), - LLAnimStateEntry("Belly Laugh", "express_laugh", ANIM_AGENT_BELLY_LAUGH), - LLAnimStateEntry("BigSmile", "express_toothsmile", ANIM_AGENT_EXPRESS_TOOTHSMILE), - LLAnimStateEntry("Blow Kiss", "blowkiss", ANIM_AGENT_BLOW_KISS), - LLAnimStateEntry("Bored", "express_bored", ANIM_AGENT_BORED), - LLAnimStateEntry("Bow", "bow", ANIM_AGENT_BOW), - LLAnimStateEntry("Clap", "clap", ANIM_AGENT_CLAP), - LLAnimStateEntry("Court Bow", "courtbow", ANIM_AGENT_COURTBOW), - LLAnimStateEntry("Cry", "express_cry", ANIM_AGENT_CRY), - LLAnimStateEntry("Dance 1", "dance1", ANIM_AGENT_DANCE1), - LLAnimStateEntry("Dance 2", "dance2", ANIM_AGENT_DANCE2), - LLAnimStateEntry("Dance 3", "dance3", ANIM_AGENT_DANCE3), - LLAnimStateEntry("Dance 4", "dance4", ANIM_AGENT_DANCE4), - LLAnimStateEntry("Dance 5", "dance5", ANIM_AGENT_DANCE5), - LLAnimStateEntry("Dance 6", "dance6", ANIM_AGENT_DANCE6), - LLAnimStateEntry("Dance 7", "dance7", ANIM_AGENT_DANCE7), - LLAnimStateEntry("Dance 8", "dance8", ANIM_AGENT_DANCE8), - LLAnimStateEntry("Disdain", "express_disdain", ANIM_AGENT_EXPRESS_DISDAIN), - LLAnimStateEntry("Drink", "drink", ANIM_AGENT_DRINK), - LLAnimStateEntry("Embarrassed", "express_embarrased", ANIM_AGENT_EMBARRASSED), - LLAnimStateEntry("Finger Wag", "angry_fingerwag", ANIM_AGENT_FINGER_WAG), - LLAnimStateEntry("Fist Pump", "fist_pump", ANIM_AGENT_FIST_PUMP), - LLAnimStateEntry("Floating Yoga", "yoga_float", ANIM_AGENT_YOGA_FLOAT), - LLAnimStateEntry("Frown", "express_frown", ANIM_AGENT_EXPRESS_FROWN), - LLAnimStateEntry("Impatient", "impatient", ANIM_AGENT_IMPATIENT), - LLAnimStateEntry("Jump For Joy", "jumpforjoy", ANIM_AGENT_JUMP_FOR_JOY), - LLAnimStateEntry("Kiss My Butt", "kissmybutt", ANIM_AGENT_KISS_MY_BUTT), - LLAnimStateEntry("Kiss", "express_kiss", ANIM_AGENT_EXPRESS_KISS), - LLAnimStateEntry("Laugh", "laugh_short", ANIM_AGENT_LAUGH_SHORT), - LLAnimStateEntry("Muscle Beach", "musclebeach", ANIM_AGENT_MUSCLE_BEACH), - LLAnimStateEntry("No (Unhappy)", "no_unhappy", ANIM_AGENT_NO_UNHAPPY), - LLAnimStateEntry("No", "no_head", ANIM_AGENT_NO), - LLAnimStateEntry("Nya-nya-nya", "nyanya", ANIM_AGENT_NYAH_NYAH), - LLAnimStateEntry("One-Two Punch", "punch_onetwo", ANIM_AGENT_ONETWO_PUNCH), - LLAnimStateEntry("Open Mouth", "express_open_mouth", ANIM_AGENT_EXPRESS_OPEN_MOUTH), - LLAnimStateEntry("Peace", "peace", ANIM_AGENT_PEACE), - LLAnimStateEntry("Point at Other", "point_you", ANIM_AGENT_POINT_YOU), - LLAnimStateEntry("Point at Self", "point_me", ANIM_AGENT_POINT_ME), - LLAnimStateEntry("Punch Left", "punch_l", ANIM_AGENT_PUNCH_LEFT), - LLAnimStateEntry("Punch Right", "punch_r", ANIM_AGENT_PUNCH_RIGHT), - LLAnimStateEntry("RPS count", "rps_countdown", ANIM_AGENT_RPS_COUNTDOWN), - LLAnimStateEntry("RPS paper", "rps_paper", ANIM_AGENT_RPS_PAPER), - LLAnimStateEntry("RPS rock", "rps_rock", ANIM_AGENT_RPS_ROCK), - LLAnimStateEntry("RPS scissors", "rps_scissors", ANIM_AGENT_RPS_SCISSORS), - LLAnimStateEntry("Repulsed", "express_repulsed", ANIM_AGENT_EXPRESS_REPULSED), - LLAnimStateEntry("Roundhouse Kick", "kick_roundhouse_r", ANIM_AGENT_ROUNDHOUSE_KICK), - LLAnimStateEntry("Sad", "express_sad", ANIM_AGENT_SAD), - LLAnimStateEntry("Salute", "salute", ANIM_AGENT_SALUTE), - LLAnimStateEntry("Shout", "shout", ANIM_AGENT_SHOUT), - LLAnimStateEntry("Shrug", "express_shrug", ANIM_AGENT_SHRUG), - LLAnimStateEntry("Smile", "express_smile", ANIM_AGENT_EXPRESS_SMILE), - LLAnimStateEntry("Smoke Idle", "smoke_idle", ANIM_AGENT_SMOKE_IDLE), - LLAnimStateEntry("Smoke Inhale", "smoke_inhale", ANIM_AGENT_SMOKE_INHALE), - LLAnimStateEntry("Smoke Throw Down","smoke_throw_down", ANIM_AGENT_SMOKE_THROW_DOWN), - LLAnimStateEntry("Surprise", "express_surprise", ANIM_AGENT_SURPRISE), - LLAnimStateEntry("Sword Strike", "sword_strike_r", ANIM_AGENT_SWORD_STRIKE), - LLAnimStateEntry("Tantrum", "angry_tantrum", ANIM_AGENT_TANTRUM), - LLAnimStateEntry("TongueOut", "express_tongue_out", ANIM_AGENT_EXPRESS_TONGUE_OUT), - LLAnimStateEntry("Wave", "hello", ANIM_AGENT_HELLO), - LLAnimStateEntry("Whisper", "whisper", ANIM_AGENT_WHISPER), - LLAnimStateEntry("Whistle", "whistle", ANIM_AGENT_WHISTLE), - LLAnimStateEntry("Wink", "express_wink", ANIM_AGENT_WINK), - LLAnimStateEntry("Wink (Hollywood)","wink_hollywood", ANIM_AGENT_WINK_HOLLYWOOD), - LLAnimStateEntry("Worry", "express_worry", ANIM_AGENT_EXPRESS_WORRY), - LLAnimStateEntry("Yes (Happy)", "yes_happy", ANIM_AGENT_YES_HAPPY), - LLAnimStateEntry("Yes", "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 = sizeof(gUserAnimStates) / sizeof(gUserAnimStates[0]); - +const S32 gUserAnimStatesCount = LL_ARRAY_SIZE(gUserAnimStates); // End diff --git a/indra/llcharacter/llanimationstates.h b/indra/llcharacter/llanimationstates.h index cceb952926..aa6579ac8e 100644 --- a/indra/llcharacter/llanimationstates.h +++ b/indra/llcharacter/llanimationstates.h @@ -2,30 +2,25 @@ * @file llanimationstates.h * @brief Implementation of animation state support. * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2007, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlife.com/developers/opensource/gplv2 + * 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. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at http://secondlife.com/developers/opensource/flossexception + * 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. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * 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 * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -48,142 +43,145 @@ //----------------------------------------------------------------------------- const S32 MAX_CONCURRENT_ANIMS = 16; - -const LLUUID ANIM_AGENT_AFRAID = LLUUID("6b61c8e8-4747-0d75-12d7-e49ff207a4ca"); -const LLUUID ANIM_AGENT_AIM_BAZOOKA_R = LLUUID("b5b4a67d-0aee-30d2-72cd-77b333e932ef"); -const LLUUID ANIM_AGENT_AIM_BOW_L = LLUUID("46bb4359-de38-4ed8-6a22-f1f52fe8f506"); -const LLUUID ANIM_AGENT_AIM_HANDGUN_R = LLUUID("3147d815-6338-b932-f011-16b56d9ac18b"); -const LLUUID ANIM_AGENT_AIM_RIFLE_R = LLUUID("ea633413-8006-180a-c3ba-96dd1d756720"); -const LLUUID ANIM_AGENT_ANGRY = LLUUID("5747a48e-073e-c331-f6f3-7c2149613d3e"); -const LLUUID ANIM_AGENT_AWAY = LLUUID("fd037134-85d4-f241-72c6-4f42164fedee"); -const LLUUID ANIM_AGENT_BACKFLIP = LLUUID("c4ca6188-9127-4f31-0158-23c4e2f93304"); -const LLUUID ANIM_AGENT_BELLY_LAUGH = LLUUID("18b3a4b5-b463-bd48-e4b6-71eaac76c515"); -const LLUUID ANIM_AGENT_BLOW_KISS = LLUUID("db84829b-462c-ee83-1e27-9bbee66bd624"); -const LLUUID ANIM_AGENT_BORED = LLUUID("b906c4ba-703b-1940-32a3-0c7f7d791510"); -const LLUUID ANIM_AGENT_BOW = LLUUID("82e99230-c906-1403-4d9c-3889dd98daba"); -const LLUUID ANIM_AGENT_BRUSH = LLUUID("349a3801-54f9-bf2c-3bd0-1ac89772af01"); -const LLUUID ANIM_AGENT_BUSY = LLUUID("efcf670c-2d18-8128-973a-034ebc806b67"); -const LLUUID ANIM_AGENT_CLAP = LLUUID("9b0c1c4e-8ac7-7969-1494-28c874c4f668"); -const LLUUID ANIM_AGENT_COURTBOW = LLUUID("9ba1c942-08be-e43a-fb29-16ad440efc50"); -const LLUUID ANIM_AGENT_CROUCH = LLUUID("201f3fdf-cb1f-dbec-201f-7333e328ae7c"); -const LLUUID ANIM_AGENT_CROUCHWALK = LLUUID("47f5f6fb-22e5-ae44-f871-73aaaf4a6022"); -const LLUUID ANIM_AGENT_CRY = LLUUID("92624d3e-1068-f1aa-a5ec-8244585193ed"); -const LLUUID ANIM_AGENT_CUSTOMIZE = LLUUID("038fcec9-5ebd-8a8e-0e2e-6e71a0a1ac53"); -const LLUUID ANIM_AGENT_CUSTOMIZE_DONE = LLUUID("6883a61a-b27b-5914-a61e-dda118a9ee2c"); -const LLUUID ANIM_AGENT_DANCE1 = LLUUID("b68a3d7c-de9e-fc87-eec8-543d787e5b0d"); -const LLUUID ANIM_AGENT_DANCE2 = LLUUID("928cae18-e31d-76fd-9cc9-2f55160ff818"); -const LLUUID ANIM_AGENT_DANCE3 = LLUUID("30047778-10ea-1af7-6881-4db7a3a5a114"); -const LLUUID ANIM_AGENT_DANCE4 = LLUUID("951469f4-c7b2-c818-9dee-ad7eea8c30b7"); -const LLUUID ANIM_AGENT_DANCE5 = LLUUID("4bd69a1d-1114-a0b4-625f-84e0a5237155"); -const LLUUID ANIM_AGENT_DANCE6 = LLUUID("cd28b69b-9c95-bb78-3f94-8d605ff1bb12"); -const LLUUID ANIM_AGENT_DANCE7 = LLUUID("a54d8ee2-28bb-80a9-7f0c-7afbbe24a5d6"); -const LLUUID ANIM_AGENT_DANCE8 = LLUUID("b0dc417c-1f11-af36-2e80-7e7489fa7cdc"); -const LLUUID ANIM_AGENT_DEAD = LLUUID("57abaae6-1d17-7b1b-5f98-6d11a6411276"); -const LLUUID ANIM_AGENT_DRINK = LLUUID("0f86e355-dd31-a61c-fdb0-3a96b9aad05f"); -const LLUUID ANIM_AGENT_EMBARRASSED = LLUUID("514af488-9051-044a-b3fc-d4dbf76377c6"); -const LLUUID ANIM_AGENT_EXPRESS_AFRAID = LLUUID("aa2df84d-cf8f-7218-527b-424a52de766e"); -const LLUUID ANIM_AGENT_EXPRESS_ANGER = LLUUID("1a03b575-9634-b62a-5767-3a679e81f4de"); -const LLUUID ANIM_AGENT_EXPRESS_BORED = LLUUID("214aa6c1-ba6a-4578-f27c-ce7688f61d0d"); -const LLUUID ANIM_AGENT_EXPRESS_CRY = LLUUID("d535471b-85bf-3b4d-a542-93bea4f59d33"); -const LLUUID ANIM_AGENT_EXPRESS_DISDAIN = LLUUID("d4416ff1-09d3-300f-4183-1b68a19b9fc1"); -const LLUUID ANIM_AGENT_EXPRESS_EMBARRASSED = LLUUID("0b8c8211-d78c-33e8-fa28-c51a9594e424"); -const LLUUID ANIM_AGENT_EXPRESS_FROWN = LLUUID("fee3df48-fa3d-1015-1e26-a205810e3001"); -const LLUUID ANIM_AGENT_EXPRESS_KISS = LLUUID("1e8d90cc-a84e-e135-884c-7c82c8b03a14"); -const LLUUID ANIM_AGENT_EXPRESS_LAUGH = LLUUID("62570842-0950-96f8-341c-809e65110823"); -const LLUUID ANIM_AGENT_EXPRESS_OPEN_MOUTH = LLUUID("d63bc1f9-fc81-9625-a0c6-007176d82eb7"); -const LLUUID ANIM_AGENT_EXPRESS_REPULSED = LLUUID("f76cda94-41d4-a229-2872-e0296e58afe1"); -const LLUUID ANIM_AGENT_EXPRESS_SAD = LLUUID("eb6ebfb2-a4b3-a19c-d388-4dd5c03823f7"); -const LLUUID ANIM_AGENT_EXPRESS_SHRUG = LLUUID("a351b1bc-cc94-aac2-7bea-a7e6ebad15ef"); -const LLUUID ANIM_AGENT_EXPRESS_SMILE = LLUUID("b7c7c833-e3d3-c4e3-9fc0-131237446312"); -const LLUUID ANIM_AGENT_EXPRESS_SURPRISE = LLUUID("728646d9-cc79-08b2-32d6-937f0a835c24"); -const LLUUID ANIM_AGENT_EXPRESS_TONGUE_OUT = LLUUID("835965c6-7f2f-bda2-5deb-2478737f91bf"); -const LLUUID ANIM_AGENT_EXPRESS_TOOTHSMILE = LLUUID("b92ec1a5-e7ce-a76b-2b05-bcdb9311417e"); -const LLUUID ANIM_AGENT_EXPRESS_WINK = LLUUID("da020525-4d94-59d6-23d7-81fdebf33148"); -const LLUUID ANIM_AGENT_EXPRESS_WORRY = LLUUID("9c05e5c7-6f07-6ca4-ed5a-b230390c3950"); -const LLUUID ANIM_AGENT_FALLDOWN = LLUUID("666307d9-a860-572d-6fd4-c3ab8865c094"); -const LLUUID ANIM_AGENT_FEMALE_WALK = LLUUID("f5fc7433-043d-e819-8298-f519a119b688"); -const LLUUID ANIM_AGENT_FINGER_WAG = LLUUID("c1bc7f36-3ba0-d844-f93c-93be945d644f"); -const LLUUID ANIM_AGENT_FIST_PUMP = LLUUID("7db00ccd-f380-f3ee-439d-61968ec69c8a"); -const LLUUID ANIM_AGENT_FLY = LLUUID("aec4610c-757f-bc4e-c092-c6e9caf18daf"); -const LLUUID ANIM_AGENT_FLYSLOW = LLUUID("2b5a38b2-5e00-3a97-a495-4c826bc443e6"); -const LLUUID ANIM_AGENT_HELLO = LLUUID("9b29cd61-c45b-5689-ded2-91756b8d76a9"); -const LLUUID ANIM_AGENT_HOLD_BAZOOKA_R = LLUUID("ef62d355-c815-4816-2474-b1acc21094a6"); -const LLUUID ANIM_AGENT_HOLD_BOW_L = LLUUID("8b102617-bcba-037b-86c1-b76219f90c88"); -const LLUUID ANIM_AGENT_HOLD_HANDGUN_R = LLUUID("efdc1727-8b8a-c800-4077-975fc27ee2f2"); -const LLUUID ANIM_AGENT_HOLD_RIFLE_R = LLUUID("3d94bad0-c55b-7dcc-8763-033c59405d33"); -const LLUUID ANIM_AGENT_HOLD_THROW_R = LLUUID("7570c7b5-1f22-56dd-56ef-a9168241bbb6"); -const LLUUID ANIM_AGENT_HOVER = LLUUID("4ae8016b-31b9-03bb-c401-b1ea941db41d"); -const LLUUID ANIM_AGENT_HOVER_DOWN = LLUUID("20f063ea-8306-2562-0b07-5c853b37b31e"); -const LLUUID ANIM_AGENT_HOVER_UP = LLUUID("62c5de58-cb33-5743-3d07-9e4cd4352864"); -const LLUUID ANIM_AGENT_IMPATIENT = LLUUID("5ea3991f-c293-392e-6860-91dfa01278a3"); -const LLUUID ANIM_AGENT_JUMP = LLUUID("2305bd75-1ca9-b03b-1faa-b176b8a8c49e"); -const LLUUID ANIM_AGENT_JUMP_FOR_JOY = LLUUID("709ea28e-1573-c023-8bf8-520c8bc637fa"); -const LLUUID ANIM_AGENT_KISS_MY_BUTT = LLUUID("19999406-3a3a-d58c-a2ac-d72e555dcf51"); -const LLUUID ANIM_AGENT_LAND = LLUUID("7a17b059-12b2-41b1-570a-186368b6aa6f"); -const LLUUID ANIM_AGENT_LAUGH_SHORT = LLUUID("ca5b3f14-3194-7a2b-c894-aa699b718d1f"); -const LLUUID ANIM_AGENT_MEDIUM_LAND = LLUUID("f4f00d6e-b9fe-9292-f4cb-0ae06ea58d57"); -const LLUUID ANIM_AGENT_MOTORCYCLE_SIT = LLUUID("08464f78-3a8e-2944-cba5-0c94aff3af29"); -const LLUUID ANIM_AGENT_MUSCLE_BEACH = LLUUID("315c3a41-a5f3-0ba4-27da-f893f769e69b"); -const LLUUID ANIM_AGENT_NO = LLUUID("5a977ed9-7f72-44e9-4c4c-6e913df8ae74"); -const LLUUID ANIM_AGENT_NO_UNHAPPY = LLUUID("d83fa0e5-97ed-7eb2-e798-7bd006215cb4"); -const LLUUID ANIM_AGENT_NYAH_NYAH = LLUUID("f061723d-0a18-754f-66ee-29a44795a32f"); -const LLUUID ANIM_AGENT_ONETWO_PUNCH = LLUUID("eefc79be-daae-a239-8c04-890f5d23654a"); -const LLUUID ANIM_AGENT_PEACE = LLUUID("b312b10e-65ab-a0a4-8b3c-1326ea8e3ed9"); -const LLUUID ANIM_AGENT_POINT_ME = LLUUID("17c024cc-eef2-f6a0-3527-9869876d7752"); -const LLUUID ANIM_AGENT_POINT_YOU = LLUUID("ec952cca-61ef-aa3b-2789-4d1344f016de"); -const LLUUID ANIM_AGENT_PRE_JUMP = LLUUID("7a4e87fe-de39-6fcb-6223-024b00893244"); -const LLUUID ANIM_AGENT_PUNCH_LEFT = LLUUID("f3300ad9-3462-1d07-2044-0fef80062da0"); -const LLUUID ANIM_AGENT_PUNCH_RIGHT = LLUUID("c8e42d32-7310-6906-c903-cab5d4a34656"); -const LLUUID ANIM_AGENT_REPULSED = LLUUID("36f81a92-f076-5893-dc4b-7c3795e487cf"); -const LLUUID ANIM_AGENT_ROUNDHOUSE_KICK = LLUUID("49aea43b-5ac3-8a44-b595-96100af0beda"); -const LLUUID ANIM_AGENT_RPS_COUNTDOWN = LLUUID("35db4f7e-28c2-6679-cea9-3ee108f7fc7f"); -const LLUUID ANIM_AGENT_RPS_PAPER = LLUUID("0836b67f-7f7b-f37b-c00a-460dc1521f5a"); -const LLUUID ANIM_AGENT_RPS_ROCK = LLUUID("42dd95d5-0bc6-6392-f650-777304946c0f"); -const LLUUID ANIM_AGENT_RPS_SCISSORS = LLUUID("16803a9f-5140-e042-4d7b-d28ba247c325"); -const LLUUID ANIM_AGENT_RUN = LLUUID("05ddbff8-aaa9-92a1-2b74-8fe77a29b445"); -const LLUUID ANIM_AGENT_SAD = LLUUID("0eb702e2-cc5a-9a88-56a5-661a55c0676a"); -const LLUUID ANIM_AGENT_SALUTE = LLUUID("cd7668a6-7011-d7e2-ead8-fc69eff1a104"); -const LLUUID ANIM_AGENT_SHOOT_BOW_L = LLUUID("e04d450d-fdb5-0432-fd68-818aaf5935f8"); -const LLUUID ANIM_AGENT_SHOUT = LLUUID("6bd01860-4ebd-127a-bb3d-d1427e8e0c42"); -const LLUUID ANIM_AGENT_SHRUG = LLUUID("70ea714f-3a97-d742-1b01-590a8fcd1db5"); -const LLUUID ANIM_AGENT_SIT = LLUUID("1a5fe8ac-a804-8a5d-7cbd-56bd83184568"); -const LLUUID ANIM_AGENT_SIT_FEMALE = LLUUID("b1709c8d-ecd3-54a1-4f28-d55ac0840782"); -const LLUUID ANIM_AGENT_SIT_GENERIC = LLUUID("245f3c54-f1c0-bf2e-811f-46d8eeb386e7"); -const LLUUID ANIM_AGENT_SIT_GROUND = LLUUID("1c7600d6-661f-b87b-efe2-d7421eb93c86"); -const LLUUID ANIM_AGENT_SIT_GROUND_CONSTRAINED = LLUUID("1a2bd58e-87ff-0df8-0b4c-53e047b0bb6e"); -const LLUUID ANIM_AGENT_SIT_TO_STAND = LLUUID("a8dee56f-2eae-9e7a-05a2-6fb92b97e21e"); -const LLUUID ANIM_AGENT_SLEEP = LLUUID("f2bed5f9-9d44-39af-b0cd-257b2a17fe40"); -const LLUUID ANIM_AGENT_SMOKE_IDLE = LLUUID("d2f2ee58-8ad1-06c9-d8d3-3827ba31567a"); -const LLUUID ANIM_AGENT_SMOKE_INHALE = LLUUID("6802d553-49da-0778-9f85-1599a2266526"); -const LLUUID ANIM_AGENT_SMOKE_THROW_DOWN = LLUUID("0a9fb970-8b44-9114-d3a9-bf69cfe804d6"); -const LLUUID ANIM_AGENT_SNAPSHOT = LLUUID("eae8905b-271a-99e2-4c0e-31106afd100c"); -const LLUUID ANIM_AGENT_STAND = LLUUID("2408fe9e-df1d-1d7d-f4ff-1384fa7b350f"); -const LLUUID ANIM_AGENT_STANDUP = LLUUID("3da1d753-028a-5446-24f3-9c9b856d9422"); -const LLUUID ANIM_AGENT_STAND_1 = LLUUID("15468e00-3400-bb66-cecc-646d7c14458e"); -const LLUUID ANIM_AGENT_STAND_2 = LLUUID("370f3a20-6ca6-9971-848c-9a01bc42ae3c"); -const LLUUID ANIM_AGENT_STAND_3 = LLUUID("42b46214-4b44-79ae-deb8-0df61424ff4b"); -const LLUUID ANIM_AGENT_STAND_4 = LLUUID("f22fed8b-a5ed-2c93-64d5-bdd8b93c889f"); -const LLUUID ANIM_AGENT_STRETCH = LLUUID("80700431-74ec-a008-14f8-77575e73693f"); -const LLUUID ANIM_AGENT_STRIDE = LLUUID("1cb562b0-ba21-2202-efb3-30f82cdf9595"); -const LLUUID ANIM_AGENT_SURF = LLUUID("41426836-7437-7e89-025d-0aa4d10f1d69"); -const LLUUID ANIM_AGENT_SURPRISE = LLUUID("313b9881-4302-73c0-c7d0-0e7a36b6c224"); -const LLUUID ANIM_AGENT_SWORD_STRIKE = LLUUID("85428680-6bf9-3e64-b489-6f81087c24bd"); -const LLUUID ANIM_AGENT_TALK = LLUUID("5c682a95-6da4-a463-0bf6-0f5b7be129d1"); -const LLUUID ANIM_AGENT_TANTRUM = LLUUID("11000694-3f41-adc2-606b-eee1d66f3724"); -const LLUUID ANIM_AGENT_THROW_R = LLUUID("aa134404-7dac-7aca-2cba-435f9db875ca"); -const LLUUID ANIM_AGENT_TRYON_SHIRT = LLUUID("83ff59fe-2346-f236-9009-4e3608af64c1"); -const LLUUID ANIM_AGENT_TURNLEFT = LLUUID("56e0ba0d-4a9f-7f27-6117-32f2ebbf6135"); -const LLUUID ANIM_AGENT_TURNRIGHT = LLUUID("2d6daa51-3192-6794-8e2e-a15f8338ec30"); -const LLUUID ANIM_AGENT_TYPE = LLUUID("c541c47f-e0c0-058b-ad1a-d6ae3a4584d9"); -const LLUUID ANIM_AGENT_WALK = LLUUID("6ed24bd8-91aa-4b12-ccc7-c97c857ab4e0"); -const LLUUID ANIM_AGENT_WHISPER = LLUUID("7693f268-06c7-ea71-fa21-2b30d6533f8f"); -const LLUUID ANIM_AGENT_WHISTLE = LLUUID("b1ed7982-c68e-a982-7561-52a88a5298c0"); -const LLUUID ANIM_AGENT_WINK = LLUUID("869ecdad-a44b-671e-3266-56aef2e3ac2e"); -const LLUUID ANIM_AGENT_WINK_HOLLYWOOD = LLUUID("c0c4030f-c02b-49de-24ba-2331f43fe41c"); -const LLUUID ANIM_AGENT_WORRY = LLUUID("9f496bd2-589a-709f-16cc-69bf7df1d36c"); -const LLUUID ANIM_AGENT_YES = LLUUID("15dd911d-be82-2856-26db-27659b142875"); -const LLUUID ANIM_AGENT_YES_HAPPY = LLUUID("b8c8b2a3-9008-1771-3bfc-90924955ab2d"); -const LLUUID ANIM_AGENT_YOGA_FLOAT = LLUUID("42ecd00b-9947-a97c-400a-bbc9174c7aeb"); +extern const LLUUID ANIM_AGENT_AFRAID; +extern const LLUUID ANIM_AGENT_AIM_BAZOOKA_R; +extern const LLUUID ANIM_AGENT_AIM_BOW_L; +extern const LLUUID ANIM_AGENT_AIM_HANDGUN_R; +extern const LLUUID ANIM_AGENT_AIM_RIFLE_R; +extern const LLUUID ANIM_AGENT_ANGRY; +extern const LLUUID ANIM_AGENT_AWAY; +extern const LLUUID ANIM_AGENT_BACKFLIP; +extern const LLUUID ANIM_AGENT_BELLY_LAUGH; +extern const LLUUID ANIM_AGENT_BLOW_KISS; +extern const LLUUID ANIM_AGENT_BORED; +extern const LLUUID ANIM_AGENT_BOW; +extern const LLUUID ANIM_AGENT_BRUSH; +extern const LLUUID ANIM_AGENT_BUSY; +extern const LLUUID ANIM_AGENT_CLAP; +extern const LLUUID ANIM_AGENT_COURTBOW; +extern const LLUUID ANIM_AGENT_CROUCH; +extern const LLUUID ANIM_AGENT_CROUCHWALK; +extern const LLUUID ANIM_AGENT_CRY; +extern const LLUUID ANIM_AGENT_CUSTOMIZE; +extern const LLUUID ANIM_AGENT_CUSTOMIZE_DONE; +extern const LLUUID ANIM_AGENT_DANCE1; +extern const LLUUID ANIM_AGENT_DANCE2; +extern const LLUUID ANIM_AGENT_DANCE3; +extern const LLUUID ANIM_AGENT_DANCE4; +extern const LLUUID ANIM_AGENT_DANCE5; +extern const LLUUID ANIM_AGENT_DANCE6; +extern const LLUUID ANIM_AGENT_DANCE7; +extern const LLUUID ANIM_AGENT_DANCE8; +extern const LLUUID ANIM_AGENT_DEAD; +extern const LLUUID ANIM_AGENT_DRINK; +extern const LLUUID ANIM_AGENT_EMBARRASSED; +extern const LLUUID ANIM_AGENT_EXPRESS_AFRAID; +extern const LLUUID ANIM_AGENT_EXPRESS_ANGER; +extern const LLUUID ANIM_AGENT_EXPRESS_BORED; +extern const LLUUID ANIM_AGENT_EXPRESS_CRY; +extern const LLUUID ANIM_AGENT_EXPRESS_DISDAIN; +extern const LLUUID ANIM_AGENT_EXPRESS_EMBARRASSED; +extern const LLUUID ANIM_AGENT_EXPRESS_FROWN; +extern const LLUUID ANIM_AGENT_EXPRESS_KISS; +extern const LLUUID ANIM_AGENT_EXPRESS_LAUGH; +extern const LLUUID ANIM_AGENT_EXPRESS_OPEN_MOUTH; +extern const LLUUID ANIM_AGENT_EXPRESS_REPULSED; +extern const LLUUID ANIM_AGENT_EXPRESS_SAD; +extern const LLUUID ANIM_AGENT_EXPRESS_SHRUG; +extern const LLUUID ANIM_AGENT_EXPRESS_SMILE; +extern const LLUUID ANIM_AGENT_EXPRESS_SURPRISE; +extern const LLUUID ANIM_AGENT_EXPRESS_TONGUE_OUT; +extern const LLUUID ANIM_AGENT_EXPRESS_TOOTHSMILE; +extern const LLUUID ANIM_AGENT_EXPRESS_WINK; +extern const LLUUID ANIM_AGENT_EXPRESS_WORRY; +extern const LLUUID ANIM_AGENT_FALLDOWN; +extern const LLUUID ANIM_AGENT_FEMALE_RUN_NEW; +extern const LLUUID ANIM_AGENT_FEMALE_WALK; +extern const LLUUID ANIM_AGENT_FEMALE_WALK_NEW; +extern const LLUUID ANIM_AGENT_FINGER_WAG; +extern const LLUUID ANIM_AGENT_FIST_PUMP; +extern const LLUUID ANIM_AGENT_FLY; +extern const LLUUID ANIM_AGENT_FLYSLOW; +extern const LLUUID ANIM_AGENT_HELLO; +extern const LLUUID ANIM_AGENT_HOLD_BAZOOKA_R; +extern const LLUUID ANIM_AGENT_HOLD_BOW_L; +extern const LLUUID ANIM_AGENT_HOLD_HANDGUN_R; +extern const LLUUID ANIM_AGENT_HOLD_RIFLE_R; +extern const LLUUID ANIM_AGENT_HOLD_THROW_R; +extern const LLUUID ANIM_AGENT_HOVER; +extern const LLUUID ANIM_AGENT_HOVER_DOWN; +extern const LLUUID ANIM_AGENT_HOVER_UP; +extern const LLUUID ANIM_AGENT_IMPATIENT; +extern const LLUUID ANIM_AGENT_JUMP; +extern const LLUUID ANIM_AGENT_JUMP_FOR_JOY; +extern const LLUUID ANIM_AGENT_KISS_MY_BUTT; +extern const LLUUID ANIM_AGENT_LAND; +extern const LLUUID ANIM_AGENT_LAUGH_SHORT; +extern const LLUUID ANIM_AGENT_MEDIUM_LAND; +extern const LLUUID ANIM_AGENT_MOTORCYCLE_SIT; +extern const LLUUID ANIM_AGENT_MUSCLE_BEACH; +extern const LLUUID ANIM_AGENT_NO; +extern const LLUUID ANIM_AGENT_NO_UNHAPPY; +extern const LLUUID ANIM_AGENT_NYAH_NYAH; +extern const LLUUID ANIM_AGENT_ONETWO_PUNCH; +extern const LLUUID ANIM_AGENT_PEACE; +extern const LLUUID ANIM_AGENT_POINT_ME; +extern const LLUUID ANIM_AGENT_POINT_YOU; +extern const LLUUID ANIM_AGENT_PRE_JUMP; +extern const LLUUID ANIM_AGENT_PUNCH_LEFT; +extern const LLUUID ANIM_AGENT_PUNCH_RIGHT; +extern const LLUUID ANIM_AGENT_REPULSED; +extern const LLUUID ANIM_AGENT_ROUNDHOUSE_KICK; +extern const LLUUID ANIM_AGENT_RPS_COUNTDOWN; +extern const LLUUID ANIM_AGENT_RPS_PAPER; +extern const LLUUID ANIM_AGENT_RPS_ROCK; +extern const LLUUID ANIM_AGENT_RPS_SCISSORS; +extern const LLUUID ANIM_AGENT_RUN; +extern const LLUUID ANIM_AGENT_RUN_NEW; +extern const LLUUID ANIM_AGENT_SAD; +extern const LLUUID ANIM_AGENT_SALUTE; +extern const LLUUID ANIM_AGENT_SHOOT_BOW_L; +extern const LLUUID ANIM_AGENT_SHOUT; +extern const LLUUID ANIM_AGENT_SHRUG; +extern const LLUUID ANIM_AGENT_SIT; +extern const LLUUID ANIM_AGENT_SIT_FEMALE; +extern const LLUUID ANIM_AGENT_SIT_GENERIC; +extern const LLUUID ANIM_AGENT_SIT_GROUND; +extern const LLUUID ANIM_AGENT_SIT_GROUND_CONSTRAINED; +extern const LLUUID ANIM_AGENT_SIT_TO_STAND; +extern const LLUUID ANIM_AGENT_SLEEP; +extern const LLUUID ANIM_AGENT_SMOKE_IDLE; +extern const LLUUID ANIM_AGENT_SMOKE_INHALE; +extern const LLUUID ANIM_AGENT_SMOKE_THROW_DOWN; +extern const LLUUID ANIM_AGENT_SNAPSHOT; +extern const LLUUID ANIM_AGENT_STAND; +extern const LLUUID ANIM_AGENT_STANDUP; +extern const LLUUID ANIM_AGENT_STAND_1; +extern const LLUUID ANIM_AGENT_STAND_2; +extern const LLUUID ANIM_AGENT_STAND_3; +extern const LLUUID ANIM_AGENT_STAND_4; +extern const LLUUID ANIM_AGENT_STRETCH; +extern const LLUUID ANIM_AGENT_STRIDE; +extern const LLUUID ANIM_AGENT_SURF; +extern const LLUUID ANIM_AGENT_SURPRISE; +extern const LLUUID ANIM_AGENT_SWORD_STRIKE; +extern const LLUUID ANIM_AGENT_TALK; +extern const LLUUID ANIM_AGENT_TANTRUM; +extern const LLUUID ANIM_AGENT_THROW_R; +extern const LLUUID ANIM_AGENT_TRYON_SHIRT; +extern const LLUUID ANIM_AGENT_TURNLEFT; +extern const LLUUID ANIM_AGENT_TURNRIGHT; +extern const LLUUID ANIM_AGENT_TYPE; +extern const LLUUID ANIM_AGENT_WALK; +extern const LLUUID ANIM_AGENT_WALK_NEW; +extern const LLUUID ANIM_AGENT_WHISPER; +extern const LLUUID ANIM_AGENT_WHISTLE; +extern const LLUUID ANIM_AGENT_WINK; +extern const LLUUID ANIM_AGENT_WINK_HOLLYWOOD; +extern const LLUUID ANIM_AGENT_WORRY; +extern const LLUUID ANIM_AGENT_YES; +extern const LLUUID ANIM_AGENT_YES_HAPPY; +extern const LLUUID ANIM_AGENT_YOGA_FLOAT; extern LLUUID AGENT_WALK_ANIMS[]; extern S32 NUM_AGENT_WALK_ANIMS; @@ -222,18 +220,33 @@ public: // Return the animation state for the given name. // Retun NULL if the name is invalid. //----------------------------------------------------------------------------- - LLUUID stringToAnimState( const char *name, BOOL allow_ids = TRUE ); + 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); + + //----------------------------------------------------------------------------- + // 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* label, const char* name, const LLUUID& id) - : mLabel(label), + 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* mLabel; const char* mName; const LLUUID mID; }; @@ -243,7 +256,6 @@ extern const LLAnimStateEntry gUserAnimStates[]; extern const S32 gUserAnimStatesCount; extern LLAnimationLibrary gAnimLibrary; - #endif // LL_LLANIMATIONSTATES_H diff --git a/indra/llcharacter/llbvhconsts.h b/indra/llcharacter/llbvhconsts.h new file mode 100644 index 0000000000..d363a6e595 --- /dev/null +++ b/indra/llcharacter/llbvhconsts.h @@ -0,0 +1,46 @@ +/** + * @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$ + */ + +#ifndef LL_LLBVHCONSTS_H +#define LL_LLBVHCONSTS_H + +const F32 MAX_ANIM_DURATION = 30.f; + +typedef enum e_constraint_type + { + 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; + +#endif // LL_LLBVHCONSTS_H diff --git a/indra/llcharacter/llbvhloader.cpp b/indra/llcharacter/llbvhloader.cpp index 1d157fd5f5..532a2c1b0d 100644 --- a/indra/llcharacter/llbvhloader.cpp +++ b/indra/llcharacter/llbvhloader.cpp @@ -2,30 +2,25 @@ * @file llbvhloader.cpp * @brief Translates a BVH files to LindenLabAnimation format. * - * $LicenseInfo:firstyear=2004&license=viewergpl$ - * - * Copyright (c) 2004-2007, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2004&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlife.com/developers/opensource/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at http://secondlife.com/developers/opensource/flossexception + * 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. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * 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. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * 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$ */ @@ -55,41 +50,43 @@ const F32 ROTATION_MOTION_THRESHOLD = 0.001f; char gInFile[1024]; /* Flawfinder: ignore */ char gOutFile[1024]; /* Flawfinder: ignore */ - +/* //------------------------------------------------------------------------ // Status Codes //------------------------------------------------------------------------ -char *LLBVHLoader::ST_OK = "Ok"; -char *LLBVHLoader::ST_EOF = "Premature end of file."; -char *LLBVHLoader::ST_NO_CONSTRAINT = "Can't read constraint definition."; -char *LLBVHLoader::ST_NO_FILE = "Can't open BVH file."; -char *LLBVHLoader::ST_NO_HIER = "Invalid HIERARCHY header."; -char *LLBVHLoader::ST_NO_JOINT = "Can't find ROOT or JOINT."; -char *LLBVHLoader::ST_NO_NAME = "Can't get JOINT name."; -char *LLBVHLoader::ST_NO_OFFSET = "Can't find OFFSET."; -char *LLBVHLoader::ST_NO_CHANNELS = "Can't find CHANNELS."; -char *LLBVHLoader::ST_NO_ROTATION = "Can't get rotation order."; -char *LLBVHLoader::ST_NO_AXIS = "Can't get rotation axis."; -char *LLBVHLoader::ST_NO_MOTION = "Can't find MOTION."; -char *LLBVHLoader::ST_NO_FRAMES = "Can't get number of frames."; -char *LLBVHLoader::ST_NO_FRAME_TIME = "Can't get frame time."; -char *LLBVHLoader::ST_NO_POS = "Can't get position values."; -char *LLBVHLoader::ST_NO_ROT = "Can't get rotation values."; -char *LLBVHLoader::ST_NO_XLT_FILE = "Can't open translation file."; -char *LLBVHLoader::ST_NO_XLT_HEADER = "Can't read translation header."; -char *LLBVHLoader::ST_NO_XLT_NAME = "Can't read translation names."; -char *LLBVHLoader::ST_NO_XLT_IGNORE = "Can't read translation ignore value."; -char *LLBVHLoader::ST_NO_XLT_RELATIVE = "Can't read translation relative value."; -char *LLBVHLoader::ST_NO_XLT_OUTNAME = "Can't read translation outname value."; -char *LLBVHLoader::ST_NO_XLT_MATRIX = "Can't read translation matrix."; -char *LLBVHLoader::ST_NO_XLT_MERGECHILD = "Can't get mergechild name."; -char *LLBVHLoader::ST_NO_XLT_MERGEPARENT = "Can't get mergeparent name."; -char *LLBVHLoader::ST_NO_XLT_PRIORITY = "Can't get priority value."; -char *LLBVHLoader::ST_NO_XLT_LOOP = "Can't get loop value."; -char *LLBVHLoader::ST_NO_XLT_EASEIN = "Can't get easeIn values."; -char *LLBVHLoader::ST_NO_XLT_EASEOUT = "Can't get easeOut values."; -char *LLBVHLoader::ST_NO_XLT_HAND = "Can't get hand morph value."; -char *LLBVHLoader::ST_NO_XLT_EMOTE = "Can't read emote name."; +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_BAD_ROOT = "Illegal ROOT joint."; +*/ //------------------------------------------------------------------------ // find_next_whitespace() @@ -123,7 +120,9 @@ LLQuaternion::Order bvhStringToOrder( char *str ) //----------------------------------------------------------------------------- // LLBVHLoader() //----------------------------------------------------------------------------- -LLBVHLoader::LLBVHLoader(const char* buffer) + +/* + LLBVHLoader::LLBVHLoader(const char* buffer) { reset(); @@ -143,7 +142,7 @@ LLBVHLoader::LLBVHLoader(const char* buffer) } } - char error_text[128]; /* Flawfinder: ignore */ + char error_text[128]; // Flawfinder: ignore S32 error_line; mStatus = loadBVHFile(buffer, error_text, error_line); if (mStatus != LLBVHLoader::ST_OK) @@ -157,6 +156,49 @@ LLBVHLoader::LLBVHLoader(const char* buffer) mInitialized = TRUE; } +*/ +LLBVHLoader::LLBVHLoader(const char* buffer, ELoadStatus &loadStatus, S32 &errorLine) +{ + reset(); + errorLine = 0; + mStatus = loadTranslationTable("anim.ini"); + loadStatus = mStatus; + llinfos<<"Load Status 00 : "<< loadStatus << llendl; + if (mStatus == E_ST_NO_XLT_FILE) + { + //llwarns << "NOTE: No translation table found." << llendl; + loadStatus = mStatus; + return; + } + else + { + if (mStatus != E_ST_OK) + { + //llwarns << "ERROR: [line: " << getLineNumber() << "] " << mStatus << llendl; + errorLine = getLineNumber(); + loadStatus = mStatus; + return; + } + } + + char error_text[128]; /* Flawfinder: ignore */ + S32 error_line; + mStatus = loadBVHFile(buffer, error_text, error_line); + + if (mStatus != E_ST_OK) + { + //llwarns << "ERROR: [line: " << getLineNumber() << "] " << mStatus << llendl; + loadStatus = mStatus; + errorLine = getLineNumber(); + return; + } + + applyTranslations(); + optimize(); + + mInitialized = TRUE; +} + LLBVHLoader::~LLBVHLoader() { @@ -166,7 +208,7 @@ LLBVHLoader::~LLBVHLoader() //------------------------------------------------------------------------ // LLBVHLoader::loadTranslationTable() //------------------------------------------------------------------------ -LLBVHLoader::Status LLBVHLoader::loadTranslationTable(const char *fileName) +ELoadStatus LLBVHLoader::loadTranslationTable(const char *fileName) { mLineNumber = 0; mTranslations.clear(); @@ -175,30 +217,27 @@ LLBVHLoader::Status LLBVHLoader::loadTranslationTable(const char *fileName) //-------------------------------------------------------------------- // open file //-------------------------------------------------------------------- - char path[LL_MAX_PATH]; /* Flawfinder: ignore */ + std::string path = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS,fileName); - snprintf( path, sizeof(path), "%s", /* Flawfinder: ignore */ - gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS,fileName).c_str()); - - - apr_file_t *fp = ll_apr_file_open(path, LL_APR_R); + LLAPRFile infile ; + infile.open(path, LL_APR_R); + apr_file_t *fp = infile.getFileHandle(); if (!fp) - return ST_NO_XLT_FILE; + return E_ST_NO_XLT_FILE; llinfos << "NOTE: Loading translation table: " << fileName << llendl; //-------------------------------------------------------------------- // register file to be closed on function exit //-------------------------------------------------------------------- - FileCloser fileCloser(fp); - + //-------------------------------------------------------------------- // load header //-------------------------------------------------------------------- if ( ! getLine(fp) ) - return ST_EOF; + return E_ST_EOF; if ( strncmp(mLine, "Translations 1.0", 16) ) - return ST_NO_XLT_HEADER; + return E_ST_NO_XLT_HEADER; //-------------------------------------------------------------------- // load data one line at a time @@ -224,7 +263,7 @@ LLBVHLoader::Status LLBVHLoader::loadTranslationTable(const char *fileName) { char name[128]; /* Flawfinder: ignore */ if ( sscanf(mLine, " [%127[^]]", name) != 1 ) - return ST_NO_XLT_NAME; + return E_ST_NO_XLT_NAME; if (strcmp(name, "GLOBALS")==0) { @@ -243,11 +282,11 @@ LLBVHLoader::Status LLBVHLoader::loadTranslationTable(const char *fileName) //---------------------------------------------------------------- // check for optional emote //---------------------------------------------------------------- - if (loadingGlobals && LLString::compareInsensitive(token, "emote")==0) + if (loadingGlobals && LLStringUtil::compareInsensitive(token, "emote")==0) { char emote_str[1024]; /* Flawfinder: ignore */ if ( sscanf(mLine, " %*s = %1023s", emote_str) != 1 ) /* Flawfinder: ignore */ - return ST_NO_XLT_EMOTE; + return E_ST_NO_XLT_EMOTE; mEmoteName.assign( emote_str ); // llinfos << "NOTE: Emote: " << mEmoteName.c_str() << llendl; @@ -258,11 +297,11 @@ LLBVHLoader::Status LLBVHLoader::loadTranslationTable(const char *fileName) //---------------------------------------------------------------- // check for global priority setting //---------------------------------------------------------------- - if (loadingGlobals && LLString::compareInsensitive(token, "priority")==0) + if (loadingGlobals && LLStringUtil::compareInsensitive(token, "priority")==0) { S32 priority; if ( sscanf(mLine, " %*s = %d", &priority) != 1 ) - return ST_NO_XLT_PRIORITY; + return E_ST_NO_XLT_PRIORITY; mPriority = priority; // llinfos << "NOTE: Priority: " << mPriority << llendl; @@ -272,7 +311,7 @@ LLBVHLoader::Status LLBVHLoader::loadTranslationTable(const char *fileName) //---------------------------------------------------------------- // check for global loop setting //---------------------------------------------------------------- - if (loadingGlobals && LLString::compareInsensitive(token, "loop")==0) + if (loadingGlobals && LLStringUtil::compareInsensitive(token, "loop")==0) { char trueFalse[128]; /* Flawfinder: ignore */ trueFalse[0] = '\0'; @@ -286,11 +325,11 @@ LLBVHLoader::Status LLBVHLoader::loadTranslationTable(const char *fileName) } else if ( sscanf(mLine, " %*s = %127s", trueFalse) == 1 ) /* Flawfinder: ignore */ { - mLoop = (LLString::compareInsensitive(trueFalse, "true")==0); + mLoop = (LLStringUtil::compareInsensitive(trueFalse, "true")==0); } else { - return ST_NO_XLT_LOOP; + return E_ST_NO_XLT_LOOP; } mLoopInPoint = loop_in * mDuration; @@ -302,12 +341,12 @@ LLBVHLoader::Status LLBVHLoader::loadTranslationTable(const char *fileName) //---------------------------------------------------------------- // check for global easeIn setting //---------------------------------------------------------------- - if (loadingGlobals && LLString::compareInsensitive(token, "easein")==0) + 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 ST_NO_XLT_EASEIN; + return E_ST_NO_XLT_EASEIN; mEaseIn = duration; continue; @@ -316,12 +355,12 @@ LLBVHLoader::Status LLBVHLoader::loadTranslationTable(const char *fileName) //---------------------------------------------------------------- // check for global easeOut setting //---------------------------------------------------------------- - if (loadingGlobals && LLString::compareInsensitive(token, "easeout")==0) + 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 ST_NO_XLT_EASEOUT; + return E_ST_NO_XLT_EASEOUT; mEaseOut = duration; continue; @@ -330,17 +369,17 @@ LLBVHLoader::Status LLBVHLoader::loadTranslationTable(const char *fileName) //---------------------------------------------------------------- // check for global handMorph setting //---------------------------------------------------------------- - if (loadingGlobals && LLString::compareInsensitive(token, "hand")==0) + if (loadingGlobals && LLStringUtil::compareInsensitive(token, "hand")==0) { S32 handMorph; if (sscanf(mLine, " %*s = %d", &handMorph) != 1) - return ST_NO_XLT_HAND; + return E_ST_NO_XLT_HAND; mHand = handMorph; continue; } - if (loadingGlobals && LLString::compareInsensitive(token, "constraint")==0) + if (loadingGlobals && LLStringUtil::compareInsensitive(token, "constraint")==0) { Constraint constraint; @@ -382,7 +421,7 @@ LLBVHLoader::Status LLBVHLoader::loadTranslationTable(const char *fileName) &constraint.mTargetOffset.mV[VY], &constraint.mTargetOffset.mV[VZ]) != 13) { - return ST_NO_CONSTRAINT; + return E_ST_NO_CONSTRAINT; } } else @@ -400,7 +439,7 @@ LLBVHLoader::Status LLBVHLoader::loadTranslationTable(const char *fileName) continue; } - if (loadingGlobals && LLString::compareInsensitive(token, "planar_constraint")==0) + if (loadingGlobals && LLStringUtil::compareInsensitive(token, "planar_constraint")==0) { Constraint constraint; @@ -442,7 +481,7 @@ LLBVHLoader::Status LLBVHLoader::loadTranslationTable(const char *fileName) &constraint.mTargetOffset.mV[VY], &constraint.mTargetOffset.mV[VZ]) != 13) { - return ST_NO_CONSTRAINT; + return E_ST_NO_CONSTRAINT; } } else @@ -465,25 +504,25 @@ LLBVHLoader::Status LLBVHLoader::loadTranslationTable(const char *fileName) // at this point there must be a valid trans pointer //---------------------------------------------------------------- if ( ! trans ) - return ST_NO_XLT_NAME; + return E_ST_NO_XLT_NAME; //---------------------------------------------------------------- // check for ignore flag //---------------------------------------------------------------- - if ( LLString::compareInsensitive(token, "ignore")==0 ) + if ( LLStringUtil::compareInsensitive(token, "ignore")==0 ) { char trueFalse[128]; /* Flawfinder: ignore */ if ( sscanf(mLine, " %*s = %127s", trueFalse) != 1 ) /* Flawfinder: ignore */ - return ST_NO_XLT_IGNORE; + return E_ST_NO_XLT_IGNORE; - trans->mIgnore = (LLString::compareInsensitive(trueFalse, "true")==0); + trans->mIgnore = (LLStringUtil::compareInsensitive(trueFalse, "true")==0); continue; } //---------------------------------------------------------------- // check for relativepos flag //---------------------------------------------------------------- - if ( LLString::compareInsensitive(token, "relativepos")==0 ) + if ( LLStringUtil::compareInsensitive(token, "relativepos")==0 ) { F32 x, y, z; char relpos[128]; /* Flawfinder: ignore */ @@ -493,18 +532,18 @@ LLBVHLoader::Status LLBVHLoader::loadTranslationTable(const char *fileName) } else if ( sscanf(mLine, " %*s = %127s", relpos) == 1 ) /* Flawfinder: ignore */ { - if ( LLString::compareInsensitive(relpos, "firstkey")==0 ) + if ( LLStringUtil::compareInsensitive(relpos, "firstkey")==0 ) { trans->mRelativePositionKey = TRUE; } else { - return ST_NO_XLT_RELATIVE; + return E_ST_NO_XLT_RELATIVE; } } else { - return ST_NO_XLT_RELATIVE; + return E_ST_NO_XLT_RELATIVE; } continue; @@ -513,24 +552,24 @@ LLBVHLoader::Status LLBVHLoader::loadTranslationTable(const char *fileName) //---------------------------------------------------------------- // check for relativerot flag //---------------------------------------------------------------- - if ( LLString::compareInsensitive(token, "relativerot")==0 ) + if ( LLStringUtil::compareInsensitive(token, "relativerot")==0 ) { //F32 x, y, z; char relpos[128]; /* Flawfinder: ignore */ if ( sscanf(mLine, " %*s = %127s", relpos) == 1 ) /* Flawfinder: ignore */ { - if ( LLString::compareInsensitive(relpos, "firstkey")==0 ) + if ( LLStringUtil::compareInsensitive(relpos, "firstkey")==0 ) { trans->mRelativeRotationKey = TRUE; } else { - return ST_NO_XLT_RELATIVE; + return E_ST_NO_XLT_RELATIVE; } } else { - return ST_NO_XLT_RELATIVE; + return E_ST_NO_XLT_RELATIVE; } continue; @@ -539,11 +578,11 @@ LLBVHLoader::Status LLBVHLoader::loadTranslationTable(const char *fileName) //---------------------------------------------------------------- // check for outname value //---------------------------------------------------------------- - if ( LLString::compareInsensitive(token, "outname")==0 ) + if ( LLStringUtil::compareInsensitive(token, "outname")==0 ) { char outName[128]; /* Flawfinder: ignore */ if ( sscanf(mLine, " %*s = %127s", outName) != 1 ) /* Flawfinder: ignore */ - return ST_NO_XLT_OUTNAME; + return E_ST_NO_XLT_OUTNAME; trans->mOutName = outName; continue; @@ -552,14 +591,14 @@ LLBVHLoader::Status LLBVHLoader::loadTranslationTable(const char *fileName) //---------------------------------------------------------------- // check for frame matrix value //---------------------------------------------------------------- - if ( LLString::compareInsensitive(token, "frame")==0 ) + if ( LLStringUtil::compareInsensitive(token, "frame")==0 ) { LLMatrix3 fm; if ( sscanf(mLine, " %*s = %f %f %f, %f %f %f, %f %f %f", &fm.mMatrix[0][0], &fm.mMatrix[0][1], &fm.mMatrix[0][2], &fm.mMatrix[1][0], &fm.mMatrix[1][1], &fm.mMatrix[1][2], &fm.mMatrix[2][0], &fm.mMatrix[2][1], &fm.mMatrix[2][2] ) != 9 ) - return ST_NO_XLT_MATRIX; + return E_ST_NO_XLT_MATRIX; trans->mFrameMatrix = fm; continue; @@ -568,14 +607,14 @@ LLBVHLoader::Status LLBVHLoader::loadTranslationTable(const char *fileName) //---------------------------------------------------------------- // check for offset matrix value //---------------------------------------------------------------- - if ( LLString::compareInsensitive(token, "offset")==0 ) + if ( LLStringUtil::compareInsensitive(token, "offset")==0 ) { LLMatrix3 om; if ( sscanf(mLine, " %*s = %f %f %f, %f %f %f, %f %f %f", &om.mMatrix[0][0], &om.mMatrix[0][1], &om.mMatrix[0][2], &om.mMatrix[1][0], &om.mMatrix[1][1], &om.mMatrix[1][2], &om.mMatrix[2][0], &om.mMatrix[2][1], &om.mMatrix[2][2] ) != 9 ) - return ST_NO_XLT_MATRIX; + return E_ST_NO_XLT_MATRIX; trans->mOffsetMatrix = om; continue; @@ -584,11 +623,11 @@ LLBVHLoader::Status LLBVHLoader::loadTranslationTable(const char *fileName) //---------------------------------------------------------------- // check for mergeparent value //---------------------------------------------------------------- - if ( LLString::compareInsensitive(token, "mergeparent")==0 ) + if ( LLStringUtil::compareInsensitive(token, "mergeparent")==0 ) { char mergeParentName[128]; /* Flawfinder: ignore */ if ( sscanf(mLine, " %*s = %127s", mergeParentName) != 1 ) /* Flawfinder: ignore */ - return ST_NO_XLT_MERGEPARENT; + return E_ST_NO_XLT_MERGEPARENT; trans->mMergeParentName = mergeParentName; continue; @@ -597,11 +636,11 @@ LLBVHLoader::Status LLBVHLoader::loadTranslationTable(const char *fileName) //---------------------------------------------------------------- // check for mergechild value //---------------------------------------------------------------- - if ( LLString::compareInsensitive(token, "mergechild")==0 ) + if ( LLStringUtil::compareInsensitive(token, "mergechild")==0 ) { char mergeChildName[128]; /* Flawfinder: ignore */ if ( sscanf(mLine, " %*s = %127s", mergeChildName) != 1 ) /* Flawfinder: ignore */ - return ST_NO_XLT_MERGECHILD; + return E_ST_NO_XLT_MERGECHILD; trans->mMergeChildName = mergeChildName; continue; @@ -610,25 +649,27 @@ LLBVHLoader::Status LLBVHLoader::loadTranslationTable(const char *fileName) //---------------------------------------------------------------- // check for per-joint priority //---------------------------------------------------------------- - if ( LLString::compareInsensitive(token, "priority")==0 ) + if ( LLStringUtil::compareInsensitive(token, "priority")==0 ) { S32 priority; if ( sscanf(mLine, " %*s = %d", &priority) != 1 ) - return ST_NO_XLT_PRIORITY; + return E_ST_NO_XLT_PRIORITY; trans->mPriorityModifier = priority; continue; } } - return ST_OK; + + infile.close() ; + return E_ST_OK; } //------------------------------------------------------------------------ // LLBVHLoader::loadBVHFile() //------------------------------------------------------------------------ -LLBVHLoader::Status LLBVHLoader::loadBVHFile(const char *buffer, char* error_text, S32 &err_line) +ELoadStatus LLBVHLoader::loadBVHFile(const char *buffer, char* error_text, S32 &err_line) { std::string line; @@ -650,14 +691,14 @@ LLBVHLoader::Status LLBVHLoader::loadBVHFile(const char *buffer, char* error_tex // consume hierarchy //-------------------------------------------------------------------- if (iter == tokens.end()) - return ST_EOF; + return E_ST_EOF; line = (*(iter++)); err_line++; if ( !strstr(line.c_str(), "HIERARCHY") ) { // llinfos << line << llendl; - return ST_NO_HIER; + return E_ST_NO_HIER; } //-------------------------------------------------------------------- @@ -669,7 +710,7 @@ LLBVHLoader::Status LLBVHLoader::loadBVHFile(const char *buffer, char* error_tex // get next line //---------------------------------------------------------------- if (iter == tokens.end()) - return ST_EOF; + return E_ST_EOF; line = (*(iter++)); err_line++; @@ -719,7 +760,7 @@ LLBVHLoader::Status LLBVHLoader::loadBVHFile(const char *buffer, char* error_tex else { strncpy(error_text, line.c_str(), 127); /* Flawfinder: ignore */ - return ST_NO_JOINT; + return E_ST_NO_JOINT; } //---------------------------------------------------------------- @@ -729,9 +770,20 @@ LLBVHLoader::Status LLBVHLoader::loadBVHFile(const char *buffer, char* error_tex if ( sscanf(line.c_str(), "%*s %79s", jointName) != 1 ) /* Flawfinder: ignore */ { strncpy(error_text, line.c_str(), 127); /* Flawfinder: ignore */ - return ST_NO_NAME; + return E_ST_NO_NAME; } + //--------------------------------------------------------------- + // we require the root joint be "hip" - DEV-26188 + //--------------------------------------------------------------- + const char* FORCED_ROOT_NAME = "hip"; + if ( (mJoints.size() == 0 ) && ( !strstr(jointName, FORCED_ROOT_NAME) ) ) + { + strncpy(error_text, line.c_str(), 127); /* Flawfinder: ignore */ + return E_ST_BAD_ROOT; + } + + //---------------------------------------------------------------- // add a set of keyframes for this joint //---------------------------------------------------------------- @@ -754,7 +806,7 @@ LLBVHLoader::Status LLBVHLoader::loadBVHFile(const char *buffer, char* error_tex //---------------------------------------------------------------- if (iter == tokens.end()) { - return ST_EOF; + return E_ST_EOF; } line = (*(iter++)); err_line++; @@ -765,7 +817,7 @@ LLBVHLoader::Status LLBVHLoader::loadBVHFile(const char *buffer, char* error_tex if ( !strstr(line.c_str(), "{") ) { strncpy(error_text, line.c_str(), 127); /*Flawfinder: ignore*/ - return ST_NO_OFFSET; + return E_ST_NO_OFFSET; } else { @@ -777,7 +829,7 @@ LLBVHLoader::Status LLBVHLoader::loadBVHFile(const char *buffer, char* error_tex //---------------------------------------------------------------- if (iter == tokens.end()) { - return ST_EOF; + return E_ST_EOF; } line = (*(iter++)); err_line++; @@ -788,7 +840,7 @@ LLBVHLoader::Status LLBVHLoader::loadBVHFile(const char *buffer, char* error_tex if ( !strstr(line.c_str(), "OFFSET") ) { strncpy(error_text, line.c_str(), 127); /*Flawfinder: ignore*/ - return ST_NO_OFFSET; + return E_ST_NO_OFFSET; } //---------------------------------------------------------------- @@ -796,7 +848,7 @@ LLBVHLoader::Status LLBVHLoader::loadBVHFile(const char *buffer, char* error_tex //---------------------------------------------------------------- if (iter == tokens.end()) { - return ST_EOF; + return E_ST_EOF; } line = (*(iter++)); err_line++; @@ -807,7 +859,7 @@ LLBVHLoader::Status LLBVHLoader::loadBVHFile(const char *buffer, char* error_tex if ( !strstr(line.c_str(), "CHANNELS") ) { strncpy(error_text, line.c_str(), 127); /*Flawfinder: ignore*/ - return ST_NO_CHANNELS; + return E_ST_NO_CHANNELS; } //---------------------------------------------------------------- @@ -820,14 +872,14 @@ LLBVHLoader::Status LLBVHLoader::loadBVHFile(const char *buffer, char* error_tex if (!p) { strncpy(error_text, line.c_str(), 127); /*Flawfinder: ignore*/ - return ST_NO_ROTATION; + 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 ST_NO_AXIS; + return E_ST_NO_AXIS; } joint->mOrder[i] = axis; @@ -842,7 +894,7 @@ LLBVHLoader::Status LLBVHLoader::loadBVHFile(const char *buffer, char* error_tex if ( !strstr(line.c_str(), "MOTION") ) { strncpy(error_text, line.c_str(), 127); /*Flawfinder: ignore*/ - return ST_NO_MOTION; + return E_ST_NO_MOTION; } //-------------------------------------------------------------------- @@ -850,7 +902,7 @@ LLBVHLoader::Status LLBVHLoader::loadBVHFile(const char *buffer, char* error_tex //-------------------------------------------------------------------- if (iter == tokens.end()) { - return ST_EOF; + return E_ST_EOF; } line = (*(iter++)); err_line++; @@ -858,13 +910,13 @@ LLBVHLoader::Status LLBVHLoader::loadBVHFile(const char *buffer, char* error_tex if ( !strstr(line.c_str(), "Frames:") ) { strncpy(error_text, line.c_str(), 127); /*Flawfinder: ignore*/ - return ST_NO_FRAMES; + return E_ST_NO_FRAMES; } if ( sscanf(line.c_str(), "Frames: %d", &mNumFrames) != 1 ) { strncpy(error_text, line.c_str(), 127); /*Flawfinder: ignore*/ - return ST_NO_FRAMES; + return E_ST_NO_FRAMES; } //-------------------------------------------------------------------- @@ -872,7 +924,7 @@ LLBVHLoader::Status LLBVHLoader::loadBVHFile(const char *buffer, char* error_tex //-------------------------------------------------------------------- if (iter == tokens.end()) { - return ST_EOF; + return E_ST_EOF; } line = (*(iter++)); err_line++; @@ -880,13 +932,13 @@ LLBVHLoader::Status LLBVHLoader::loadBVHFile(const char *buffer, char* error_tex if ( !strstr(line.c_str(), "Frame Time:") ) { strncpy(error_text, line.c_str(), 127); /*Flawfinder: ignore*/ - return ST_NO_FRAME_TIME; + 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 ST_NO_FRAME_TIME; + return E_ST_NO_FRAME_TIME; } mDuration = (F32)mNumFrames * mFrameTime; @@ -903,7 +955,7 @@ LLBVHLoader::Status LLBVHLoader::loadBVHFile(const char *buffer, char* error_tex // get next line if (iter == tokens.end()) { - return ST_EOF; + return E_ST_EOF; } line = (*(iter++)); err_line++; @@ -922,7 +974,7 @@ LLBVHLoader::Status LLBVHLoader::loadBVHFile(const char *buffer, char* error_tex if ( sscanf(p, "%f %f %f", key.mPos, key.mPos+1, key.mPos+2) != 3 ) { strncpy(error_text, line.c_str(), 127); /*Flawfinder: ignore*/ - return ST_NO_POS; + return E_ST_NO_POS; } } @@ -931,19 +983,19 @@ LLBVHLoader::Status LLBVHLoader::loadBVHFile(const char *buffer, char* error_tex if (!p) { strncpy(error_text, line.c_str(), 127); /*Flawfinder: ignore*/ - return ST_NO_ROT; + return E_ST_NO_ROT; } p = find_next_whitespace(++p); if (!p) { strncpy(error_text, line.c_str(), 127); /*Flawfinder: ignore*/ - return ST_NO_ROT; + return E_ST_NO_ROT; } p = find_next_whitespace(++p); if (!p) { strncpy(error_text, line.c_str(), 127); /*Flawfinder: ignore*/ - return ST_NO_ROT; + return E_ST_NO_ROT; } // get 3 rot values for joint @@ -951,7 +1003,7 @@ LLBVHLoader::Status LLBVHLoader::loadBVHFile(const char *buffer, char* error_tex if ( sscanf(p, " %f %f %f", rot, rot+1, rot+2) != 3 ) { strncpy(error_text, line.c_str(), 127); /*Flawfinder: ignore*/ - return ST_NO_ROT; + return E_ST_NO_ROT; } p++; @@ -962,7 +1014,7 @@ LLBVHLoader::Status LLBVHLoader::loadBVHFile(const char *buffer, char* error_tex } } - return ST_OK; + return E_ST_OK; } @@ -1137,6 +1189,8 @@ void LLBVHLoader::optimize() 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) @@ -1197,30 +1251,55 @@ void LLBVHLoader::optimize() 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; - if (rot_test < rot_threshold) - { - ki_prev->mIgnoreRot = TRUE; - numRotFramesConsidered++; - } - else + // 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; + } } } @@ -1304,7 +1383,7 @@ BOOL LLBVHLoader::serialize(LLDataPacker& dp) dp.packU16(KEYFRAME_MOTION_SUBVERSION, "sub_version"); dp.packS32(mPriority, "base_priority"); dp.packF32(mDuration, "duration"); - dp.packString(mEmoteName.c_str(), "emote_name"); + dp.packString(mEmoteName, "emote_name"); dp.packF32(mLoopInPoint, "loop_in_point"); dp.packF32(mLoopOutPoint, "loop_out_point"); dp.packS32(mLoop, "loop"); @@ -1325,7 +1404,7 @@ BOOL LLBVHLoader::serialize(LLDataPacker& dp) LLQuaternion first_frame_rot; LLQuaternion fixup_rot; - dp.packString(joint->mOutName.c_str(), "joint_name"); + dp.packString(joint->mOutName, "joint_name"); dp.packS32(joint->mPriority, "joint_priority"); // compute coordinate frame rotation diff --git a/indra/llcharacter/llbvhloader.h b/indra/llcharacter/llbvhloader.h index 9f69cff7c7..f816b76277 100644 --- a/indra/llcharacter/llbvhloader.h +++ b/indra/llcharacter/llbvhloader.h @@ -2,30 +2,25 @@ * @file llbvhloader.h * @brief Translates a BVH files to LindenLabAnimation format. * - * $LicenseInfo:firstyear=2004&license=viewergpl$ - * - * Copyright (c) 2004-2007, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2004&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlife.com/developers/opensource/gplv2 + * 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. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at http://secondlife.com/developers/opensource/flossexception + * 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. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * 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 * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -36,9 +31,9 @@ #include "m3math.h" #include "llmath.h" #include "llapr.h" +#include "llbvhconsts.h" const S32 BVH_PARSER_LINE_SIZE = 2048; -const F32 MAX_ANIM_DURATION = 30.f; class LLDataPacker; //------------------------------------------------------------------------ @@ -131,12 +126,6 @@ struct Joint }; -typedef enum e_constraint_type -{ - CONSTRAINT_TYPE_POINT, - CONSTRAINT_TYPE_PLANE -} EConstraintType; - struct Constraint { char mSourceJointName[16]; /* Flawfinder: ignore */ @@ -171,6 +160,7 @@ public: Translation() { mIgnore = FALSE; + mIgnorePositions = FALSE; mRelativePositionKey = FALSE; mRelativeRotationKey = FALSE; mPriorityModifier = 0; @@ -189,6 +179,42 @@ public: 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; + //------------------------------------------------------------------------ // TranslationMap //------------------------------------------------------------------------ @@ -199,49 +225,52 @@ class LLBVHLoader friend class LLKeyframeMotion; public: // Constructor - LLBVHLoader(const char* buffer); +// LLBVHLoader(const char* buffer); + LLBVHLoader(const char* buffer, ELoadStatus &loadStatus, S32 &errorLine); ~LLBVHLoader(); - - // Status Codes - typedef char *Status; - static char *ST_OK; - static char *ST_EOF; - static char *ST_NO_CONSTRAINT; - static char *ST_NO_FILE; - static char *ST_NO_HIER; - static char *ST_NO_JOINT; - static char *ST_NO_NAME; - static char *ST_NO_OFFSET; - static char *ST_NO_CHANNELS; - static char *ST_NO_ROTATION; - static char *ST_NO_AXIS; - static char *ST_NO_MOTION; - static char *ST_NO_FRAMES; - static char *ST_NO_FRAME_TIME; - static char *ST_NO_POS; - static char *ST_NO_ROT; - static char *ST_NO_XLT_FILE; - static char *ST_NO_XLT_HEADER; - static char *ST_NO_XLT_NAME; - static char *ST_NO_XLT_IGNORE; - static char *ST_NO_XLT_RELATIVE; - static char *ST_NO_XLT_OUTNAME; - static char *ST_NO_XLT_MATRIX; - static char *ST_NO_XLT_MERGECHILD; - static char *ST_NO_XLT_MERGEPARENT; - static char *ST_NO_XLT_PRIORITY; - static char *ST_NO_XLT_LOOP; - static char *ST_NO_XLT_EASEIN; - static char *ST_NO_XLT_EASEOUT; - static char *ST_NO_XLT_HAND; - static char *ST_NO_XLT_EMOTE; +/* + // 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. - Status loadTranslationTable(const char *fileName); + ELoadStatus loadTranslationTable(const char *fileName); // Load the specified BVH file. // Returns status code. - Status loadBVHFile(const char *buffer, char *error_text, S32 &error_line); + ELoadStatus loadBVHFile(const char *buffer, char *error_text, S32 &error_line); // Applies translations to BVH data loaded. void applyTranslations(); @@ -265,7 +294,7 @@ public: BOOL isInitialized() { return mInitialized; } - Status getStatus() { return mStatus; } + ELoadStatus getStatus() { return mStatus; } protected: // Consumes one line of input from file. @@ -292,7 +321,8 @@ protected: std::string mEmoteName; BOOL mInitialized; - Status mStatus; + ELoadStatus mStatus; + // computed values F32 mDuration; }; diff --git a/indra/llcharacter/llcharacter.cpp b/indra/llcharacter/llcharacter.cpp index ccc666e74d..5f84be2c5d 100644 --- a/indra/llcharacter/llcharacter.cpp +++ b/indra/llcharacter/llcharacter.cpp @@ -2,30 +2,25 @@ * @file llcharacter.cpp * @brief Implementation of LLCharacter class. * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2007, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlife.com/developers/opensource/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at http://secondlife.com/developers/opensource/flossexception + * 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. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * 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. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * 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$ */ @@ -103,11 +98,11 @@ LLJoint *LLCharacter::getJoint( const std::string &name ) } //----------------------------------------------------------------------------- -// addMotion() +// registerMotion() //----------------------------------------------------------------------------- -BOOL LLCharacter::addMotion( const LLUUID& id, LLMotionConstructor create ) +BOOL LLCharacter::registerMotion( const LLUUID& id, LLMotionConstructor create ) { - return mMotionController.addMotion(id, create); + return mMotionController.registerMotion(id, create); } //----------------------------------------------------------------------------- @@ -119,7 +114,16 @@ void LLCharacter::removeMotion( const LLUUID& id ) } //----------------------------------------------------------------------------- -// getMotion() +// findMotion() +//----------------------------------------------------------------------------- +LLMotion* LLCharacter::findMotion( const LLUUID &id ) +{ + return mMotionController.findMotion( id ); +} + +//----------------------------------------------------------------------------- +// createMotion() +// NOTE: Always assign the result to a LLPointer! //----------------------------------------------------------------------------- LLMotion* LLCharacter::createMotion( const LLUUID &id ) { @@ -168,26 +172,28 @@ void LLCharacter::requestStopMotion( LLMotion* motion) //----------------------------------------------------------------------------- -// updateMotion() +// updateMotions() //----------------------------------------------------------------------------- -void LLCharacter::updateMotion(BOOL force_update) +static LLFastTimer::DeclareTimer FTM_UPDATE_ANIMATION("Update Animation"); +static LLFastTimer::DeclareTimer FTM_UPDATE_HIDDEN_ANIMATION("Update Hidden Anim"); + +void LLCharacter::updateMotions(e_update_t update_type) { - // unpause if we're forcing an update or - // number of outstanding pause requests has dropped - // to the initial one - if (mMotionController.isPaused() && - (force_update || mPauseRequest->getNumRefs() == 1)) + if (update_type == HIDDEN_UPDATE) { - mMotionController.unpause(); + LLFastTimer t(FTM_UPDATE_HIDDEN_ANIMATION); + mMotionController.updateMotionsMinimal(); } - - mMotionController.updateMotion(); - - // pause once again, after forced update, if there are outstanding - // pause requests - if (force_update && mPauseRequest->getNumRefs() > 1) + else { - mMotionController.pause(); + LLFastTimer t(FTM_UPDATE_ANIMATION); + // 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); } } @@ -263,13 +269,13 @@ void LLCharacter::removeAnimationData(std::string name) //----------------------------------------------------------------------------- // setVisualParamWeight() //----------------------------------------------------------------------------- -BOOL LLCharacter::setVisualParamWeight(LLVisualParam* which_param, F32 weight, BOOL set_by_user) +BOOL LLCharacter::setVisualParamWeight(LLVisualParam* which_param, F32 weight, BOOL upload_bake) { S32 index = which_param->getID(); - VisualParamIndexMap_t::iterator index_iter = mVisualParamIndexMap.find(index); + visual_param_index_map_t::iterator index_iter = mVisualParamIndexMap.find(index); if (index_iter != mVisualParamIndexMap.end()) { - index_iter->second->setWeight(weight, set_by_user); + index_iter->second->setWeight(weight, upload_bake); return TRUE; } return FALSE; @@ -278,15 +284,15 @@ BOOL LLCharacter::setVisualParamWeight(LLVisualParam* which_param, F32 weight, B //----------------------------------------------------------------------------- // setVisualParamWeight() //----------------------------------------------------------------------------- -BOOL LLCharacter::setVisualParamWeight(const char* param_name, F32 weight, BOOL set_by_user) +BOOL LLCharacter::setVisualParamWeight(const char* param_name, F32 weight, BOOL upload_bake) { - LLString tname(param_name); - LLString::toLower(tname); + std::string tname(param_name); + LLStringUtil::toLower(tname); char *tableptr = sVisualParamNames.checkString(tname); - VisualParamNameMap_t::iterator name_iter = mVisualParamNameMap.find(tableptr); + visual_param_name_map_t::iterator name_iter = mVisualParamNameMap.find(tableptr); if (name_iter != mVisualParamNameMap.end()) { - name_iter->second->setWeight(weight, set_by_user); + name_iter->second->setWeight(weight, upload_bake); return TRUE; } llwarns << "LLCharacter::setVisualParamWeight() Invalid visual parameter: " << param_name << llendl; @@ -296,12 +302,12 @@ BOOL LLCharacter::setVisualParamWeight(const char* param_name, F32 weight, BOOL //----------------------------------------------------------------------------- // setVisualParamWeight() //----------------------------------------------------------------------------- -BOOL LLCharacter::setVisualParamWeight(S32 index, F32 weight, BOOL set_by_user) +BOOL LLCharacter::setVisualParamWeight(S32 index, F32 weight, BOOL upload_bake) { - VisualParamIndexMap_t::iterator index_iter = mVisualParamIndexMap.find(index); + visual_param_index_map_t::iterator index_iter = mVisualParamIndexMap.find(index); if (index_iter != mVisualParamIndexMap.end()) { - index_iter->second->setWeight(weight, set_by_user); + index_iter->second->setWeight(weight, upload_bake); return TRUE; } llwarns << "LLCharacter::setVisualParamWeight() Invalid visual parameter index: " << index << llendl; @@ -314,7 +320,7 @@ BOOL LLCharacter::setVisualParamWeight(S32 index, F32 weight, BOOL set_by_user) F32 LLCharacter::getVisualParamWeight(LLVisualParam *which_param) { S32 index = which_param->getID(); - VisualParamIndexMap_t::iterator index_iter = mVisualParamIndexMap.find(index); + visual_param_index_map_t::iterator index_iter = mVisualParamIndexMap.find(index); if (index_iter != mVisualParamIndexMap.end()) { return index_iter->second->getWeight(); @@ -331,10 +337,10 @@ F32 LLCharacter::getVisualParamWeight(LLVisualParam *which_param) //----------------------------------------------------------------------------- F32 LLCharacter::getVisualParamWeight(const char* param_name) { - LLString tname(param_name); - LLString::toLower(tname); + std::string tname(param_name); + LLStringUtil::toLower(tname); char *tableptr = sVisualParamNames.checkString(tname); - VisualParamNameMap_t::iterator name_iter = mVisualParamNameMap.find(tableptr); + visual_param_name_map_t::iterator name_iter = mVisualParamNameMap.find(tableptr); if (name_iter != mVisualParamNameMap.end()) { return name_iter->second->getWeight(); @@ -348,7 +354,7 @@ F32 LLCharacter::getVisualParamWeight(const char* param_name) //----------------------------------------------------------------------------- F32 LLCharacter::getVisualParamWeight(S32 index) { - VisualParamIndexMap_t::iterator index_iter = mVisualParamIndexMap.find(index); + visual_param_index_map_t::iterator index_iter = mVisualParamIndexMap.find(index); if (index_iter != mVisualParamIndexMap.end()) { return index_iter->second->getWeight(); @@ -369,7 +375,7 @@ void LLCharacter::clearVisualParamWeights() param; param = getNextVisualParam()) { - if (param->getGroup() == VISUAL_PARAM_GROUP_TWEAKABLE) + if (param->isTweakable()) { param->setWeight( param->getDefaultWeight(), FALSE ); } @@ -381,10 +387,10 @@ void LLCharacter::clearVisualParamWeights() //----------------------------------------------------------------------------- LLVisualParam* LLCharacter::getVisualParam(const char *param_name) { - LLString tname(param_name); - LLString::toLower(tname); + std::string tname(param_name); + LLStringUtil::toLower(tname); char *tableptr = sVisualParamNames.checkString(tname); - VisualParamNameMap_t::iterator name_iter = mVisualParamNameMap.find(tableptr); + visual_param_name_map_t::iterator name_iter = mVisualParamNameMap.find(tableptr); if (name_iter != mVisualParamNameMap.end()) { return name_iter->second; @@ -399,7 +405,7 @@ LLVisualParam* LLCharacter::getVisualParam(const char *param_name) void LLCharacter::addSharedVisualParam(LLVisualParam *param) { S32 index = param->getID(); - VisualParamIndexMap_t::iterator index_iter = mVisualParamIndexMap.find(index); + 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; @@ -426,28 +432,28 @@ void LLCharacter::addVisualParam(LLVisualParam *param) { S32 index = param->getID(); // Add Index map - std::pair<VisualParamIndexMap_t::iterator, bool> idxres; - idxres = mVisualParamIndexMap.insert(VisualParamIndexMap_t::value_type(index, param)); + 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) { llwarns << "Visual parameter " << param->getName() << " already exists with same ID as " << param->getName() << llendl; - VisualParamIndexMap_t::iterator index_iter = idxres.first; + visual_param_index_map_t::iterator index_iter = idxres.first; index_iter->second = param; } if (param->getInfo()) { // Add name map - LLString tname(param->getName()); - LLString::toLower(tname); + std::string tname(param->getName()); + LLStringUtil::toLower(tname); char *tableptr = sVisualParamNames.addString(tname); - std::pair<VisualParamNameMap_t::iterator, bool> nameres; - nameres = mVisualParamNameMap.insert(VisualParamNameMap_t::value_type(tableptr, param)); + 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 - VisualParamNameMap_t::iterator name_iter = nameres.first; + visual_param_name_map_t::iterator name_iter = nameres.first; name_iter->second = param; } } @@ -478,7 +484,7 @@ void LLCharacter::updateVisualParams() LLAnimPauseRequest LLCharacter::requestPause() { - mMotionController.pause(); + mMotionController.pauseAllMotions(); return mPauseRequest; } diff --git a/indra/llcharacter/llcharacter.h b/indra/llcharacter/llcharacter.h index a5719b0685..a6347fcc3c 100644 --- a/indra/llcharacter/llcharacter.h +++ b/indra/llcharacter/llcharacter.h @@ -2,30 +2,25 @@ * @file llcharacter.h * @brief Implementation of LLCharacter class. * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2007, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlife.com/developers/opensource/gplv2 + * 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. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at http://secondlife.com/developers/opensource/flossexception + * 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. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * 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 * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -41,7 +36,7 @@ #include "llmotioncontroller.h" #include "llvisualparam.h" #include "string_table.h" -#include "llmemory.h" +#include "llpointer.h" #include "llthread.h" class LLPolyMesh; @@ -137,13 +132,16 @@ public: //------------------------------------------------------------------------- // registers a motion with the character // returns true if successfull - BOOL addMotion( const LLUUID& id, LLMotionConstructor create ); + BOOL registerMotion( const LLUUID& id, LLMotionConstructor create ); void removeMotion( const LLUUID& id ); - // returns an instance of a registered motion + // 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); @@ -161,12 +159,16 @@ public: virtual void requestStopMotion( LLMotion* motion ); // periodic update function, steps the motion controller - void updateMotion(BOOL force_update = FALSE); + enum e_update_t { NORMAL_UPDATE, HIDDEN_UPDATE, FORCE_UPDATE }; + void updateMotions(e_update_t update_type); LLAnimPauseRequest requestPause(); - BOOL areAnimationsPaused() { return mMotionController.isPaused(); } + 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. @@ -195,16 +197,16 @@ public: void addVisualParam(LLVisualParam *param); void addSharedVisualParam(LLVisualParam *param); - BOOL setVisualParamWeight(LLVisualParam *which_param, F32 weight, BOOL set_by_user = FALSE ); - BOOL setVisualParamWeight(const char* param_name, F32 weight, BOOL set_by_user = FALSE ); - BOOL setVisualParamWeight(S32 index, F32 weight, BOOL set_by_user = FALSE ); + virtual BOOL setVisualParamWeight(LLVisualParam *which_param, F32 weight, BOOL upload_bake = FALSE ); + virtual BOOL setVisualParamWeight(const char* param_name, F32 weight, BOOL upload_bake = FALSE ); + virtual BOOL setVisualParamWeight(S32 index, F32 weight, BOOL upload_bake = FALSE ); // 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 0 + // set all morph weights to defaults void clearVisualParamWeights(); // visual parameter accessors @@ -220,14 +222,29 @@ public: return (mCurIterator++)->second; } - LLVisualParam* getVisualParam(S32 id) + S32 getVisualParamCountInGroup(const EVisualParamGroup group) const { - VisualParamIndexMap_t::iterator iter = mVisualParamIndexMap.find(id); + S32 rtn = 0; + for (visual_param_index_map_t::const_iterator iter = mVisualParamIndexMap.begin(); + iter != mVisualParamIndexMap.end(); + /**/ ) + { + if ((iter++)->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) { - VisualParamIndexMap_t::iterator iter; + visual_param_index_map_t::iterator iter; for (iter = mVisualParamIndexMap.begin(); iter != mVisualParamIndexMap.end(); iter++) { if (iter->second == id) @@ -235,11 +252,11 @@ public: } return 0; } - S32 getVisualParamCount() { return (S32)mVisualParamIndexMap.size(); } + S32 getVisualParamCount() const { return (S32)mVisualParamIndexMap.size(); } LLVisualParam* getVisualParam(const char *name); - ESex getSex() { return mSex; } + ESex getSex() const { return mSex; } void setSex( ESex sex ) { mSex = sex; } U32 getAppearanceSerialNum() const { return mAppearanceSerialNum; } @@ -265,11 +282,12 @@ protected: private: // visual parameter stuff - typedef std::map<S32, LLVisualParam *> VisualParamIndexMap_t; - VisualParamIndexMap_t mVisualParamIndexMap; - VisualParamIndexMap_t::iterator mCurIterator; - typedef std::map<char *, LLVisualParam *> VisualParamNameMap_t; - VisualParamNameMap_t mVisualParamNameMap; + 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; static LLStringTable sVisualParamNames; }; diff --git a/indra/llcharacter/lleditingmotion.cpp b/indra/llcharacter/lleditingmotion.cpp index 34fb6c423a..66b3c2bd25 100644 --- a/indra/llcharacter/lleditingmotion.cpp +++ b/indra/llcharacter/lleditingmotion.cpp @@ -2,30 +2,25 @@ * @file lleditingmotion.cpp * @brief Implementation of LLEditingMotion class. * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2007, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlife.com/developers/opensource/gplv2 + * 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. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at http://secondlife.com/developers/opensource/flossexception + * 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. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * 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 * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ diff --git a/indra/llcharacter/lleditingmotion.h b/indra/llcharacter/lleditingmotion.h index 60ec4a34d9..7b1c8bb059 100644 --- a/indra/llcharacter/lleditingmotion.h +++ b/indra/llcharacter/lleditingmotion.h @@ -2,30 +2,25 @@ * @file lleditingmotion.h * @brief Implementation of LLEditingMotion class. * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2007, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlife.com/developers/opensource/gplv2 + * 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. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at http://secondlife.com/developers/opensource/flossexception + * 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. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * 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 * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ diff --git a/indra/llcharacter/llgesture.cpp b/indra/llcharacter/llgesture.cpp index ee2396321d..c23694639e 100644 --- a/indra/llcharacter/llgesture.cpp +++ b/indra/llcharacter/llgesture.cpp @@ -1,30 +1,25 @@ /** * @file llgesture.cpp * - * $LicenseInfo:firstyear=2002&license=viewergpl$ - * - * Copyright (c) 2002-2007, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2002&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlife.com/developers/opensource/gplv2 + * 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. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at http://secondlife.com/developers/opensource/flossexception + * 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. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * 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 * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -103,7 +98,7 @@ BOOL LLGesture::trigger(KEY key, MASK mask) } -BOOL LLGesture::trigger(const LLString &trigger_string) +BOOL LLGesture::trigger(const std::string& trigger_string) { llwarns << "Parent class trigger called: you probably didn't mean this." << llendl; return FALSE; @@ -191,11 +186,11 @@ LLGestureList::LLGestureList() mList.put(gesture); gesture = new LLGesture(KEY_F4, MASK_NONE, "/boogie", - LLUUID::null, "dance4", LLString::null ); + LLUUID::null, "dance4", LLStringUtil::null ); mList.put(gesture); gesture = new LLGesture(KEY_F5, MASK_SHIFT, "/tongue", - LLUUID::null, "Express_Tongue_Out", LLString::null ); + LLUUID::null, "Express_Tongue_Out", LLStringUtil::null ); mList.put(gesture); */ } @@ -219,9 +214,9 @@ void LLGestureList::deleteAll() // Iterates through space delimited tokens in string, triggering any gestures found. // Generates a revised string that has the found tokens replaced by their replacement strings // and (as a minor side effect) has multiple spaces in a row replaced by single spaces. -BOOL LLGestureList::triggerAndReviseString(const LLString &string, LLString* revised_string) +BOOL LLGestureList::triggerAndReviseString(const std::string &string, std::string* revised_string) { - LLString tokenized = string; + std::string tokenized = string; BOOL found_gestures = FALSE; BOOL first_token = TRUE; @@ -237,8 +232,8 @@ BOOL LLGestureList::triggerAndReviseString(const LLString &string, LLString* rev if( !found_gestures ) // Only pay attention to the first gesture in the string. { - LLString cur_token_lower = *token_iter; - LLString::toLower(cur_token_lower); + std::string cur_token_lower = *token_iter; + LLStringUtil::toLower(cur_token_lower); for (S32 i = 0; i < mList.count(); i++) { @@ -254,15 +249,15 @@ BOOL LLGestureList::triggerAndReviseString(const LLString &string, LLString* rev // Don't muck with the user's capitalization if we don't have to. const std::string& output = gesture->getOutputString(); - LLString output_lower = LLString(output.c_str()); - LLString::toLower(output_lower); + std::string output_lower = std::string(output.c_str()); + LLStringUtil::toLower(output_lower); if( cur_token_lower == output_lower ) { revised_string->append(*token_iter); } else { - revised_string->append(output.c_str()); + revised_string->append(output); } } @@ -303,7 +298,7 @@ BOOL LLGestureList::trigger(KEY key, MASK mask) } else { - llwarns << "NULL gesture in gesture list (" << i << ")" << llendl + llwarns << "NULL gesture in gesture list (" << i << ")" << llendl; } } return FALSE; diff --git a/indra/llcharacter/llgesture.h b/indra/llcharacter/llgesture.h index 34fdcd01c4..66b618c473 100644 --- a/indra/llcharacter/llgesture.h +++ b/indra/llcharacter/llgesture.h @@ -3,30 +3,25 @@ * @brief A gesture is a combination of a triggering chat phrase or * key, a sound, an animation, and a chat string. * - * $LicenseInfo:firstyear=2002&license=viewergpl$ - * - * Copyright (c) 2002-2007, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2002&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlife.com/developers/opensource/gplv2 + * 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. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at http://secondlife.com/developers/opensource/flossexception + * 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. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * 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 * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -64,7 +59,7 @@ public: virtual BOOL trigger(KEY key, MASK mask); // Triggers if case-insensitive substring matches (assumes string is lowercase) - virtual BOOL trigger(const LLString &string); + virtual BOOL trigger(const std::string &string); // non-endian-neutral serialization U8 *serialize(U8 *buffer) const; @@ -93,7 +88,7 @@ public: BOOL trigger(KEY key, MASK mask); // Triggers if substring matches and generates revised string. - BOOL triggerAndReviseString(const LLString &string, LLString* revised_string); + BOOL triggerAndReviseString(const std::string &string, std::string* revised_string); // Used for construction from UI S32 count() const { return mList.count(); } diff --git a/indra/llcharacter/llhandmotion.cpp b/indra/llcharacter/llhandmotion.cpp index 511ccc7a88..63937d8255 100644 --- a/indra/llcharacter/llhandmotion.cpp +++ b/indra/llcharacter/llhandmotion.cpp @@ -2,30 +2,25 @@ * @file llhandmotion.cpp * @brief Implementation of LLHandMotion class. * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2007, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlife.com/developers/opensource/gplv2 + * 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. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at http://secondlife.com/developers/opensource/flossexception + * 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. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * 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 * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -201,16 +196,16 @@ void LLHandMotion::onDeactivate() //----------------------------------------------------------------------------- // LLHandMotion::getHandPoseName() //----------------------------------------------------------------------------- -LLString LLHandMotion::getHandPoseName(eHandPose pose) +std::string LLHandMotion::getHandPoseName(eHandPose pose) { if ((S32)pose < LLHandMotion::NUM_HAND_POSES && (S32)pose >= 0) { - return gHandPoseNames[pose]; + return std::string(gHandPoseNames[pose]); } - return ""; + return LLStringUtil::null; } -LLHandMotion::eHandPose LLHandMotion::getHandPose(LLString posename) +LLHandMotion::eHandPose LLHandMotion::getHandPose(std::string posename) { for (S32 pose = 0; pose < LLHandMotion::NUM_HAND_POSES; ++pose) { diff --git a/indra/llcharacter/llhandmotion.h b/indra/llcharacter/llhandmotion.h index 662800784b..08de7056c8 100644 --- a/indra/llcharacter/llhandmotion.h +++ b/indra/llcharacter/llhandmotion.h @@ -2,30 +2,25 @@ * @file llhandmotion.h * @brief Implementation of LLHandMotion class. * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2007, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlife.com/developers/opensource/gplv2 + * 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. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at http://secondlife.com/developers/opensource/flossexception + * 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. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * 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 * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -126,8 +121,8 @@ public: virtual BOOL canDeprecate() { return FALSE; } - static LLString getHandPoseName(eHandPose pose); - static eHandPose getHandPose(LLString posename); + static std::string getHandPoseName(eHandPose pose); + static eHandPose getHandPose(std::string posename); public: //------------------------------------------------------------------------- diff --git a/indra/llcharacter/llheadrotmotion.cpp b/indra/llcharacter/llheadrotmotion.cpp index 7e25cc457e..15a58a8389 100644 --- a/indra/llcharacter/llheadrotmotion.cpp +++ b/indra/llcharacter/llheadrotmotion.cpp @@ -2,30 +2,25 @@ * @file llheadrotmotion.cpp * @brief Implementation of LLHeadRotMotion class. * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2007, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlife.com/developers/opensource/gplv2 + * 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. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at http://secondlife.com/developers/opensource/flossexception + * 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. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * 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 * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -250,10 +245,13 @@ BOOL LLHeadRotMotion::onUpdate(F32 time, U8* joint_mask) mLastHeadRot = head_rot_local; // Set the head rotation. - 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)); + 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; } diff --git a/indra/llcharacter/llheadrotmotion.h b/indra/llcharacter/llheadrotmotion.h index 57c4db5dad..569dbef2dd 100644 --- a/indra/llcharacter/llheadrotmotion.h +++ b/indra/llcharacter/llheadrotmotion.h @@ -2,30 +2,25 @@ * @file llheadrotmotion.h * @brief Implementation of LLHeadRotMotion class. * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2007, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlife.com/developers/opensource/gplv2 + * 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. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at http://secondlife.com/developers/opensource/flossexception + * 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. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * 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 * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ diff --git a/indra/llcharacter/lljoint.cpp b/indra/llcharacter/lljoint.cpp index 00ec8e5068..5d750c6c96 100644 --- a/indra/llcharacter/lljoint.cpp +++ b/indra/llcharacter/lljoint.cpp @@ -2,30 +2,25 @@ * @file lljoint.cpp * @brief Implementation of LLJoint class. * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2007, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlife.com/developers/opensource/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at http://secondlife.com/developers/opensource/flossexception + * 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. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * 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. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * 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$ */ @@ -69,6 +64,7 @@ LLJoint::LLJoint(const std::string &name, LLJoint *parent) mXform.setScaleChildOffset(TRUE); mXform.setScale(LLVector3(1.0f, 1.0f, 1.0f)); mDirtyFlags = MATRIX_DIRTY | ROTATION_DIRTY | POSITION_DIRTY; + mUpdateXform = FALSE; mJointNum = 0; setName(name); @@ -189,11 +185,12 @@ void LLJoint::removeChild(LLJoint* joint) child_list_t::iterator iter = std::find(mChildren.begin(), mChildren.end(), joint); if (iter != mChildren.end()) { - this->mChildren.erase(iter); + mChildren.erase(iter); + + joint->mXform.setParent(NULL); + joint->mParent = NULL; + joint->touch(); } - joint->mXform.setParent(NULL); - joint->mParent = NULL; - joint->touch(); } diff --git a/indra/llcharacter/lljoint.h b/indra/llcharacter/lljoint.h index 8ca8118e4c..8c8e5930fb 100644 --- a/indra/llcharacter/lljoint.h +++ b/indra/llcharacter/lljoint.h @@ -2,30 +2,25 @@ * @file lljoint.h * @brief Implementation of LLJoint class. * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2007, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlife.com/developers/opensource/gplv2 + * 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. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at http://secondlife.com/developers/opensource/flossexception + * 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. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * 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 * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -173,7 +168,7 @@ public: void clampRotation(LLQuaternion old_rot, LLQuaternion new_rot); - virtual BOOL isAnimatable() { return TRUE; } + virtual BOOL isAnimatable() const { return TRUE; } S32 getJointNum() const { return mJointNum; } void setJointNum(S32 joint_num) { mJointNum = joint_num; } diff --git a/indra/llcharacter/lljointsolverrp3.cpp b/indra/llcharacter/lljointsolverrp3.cpp index 0237f1ed62..1331900791 100644 --- a/indra/llcharacter/lljointsolverrp3.cpp +++ b/indra/llcharacter/lljointsolverrp3.cpp @@ -2,30 +2,25 @@ * @file lljointsolverrp3.cpp * @brief Implementation of LLJointSolverRP3 class. * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2007, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlife.com/developers/opensource/gplv2 + * 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. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at http://secondlife.com/developers/opensource/flossexception + * 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. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * 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 * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -210,7 +205,7 @@ void LLJointSolverRP3::solve() //------------------------------------------------------------------------- LLVector3 abacCompOrthoVec = abVec - acVec * ((abVec * acVec)/(acVec * acVec)); -// llinfos << "abacCompOrthoVec : " << abacCompOrthoVec << llendl +// llinfos << "abacCompOrthoVec : " << abacCompOrthoVec << llendl; //------------------------------------------------------------------------- // compute the normal of the original ABC plane (and store for later) diff --git a/indra/llcharacter/lljointsolverrp3.h b/indra/llcharacter/lljointsolverrp3.h index 24d5b6c83b..88b5d08710 100644 --- a/indra/llcharacter/lljointsolverrp3.h +++ b/indra/llcharacter/lljointsolverrp3.h @@ -2,30 +2,25 @@ * @file lljointsolverrp3.h * @brief Implementation of LLJointSolverRP3 class * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2007, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlife.com/developers/opensource/gplv2 + * 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. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at http://secondlife.com/developers/opensource/flossexception + * 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. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * 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 * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ diff --git a/indra/llcharacter/lljointstate.h b/indra/llcharacter/lljointstate.h index ab4ecc8aa7..b9c91f80b5 100644 --- a/indra/llcharacter/lljointstate.h +++ b/indra/llcharacter/lljointstate.h @@ -2,30 +2,25 @@ * @file lljointstate.h * @brief Implementation of LLJointState class. * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2007, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlife.com/developers/opensource/gplv2 + * 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. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at http://secondlife.com/developers/opensource/flossexception + * 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. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * 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 * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -36,7 +31,7 @@ // Header Files //----------------------------------------------------------------------------- #include "lljoint.h" -#include "llmemory.h" +#include "llrefcount.h" //----------------------------------------------------------------------------- // class LLJointState diff --git a/indra/llcharacter/llkeyframefallmotion.cpp b/indra/llcharacter/llkeyframefallmotion.cpp index 13308f4e4a..60ab2e9929 100644 --- a/indra/llcharacter/llkeyframefallmotion.cpp +++ b/indra/llcharacter/llkeyframefallmotion.cpp @@ -2,30 +2,25 @@ * @file llkeyframefallmotion.cpp * @brief Implementation of LLKeyframeFallMotion class. * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2007, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlife.com/developers/opensource/gplv2 + * 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. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at http://secondlife.com/developers/opensource/flossexception + * 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. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * 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 * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ diff --git a/indra/llcharacter/llkeyframefallmotion.h b/indra/llcharacter/llkeyframefallmotion.h index 618a169324..7f0a2fdda2 100644 --- a/indra/llcharacter/llkeyframefallmotion.h +++ b/indra/llcharacter/llkeyframefallmotion.h @@ -2,30 +2,25 @@ * @file llkeyframefallmotion.h * @brief Implementation of LLKeframeWalkMotion class. * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2007, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlife.com/developers/opensource/gplv2 + * 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. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at http://secondlife.com/developers/opensource/flossexception + * 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. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * 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 * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ diff --git a/indra/llcharacter/llkeyframemotion.cpp b/indra/llcharacter/llkeyframemotion.cpp index 91d96904ba..5b0867524e 100644 --- a/indra/llcharacter/llkeyframemotion.cpp +++ b/indra/llcharacter/llkeyframemotion.cpp @@ -2,30 +2,25 @@ * @file llkeyframemotion.cpp * @brief Implementation of LLKeyframeMotion class. * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2007, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlife.com/developers/opensource/gplv2 + * 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. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at http://secondlife.com/developers/opensource/flossexception + * 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. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * 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 * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -71,6 +66,15 @@ 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) { } @@ -458,7 +462,7 @@ LLMotion *LLKeyframeMotion::create(const LLUUID &id) //----------------------------------------------------------------------------- LLPointer<LLJointState>& LLKeyframeMotion::getJointState(U32 index) { - llassert_always (index < (S32)mJointStates.size()); + llassert_always (index < mJointStates.size()); return mJointStates[index]; } @@ -467,7 +471,7 @@ LLPointer<LLJointState>& LLKeyframeMotion::getJointState(U32 index) //----------------------------------------------------------------------------- LLJoint* LLKeyframeMotion::getJoint(U32 index) { - llassert_always (index < (S32)mJointStates.size()); + llassert_always (index < mJointStates.size()); LLJoint* joint = mJointStates[index]->getJoint(); llassert_always (joint); return joint; @@ -646,9 +650,14 @@ BOOL LLKeyframeMotion::setupPose() BOOL LLKeyframeMotion::onActivate() { // If the keyframe anim has an associated emote, trigger it. - if( mEmoteName.length() > 0 ) + if( mJointMotionList->mEmoteName.length() > 0 ) { - mCharacter->startMotion( gAnimLibrary.stringToAnimState(mEmoteName.c_str()) ); + 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; @@ -852,7 +861,7 @@ void LLKeyframeMotion::activateConstraint(JointConstraint* constraint) S32 joint_num; // grab ground position if we need to - if (shared_data->mConstraintTargetType == TYPE_GROUND) + if (shared_data->mConstraintTargetType == CONSTRAINT_TARGET_TYPE_GROUND) { LLVector3 source_pos = mCharacter->getVolumePos(shared_data->mSourceConstraintVolume, shared_data->mSourceConstraintOffset); LLVector3 ground_pos_agent; @@ -879,7 +888,7 @@ void LLKeyframeMotion::deactivateConstraint(JointConstraint *constraintp) constraintp->mSourceVolume->mUpdateXform = FALSE; } - if (!constraintp->mSharedData->mConstraintTargetType == TYPE_GROUND) + if (!constraintp->mSharedData->mConstraintTargetType == CONSTRAINT_TARGET_TYPE_GROUND) { if (constraintp->mTargetVolume) { @@ -949,11 +958,11 @@ void LLKeyframeMotion::applyConstraint(JointConstraint* constraint, F32 time, U8 switch(shared_data->mConstraintTargetType) { - case TYPE_GROUND: + case CONSTRAINT_TARGET_TYPE_GROUND: target_pos = mCharacter->getPosAgentFromGlobal(constraint->mGroundPos); // llinfos << "Target Pos " << constraint->mGroundPos << " on " << mCharacter->findCollisionVolume(shared_data->mSourceConstraintVolume)->getName() << llendl; break; - case TYPE_BODY: + case CONSTRAINT_TARGET_TYPE_BODY: target_pos = mCharacter->getVolumePos(shared_data->mTargetConstraintVolume, shared_data->mTargetConstraintOffset); break; default: @@ -964,14 +973,14 @@ void LLKeyframeMotion::applyConstraint(JointConstraint* constraint, F32 time, U8 LLJoint *source_jointp = NULL; LLJoint *target_jointp = NULL; - if (shared_data->mConstraintType == TYPE_PLANE) + if (shared_data->mConstraintType == CONSTRAINT_TYPE_PLANE) { switch(shared_data->mConstraintTargetType) { - case TYPE_GROUND: + case CONSTRAINT_TARGET_TYPE_GROUND: norm = constraint->mGroundNorm; break; - case TYPE_BODY: + case CONSTRAINT_TARGET_TYPE_BODY: target_jointp = mCharacter->findCollisionVolume(shared_data->mTargetConstraintVolume); if (target_jointp) { @@ -1198,7 +1207,7 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp) if (!dp.unpackS32(temp_priority, "base_priority")) { - llwarns << "can't read priority" << llendl; + llwarns << "can't read animation base_priority" << llendl; return FALSE; } mJointMotionList->mBasePriority = (LLJoint::JointPriority) temp_priority; @@ -1208,6 +1217,11 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp) mJointMotionList->mBasePriority = (LLJoint::JointPriority)((int)LLJoint::ADDITIVE_PRIORITY-1); mJointMotionList->mMaxPriority = mJointMotionList->mBasePriority; } + else if (mJointMotionList->mBasePriority < LLJoint::USE_MOTION_PRIORITY) + { + llwarns << "bad animation base_priority " << mJointMotionList->mBasePriority << llendl; + return FALSE; + } //------------------------------------------------------------------------- // get duration @@ -1217,26 +1231,41 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp) llwarns << "can't read duration" << llendl; return FALSE; } + + if (mJointMotionList->mDuration > MAX_ANIM_DURATION || + !llfinite(mJointMotionList->mDuration)) + { + llwarns << "invalid animation duration" << llendl; + return FALSE; + } //------------------------------------------------------------------------- // get emote (optional) //------------------------------------------------------------------------- - if (!dp.unpackString(mEmoteName, "emote_name")) + if (!dp.unpackString(mJointMotionList->mEmoteName, "emote_name")) { llwarns << "can't read optional_emote_animation" << llendl; return FALSE; } + if(mJointMotionList->mEmoteName==mID.asString()) + { + llwarns << "Malformed animation mEmoteName==mID" << llendl; + return FALSE; + } + //------------------------------------------------------------------------- // get loop //------------------------------------------------------------------------- - if (!dp.unpackF32(mJointMotionList->mLoopInPoint, "loop_in_point")) + if (!dp.unpackF32(mJointMotionList->mLoopInPoint, "loop_in_point") || + !llfinite(mJointMotionList->mLoopInPoint)) { llwarns << "can't read loop point" << llendl; return FALSE; } - if (!dp.unpackF32(mJointMotionList->mLoopOutPoint, "loop_out_point")) + if (!dp.unpackF32(mJointMotionList->mLoopOutPoint, "loop_out_point") || + !llfinite(mJointMotionList->mLoopOutPoint)) { llwarns << "can't read loop point" << llendl; return FALSE; @@ -1251,13 +1280,15 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp) //------------------------------------------------------------------------- // get easeIn and easeOut //------------------------------------------------------------------------- - if (!dp.unpackF32(mJointMotionList->mEaseInDuration, "ease_in_duration")) + if (!dp.unpackF32(mJointMotionList->mEaseInDuration, "ease_in_duration") || + !llfinite(mJointMotionList->mEaseInDuration)) { llwarns << "can't read easeIn" << llendl; return FALSE; } - if (!dp.unpackF32(mJointMotionList->mEaseOutDuration, "ease_out_duration")) + if (!dp.unpackF32(mJointMotionList->mEaseOutDuration, "ease_out_duration") || + !llfinite(mJointMotionList->mEaseOutDuration)) { llwarns << "can't read easeOut" << llendl; return FALSE; @@ -1272,6 +1303,13 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp) llwarns << "can't read hand pose" << llendl; return FALSE; } + + if(word > LLHandMotion::NUM_HAND_POSES) + { + llwarns << "invalid LLHandMotion::eHandPose index: " << word << llendl; + return FALSE; + } + mJointMotionList->mHandPose = (LLHandMotion::eHandPose)word; //------------------------------------------------------------------------- @@ -1315,7 +1353,13 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp) llwarns << "can't read joint name" << llendl; return FALSE; } - + + if (joint_name == "mScreen" || joint_name == "mRoot") + { + llwarns << "attempted to animate special " << joint_name << " joint" << llendl; + return FALSE; + } + //--------------------------------------------------------------------- // find the corresponding joint //--------------------------------------------------------------------- @@ -1334,7 +1378,7 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp) LLPointer<LLJointState> joint_state = new LLJointState; mJointStates.push_back(joint_state); - joint_state->setJoint( joint ); + joint_state->setJoint( joint ); // note: can accept NULL joint_state->setUsage( 0 ); //--------------------------------------------------------------------- @@ -1346,10 +1390,16 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp) llwarns << "can't read joint priority." << llendl; return FALSE; } + + if (joint_priority < LLJoint::USE_MOTION_PRIORITY) + { + llwarns << "joint priority unknown - too low." << llendl; + return FALSE; + } joint_motion->mPriority = (LLJoint::JointPriority)joint_priority; if (joint_priority != LLJoint::USE_MOTION_PRIORITY && - joint_priority > mJointMotionList->mMaxPriority) + joint_priority > mJointMotionList->mMaxPriority) { mJointMotionList->mMaxPriority = (LLJoint::JointPriority)joint_priority; } @@ -1359,7 +1409,7 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp) //--------------------------------------------------------------------- // scan rotation curve header //--------------------------------------------------------------------- - if (!dp.unpackS32(joint_motion->mRotationCurve.mNumKeys, "num_rot_keys")) + if (!dp.unpackS32(joint_motion->mRotationCurve.mNumKeys, "num_rot_keys") || joint_motion->mRotationCurve.mNumKeys < 0) { llwarns << "can't read number of rotation keys" << llendl; return FALSE; @@ -1383,7 +1433,8 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp) if (old_version) { - if (!dp.unpackF32(time, "time")) + if (!dp.unpackF32(time, "time") || + !llfinite(time)) { llwarns << "can't read rotation key (" << k << ")" << llendl; return FALSE; @@ -1399,6 +1450,12 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp) } time = U16_to_F32(time_short, 0.f, mJointMotionList->mDuration); + + if (time < 0 || time > mJointMotionList->mDuration) + { + llwarns << "invalid frame time" << llendl; + return FALSE; + } } RotationKey rot_key; @@ -1410,7 +1467,7 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp) if (old_version) { - success = dp.unpackVector3(rot_angles, "rot_angles"); + success = dp.unpackVector3(rot_angles, "rot_angles") && rot_angles.isFinite(); LLQuaternion::Order ro = StringToOrder("ZYX"); rot_key.mRotation = mayaQ(rot_angles.mV[VX], rot_angles.mV[VY], rot_angles.mV[VZ], ro); @@ -1428,6 +1485,12 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp) rot_key.mRotation.unpackFromVector3(rot_vec); } + if( !(rot_key.mRotation.isFinite()) ) + { + llwarns << "non-finite angle in rotation key" << llendl; + success = FALSE; + } + if (!success) { llwarns << "can't read rotation key (" << k << ")" << llendl; @@ -1440,7 +1503,7 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp) //--------------------------------------------------------------------- // scan position curve header //--------------------------------------------------------------------- - if (!dp.unpackS32(joint_motion->mPositionCurve.mNumKeys, "num_pos_keys")) + if (!dp.unpackS32(joint_motion->mPositionCurve.mNumKeys, "num_pos_keys") || joint_motion->mPositionCurve.mNumKeys < 0) { llwarns << "can't read number of position keys" << llendl; return FALSE; @@ -1464,7 +1527,8 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp) if (old_version) { - if (!dp.unpackF32(pos_key.mTime, "time")) + if (!dp.unpackF32(pos_key.mTime, "time") || + !llfinite(pos_key.mTime)) { llwarns << "can't read position key (" << k << ")" << llendl; return FALSE; @@ -1499,7 +1563,13 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp) 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()) ) + { + llwarns << "non-finite position in key" << llendl; + success = FALSE; + } + if (!success) { llwarns << "can't read position key (" << k << ")" << llendl; @@ -1527,9 +1597,9 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp) return FALSE; } - if (num_constraints > MAX_CONSTRAINTS) + if (num_constraints > MAX_CONSTRAINTS || num_constraints < 0) { - llwarns << "Too many constraints...ignoring" << llendl; + llwarns << "Bad number of constraints... ignoring: " << num_constraints << llendl; } else { @@ -1551,16 +1621,30 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp) } constraintp->mChainLength = (S32) byte; + if((U32)constraintp->mChainLength > mJointMotionList->getNumJointMotions()) + { + llwarns << "invalid constraint chain length" << llendl; + delete constraintp; + return FALSE; + } + if (!dp.unpackU8(byte, "constraint_type")) { llwarns << "can't read constraint type" << llendl; delete constraintp; return FALSE; } + + if( byte >= NUM_CONSTRAINT_TYPES ) + { + llwarns << "invalid constraint type" << llendl; + delete constraintp; + return FALSE; + } constraintp->mConstraintType = (EConstraintType)byte; const S32 BIN_DATA_LENGTH = 16; - U8 bin_data[BIN_DATA_LENGTH]; + U8 bin_data[BIN_DATA_LENGTH+1]; if (!dp.unpackBinaryDataFixed(bin_data, BIN_DATA_LENGTH, "source_volume")) { llwarns << "can't read source volume name" << llendl; @@ -1568,7 +1652,7 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp) return FALSE; } - bin_data[BIN_DATA_LENGTH-1] = 0; // Ensure null termination + bin_data[BIN_DATA_LENGTH] = 0; // Ensure null termination str = (char*)bin_data; constraintp->mSourceConstraintVolume = mCharacter->getCollisionVolumeID(str); @@ -1578,7 +1662,14 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp) delete constraintp; return FALSE; } - + + if( !(constraintp->mSourceConstraintOffset.isFinite()) ) + { + llwarns << "non-finite constraint source offset" << llendl; + delete constraintp; + return FALSE; + } + if (!dp.unpackBinaryDataFixed(bin_data, BIN_DATA_LENGTH, "target_volume")) { llwarns << "can't read target volume name" << llendl; @@ -1586,16 +1677,16 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp) return FALSE; } - bin_data[BIN_DATA_LENGTH-1] = 0; // Ensure null termination + bin_data[BIN_DATA_LENGTH] = 0; // Ensure null termination str = (char*)bin_data; if (str == "GROUND") { // constrain to ground - constraintp->mConstraintTargetType = TYPE_GROUND; + constraintp->mConstraintTargetType = CONSTRAINT_TARGET_TYPE_GROUND; } else { - constraintp->mConstraintTargetType = TYPE_BODY; + constraintp->mConstraintTargetType = CONSTRAINT_TARGET_TYPE_BODY; constraintp->mTargetConstraintVolume = mCharacter->getCollisionVolumeID(str); } @@ -1606,6 +1697,13 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp) return FALSE; } + if( !(constraintp->mTargetConstraintOffset.isFinite()) ) + { + llwarns << "non-finite constraint target offset" << llendl; + delete constraintp; + return FALSE; + } + if (!dp.unpackVector3(constraintp->mTargetConstraintDir, "target_dir")) { llwarns << "can't read constraint target direction" << llendl; @@ -1613,34 +1711,41 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp) return FALSE; } + if( !(constraintp->mTargetConstraintDir.isFinite()) ) + { + llwarns << "non-finite constraint target direction" << llendl; + delete constraintp; + return FALSE; + } + if (!constraintp->mTargetConstraintDir.isExactlyZero()) { constraintp->mUseTargetOffset = TRUE; // constraintp->mTargetConstraintDir *= constraintp->mSourceConstraintOffset.magVec(); } - if (!dp.unpackF32(constraintp->mEaseInStartTime, "ease_in_start")) + if (!dp.unpackF32(constraintp->mEaseInStartTime, "ease_in_start") || !llfinite(constraintp->mEaseInStartTime)) { llwarns << "can't read constraint ease in start time" << llendl; delete constraintp; return FALSE; } - if (!dp.unpackF32(constraintp->mEaseInStopTime, "ease_in_stop")) + if (!dp.unpackF32(constraintp->mEaseInStopTime, "ease_in_stop") || !llfinite(constraintp->mEaseInStopTime)) { llwarns << "can't read constraint ease in stop time" << llendl; delete constraintp; return FALSE; } - if (!dp.unpackF32(constraintp->mEaseOutStartTime, "ease_out_start")) + if (!dp.unpackF32(constraintp->mEaseOutStartTime, "ease_out_start") || !llfinite(constraintp->mEaseOutStartTime)) { llwarns << "can't read constraint ease out start time" << llendl; delete constraintp; return FALSE; } - if (!dp.unpackF32(constraintp->mEaseOutStopTime, "ease_out_stop")) + if (!dp.unpackF32(constraintp->mEaseOutStopTime, "ease_out_stop") || !llfinite(constraintp->mEaseOutStopTime)) { llwarns << "can't read constraint ease out stop time" << llendl; delete constraintp; @@ -1649,7 +1754,7 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp) mJointMotionList->mConstraints.push_front(constraintp); - constraintp->mJointStateIndices = new S32[constraintp->mChainLength + 1]; + constraintp->mJointStateIndices = new S32[constraintp->mChainLength + 1]; // note: mChainLength is size-limited - comes from a byte LLJoint* joint = mCharacter->findCollisionVolume(constraintp->mSourceConstraintVolume); // get joint to which this collision volume is attached @@ -1663,7 +1768,7 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp) if (!parent) { llwarns << "Joint with no parent: " << joint->getName() - << " Emote: " << mEmoteName << llendl; + << " Emote: " << mJointMotionList->mEmoteName << llendl; return FALSE; } joint = parent; @@ -1676,8 +1781,13 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp) break; } } + if (constraintp->mJointStateIndices[i] < 0 ) + { + llwarns << "No joint index for constraint " << i << llendl; + delete constraintp; + return FALSE; + } } - } } @@ -1701,7 +1811,7 @@ BOOL LLKeyframeMotion::serialize(LLDataPacker& dp) const success &= dp.packU16(KEYFRAME_MOTION_SUBVERSION, "sub_version"); success &= dp.packS32(mJointMotionList->mBasePriority, "base_priority"); success &= dp.packF32(mJointMotionList->mDuration, "duration"); - success &= dp.packString(mEmoteName.c_str(), "emote_name"); + 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"); @@ -1713,7 +1823,7 @@ BOOL LLKeyframeMotion::serialize(LLDataPacker& dp) const for (U32 i = 0; i < mJointMotionList->getNumJointMotions(); i++) { JointMotion* joint_motionp = mJointMotionList->getJointMotion(i); - success &= dp.packString(joint_motionp->mJointName.c_str(), "joint_name"); + success &= dp.packString(joint_motionp->mJointName, "joint_name"); success &= dp.packS32(joint_motionp->mPriority, "joint_priority"); success &= dp.packS32(joint_motionp->mRotationCurve.mNumKeys, "num_rot_keys"); @@ -1767,7 +1877,7 @@ BOOL LLKeyframeMotion::serialize(LLDataPacker& dp) const mCharacter->findCollisionVolume(shared_constraintp->mSourceConstraintVolume)->getName().c_str()); success &= dp.packBinaryDataFixed((U8*)volume_name, 16, "source_volume"); success &= dp.packVector3(shared_constraintp->mSourceConstraintOffset, "source_offset"); - if (shared_constraintp->mConstraintTargetType == TYPE_GROUND) + if (shared_constraintp->mConstraintTargetType == CONSTRAINT_TARGET_TYPE_GROUND) { snprintf(volume_name,sizeof(volume_name), "%s", "GROUND"); /* Flawfinder: ignore */ } @@ -1839,11 +1949,11 @@ void LLKeyframeMotion::setEmote(const LLUUID& emote_id) const char* emote_name = gAnimLibrary.animStateToString(emote_id); if (emote_name) { - mEmoteName = emote_name; + mJointMotionList->mEmoteName = emote_name; } else { - mEmoteName = ""; + mJointMotionList->mEmoteName = ""; } } @@ -1977,9 +2087,8 @@ void LLKeyframeMotion::onLoadComplete(LLVFS *vfs, LLCharacter* character = *char_iter; - // create an instance of this motion (it may or may not already exist) - LLKeyframeMotion* motionp = (LLKeyframeMotion*) character->createMotion(asset_uuid); - + // look for an existing instance of this motion + LLKeyframeMotion* motionp = (LLKeyframeMotion*) character->findMotion(asset_uuid); if (motionp) { if (0 == status) @@ -2008,7 +2117,7 @@ void LLKeyframeMotion::onLoadComplete(LLVFS *vfs, motionp->mAssetStatus = ASSET_FETCH_FAILED; } - delete []buffer; + delete[] buffer; } else { @@ -2018,8 +2127,7 @@ void LLKeyframeMotion::onLoadComplete(LLVFS *vfs, } else { - // motionp is NULL - llwarns << "Failed to createMotion() for asset UUID " << asset_uuid << llendl; + llwarns << "No existing motion for asset data. UUID: " << asset_uuid << llendl; } } @@ -2116,11 +2224,19 @@ void LLKeyframeDataCache::clear() //----------------------------------------------------------------------------- LLKeyframeMotion::JointConstraint::JointConstraint(JointConstraintSharedData* shared_data) : mSharedData(shared_data) { + mWeight = 0.f; mTotalLength = 0.f; mActive = FALSE; mSourceVolume = NULL; mTargetVolume = NULL; mFixupDistanceRMS = 0.f; + + int i; + for (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 c383e5e99e..1fe9af40b3 100644 --- a/indra/llcharacter/llkeyframemotion.h +++ b/indra/llcharacter/llkeyframemotion.h @@ -2,30 +2,25 @@ * @file llkeyframemotion.h * @brief Implementation of LLKeframeMotion class. * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2007, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlife.com/developers/opensource/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at http://secondlife.com/developers/opensource/flossexception + * 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. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * 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. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * 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 +41,7 @@ #include "llquaternion.h" #include "v3dmath.h" #include "v3math.h" -#include "llapr.h" +#include "llbvhconsts.h" class LLKeyframeDataCache; class LLVFS; @@ -197,18 +192,6 @@ public: static void flushKeyframeCache(); - typedef enum e_constraint_type - { - TYPE_POINT, - TYPE_PLANE - } EConstraintType; - - typedef enum e_constraint_target_type - { - TYPE_BODY, - TYPE_GROUND - } EConstraintTargetType; - protected: //------------------------------------------------------------------------- // JointConstraintSharedData @@ -223,8 +206,12 @@ protected: mEaseOutStartTime(0.f), mEaseOutStopTime(0.f), mUseTargetOffset(FALSE), - mConstraintType(TYPE_POINT), - mConstraintTargetType(TYPE_BODY) {}; + mConstraintType(CONSTRAINT_TYPE_POINT), + mConstraintTargetType(CONSTRAINT_TARGET_TYPE_BODY), + mSourceConstraintVolume(0), + mTargetConstraintVolume(0), + mJointStateIndices(NULL) + { }; ~JointConstraintSharedData() { delete [] mJointStateIndices; } S32 mSourceConstraintVolume; @@ -416,6 +403,10 @@ public: 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(); @@ -435,7 +426,6 @@ protected: std::vector<LLPointer<LLJointState> > mJointStates; LLJoint* mPelvisp; LLCharacter* mCharacter; - std::string mEmoteName; typedef std::list<JointConstraint*> constraint_list_t; constraint_list_t mConstraints; U32 mLastSkeletonSerialNum; diff --git a/indra/llcharacter/llkeyframemotionparam.cpp b/indra/llcharacter/llkeyframemotionparam.cpp index 30edc29c6e..82fe8971f5 100644 --- a/indra/llcharacter/llkeyframemotionparam.cpp +++ b/indra/llcharacter/llkeyframemotionparam.cpp @@ -2,30 +2,25 @@ * @file llkeyframemotionparam.cpp * @brief Implementation of LLKeyframeMotion class. * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2007, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlife.com/developers/opensource/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at http://secondlife.com/developers/opensource/flossexception + * 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. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * 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. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * 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$ */ @@ -76,7 +71,7 @@ LLKeyframeMotionParam::~LLKeyframeMotionParam() for (motion_list_t::iterator iter2 = motionList.begin(); iter2 != motionList.end(); ++iter2) { const ParameterizedMotion& paramMotion = *iter2; - delete paramMotion.first; // note - deletes the structure; ParameterizedMotion pair remains intact + delete paramMotion.mMotion; } motionList.clear(); } @@ -102,32 +97,32 @@ LLMotion::LLMotionInitStatus LLKeyframeMotionParam::onInitialize(LLCharacter *ch for (motion_list_t::iterator iter2 = motionList.begin(); iter2 != motionList.end(); ++iter2) { const ParameterizedMotion& paramMotion = *iter2; + LLMotion* motion = paramMotion.mMotion; + motion->onInitialize(character); - paramMotion.first->onInitialize(character); - - if (paramMotion.first->getDuration() > mEaseInDuration) + if (motion->getDuration() > mEaseInDuration) { - mEaseInDuration = paramMotion.first->getEaseInDuration(); + mEaseInDuration = motion->getEaseInDuration(); } - if (paramMotion.first->getEaseOutDuration() > mEaseOutDuration) + if (motion->getEaseOutDuration() > mEaseOutDuration) { - mEaseOutDuration = paramMotion.first->getEaseOutDuration(); + mEaseOutDuration = motion->getEaseOutDuration(); } - if (paramMotion.first->getDuration() > mDuration) + if (motion->getDuration() > mDuration) { - mDuration = paramMotion.first->getDuration(); + mDuration = motion->getDuration(); } - if (paramMotion.first->getPriority() > mPriority) + if (motion->getPriority() > mPriority) { - mPriority = paramMotion.first->getPriority(); + mPriority = motion->getPriority(); } - LLPose *pose = paramMotion.first->getPose(); + LLPose *pose = motion->getPose(); - mPoseBlender.addMotion(paramMotion.first); + mPoseBlender.addMotion(motion); for (LLJointState *jsp = pose->getFirstJointState(); jsp; jsp = pose->getNextJointState()) { LLPose *blendedPose = mPoseBlender.getBlendedPose(); @@ -151,7 +146,7 @@ BOOL LLKeyframeMotionParam::onActivate() for (motion_list_t::iterator iter2 = motionList.begin(); iter2 != motionList.end(); ++iter2) { const ParameterizedMotion& paramMotion = *iter2; - paramMotion.first->activate(); + paramMotion.mMotion->activate(mActivationTimestamp); } } return TRUE; @@ -173,8 +168,8 @@ BOOL LLKeyframeMotionParam::onUpdate(F32 time, U8* joint_mask) for (motion_list_t::iterator iter2 = motionList.begin(); iter2 != motionList.end(); ++iter2) { const ParameterizedMotion& paramMotion = *iter2; -// llinfos << "Weight for pose " << paramMotion.first->getName() << " is " << paramMotion.first->getPose()->getWeight() << llendl; - paramMotion.first->getPose()->setWeight(0.f); +// llinfos << "Weight for pose " << paramMotion.mMotion->getName() << " is " << paramMotion.mMotion->getPose()->getWeight() << llendl; + paramMotion.mMotion->getPose()->setWeight(0.f); } } @@ -190,6 +185,7 @@ BOOL LLKeyframeMotionParam::onUpdate(F32 time, U8* joint_mask) continue; } + // DANGER! Do not modify mParameterizedMotions while using these pointers! const ParameterizedMotion* firstMotion = NULL; const ParameterizedMotion* secondMotion = NULL; @@ -197,9 +193,9 @@ BOOL LLKeyframeMotionParam::onUpdate(F32 time, U8* joint_mask) for (motion_list_t::iterator iter2 = motionList.begin(); iter2 != motionList.end(); ++iter2) { const ParameterizedMotion& paramMotion = *iter2; - paramMotion.first->onUpdate(time, joint_mask); + paramMotion.mMotion->onUpdate(time, joint_mask); - F32 distToParam = paramMotion.second - *paramValue; + F32 distToParam = paramMotion.mParam - *paramValue; if ( distToParam <= 0.f) { @@ -227,12 +223,12 @@ BOOL LLKeyframeMotionParam::onUpdate(F32 time, U8* joint_mask) LLPose *secondPose; if (firstMotion) - firstPose = firstMotion->first->getPose(); + firstPose = firstMotion->mMotion->getPose(); else firstPose = NULL; if (secondMotion) - secondPose = secondMotion->first->getPose(); + secondPose = secondMotion->mMotion->getPose(); else secondPose = NULL; @@ -243,7 +239,7 @@ BOOL LLKeyframeMotionParam::onUpdate(F32 time, U8* joint_mask) { firstPose->setWeight(weightFactor); } - else if (firstMotion->second == secondMotion->second) + else if (firstMotion->mParam == secondMotion->mParam) { firstPose->setWeight(0.5f * weightFactor); secondPose->setWeight(0.5f * weightFactor); @@ -251,8 +247,8 @@ BOOL LLKeyframeMotionParam::onUpdate(F32 time, U8* joint_mask) else { F32 first_weight = 1.f - - ((llclamp(*paramValue - firstMotion->second, 0.f, (secondMotion->second - firstMotion->second))) / - (secondMotion->second - firstMotion->second)); + ((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; @@ -290,7 +286,7 @@ void LLKeyframeMotionParam::onDeactivate() for (motion_list_t::iterator iter2 = motionList.begin(); iter2 != motionList.end(); ++iter2) { const ParameterizedMotion& paramMotion = *iter2; - paramMotion.first->onDeactivate(); + paramMotion.mMotion->onDeactivate(); } } } @@ -328,9 +324,9 @@ void LLKeyframeMotionParam::setDefaultKeyframeMotion(char *name) for (motion_list_t::iterator iter2 = motionList.begin(); iter2 != motionList.end(); ++iter2) { const ParameterizedMotion& paramMotion = *iter2; - if (paramMotion.first->getName() == name) + if (paramMotion.mMotion->getName() == name) { - mDefaultKeyframeMotion = paramMotion.first; + mDefaultKeyframeMotion = paramMotion.mMotion; } } } @@ -345,16 +341,19 @@ BOOL LLKeyframeMotionParam::loadMotions() // Load named file by concatenating the character prefix with the motion name. // Load data into a buffer to be parsed. //------------------------------------------------------------------------- - char path[LL_MAX_PATH]; /* Flawfinder: ignore */ - snprintf( path,sizeof(path), "%s_%s.llp", - gDirUtilp->getExpandedFilename(LL_PATH_MOTIONS,mCharacter->getAnimationPrefix()).c_str(), - getName().c_str() ); + //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; - apr_file_t* fp = ll_apr_file_open(path, LL_APR_R, &fileSize); + LLAPRFile infile ; + infile.open(path, LL_APR_R, NULL, &fileSize); + apr_file_t* fp = infile.getFileHandle() ; if (!fp || fileSize == 0) { llinfos << "ERROR: can't open: " << path << llendl; @@ -362,19 +361,13 @@ BOOL LLKeyframeMotionParam::loadMotions() } // allocate a text buffer - char *text = new char[ fileSize+1 ]; - if ( !text ) - { - llinfos << "ERROR: can't allocated keyframe text buffer." << llendl; - apr_file_close(fp); - return FALSE; - } + std::vector<char> text(fileSize+1); //------------------------------------------------------------------------- // load data from file into buffer //------------------------------------------------------------------------- bool error = false; - char *p = text; + char *p = &text[0]; while ( 1 ) { if (apr_file_eof(fp) == APR_EOF) @@ -393,17 +386,16 @@ BOOL LLKeyframeMotionParam::loadMotions() //------------------------------------------------------------------------- // close the file //------------------------------------------------------------------------- - apr_file_close( fp ); + infile.close(); //------------------------------------------------------------------------- // check for error //------------------------------------------------------------------------- - llassert( p <= (text+fileSize) ); + llassert( p <= (&text[0] + fileSize) ); if ( error ) { llinfos << "ERROR: error while reading from " << path << llendl; - delete [] text; return FALSE; } @@ -412,7 +404,7 @@ BOOL LLKeyframeMotionParam::loadMotions() //------------------------------------------------------------------------- // parse the text and build keyframe data structures //------------------------------------------------------------------------- - p = text; + p = &text[0]; S32 num; char strA[80]; /* Flawfinder: ignore */ char strB[80]; /* Flawfinder: ignore */ @@ -431,11 +423,10 @@ BOOL LLKeyframeMotionParam::loadMotions() if ((num != 3)) { llinfos << "WARNING: can't read parametric motion" << llendl; - delete [] text; return FALSE; } - addKeyframeMotion(strA, gAnimLibrary.stringToAnimState(strA), strB, floatA); + addKeyframeMotion(strA, gAnimLibrary.stringToAnimState(std::string(strA)), strB, floatA); if (isFirstMotion) { isFirstMotion = FALSE; @@ -452,7 +443,6 @@ BOOL LLKeyframeMotionParam::loadMotions() num = sscanf(p, "%79s %79s %f", strA, strB, &floatA); /* Flawfinder: ignore */ } - delete [] text; return TRUE; } diff --git a/indra/llcharacter/llkeyframemotionparam.h b/indra/llcharacter/llkeyframemotionparam.h index 305207eb09..24e8141753 100644 --- a/indra/llcharacter/llkeyframemotionparam.h +++ b/indra/llcharacter/llkeyframemotionparam.h @@ -2,30 +2,25 @@ * @file llkeyframemotionparam.h * @brief Implementation of LLKeframeMotionParam class. * - * $LicenseInfo:firstyear=2002&license=viewergpl$ - * - * Copyright (c) 2002-2007, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2002&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlife.com/developers/opensource/gplv2 + * 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. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at http://secondlife.com/developers/opensource/flossexception + * 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. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * 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 * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -126,7 +121,12 @@ protected: //------------------------------------------------------------------------- // new functions defined by this subclass //------------------------------------------------------------------------- - typedef std::pair<LLMotion*, F32> ParameterizedMotion; + 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); @@ -134,8 +134,6 @@ protected: // set default motion for LOD and retrieving blend constants void setDefaultKeyframeMotion(char *); - static BOOL sortFunc(ParameterizedMotion *new_motion, ParameterizedMotion *tested_motion); - BOOL loadMotions(); protected: @@ -147,10 +145,10 @@ protected: { bool operator() (const ParameterizedMotion& a, const ParameterizedMotion& b) const { - if (a.second != b.second) - return (a.second < b.second); + if (a.mParam != b.mParam) + return (a.mParam < b.mParam); else - return a.first < b.first; + return a.mMotion < b.mMotion; } }; diff --git a/indra/llcharacter/llkeyframestandmotion.cpp b/indra/llcharacter/llkeyframestandmotion.cpp index 5093243f64..3f91532c8e 100644 --- a/indra/llcharacter/llkeyframestandmotion.cpp +++ b/indra/llcharacter/llkeyframestandmotion.cpp @@ -2,30 +2,25 @@ * @file llkeyframestandmotion.cpp * @brief Implementation of LLKeyframeStandMotion class. * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2007, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlife.com/developers/opensource/gplv2 + * 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. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at http://secondlife.com/developers/opensource/flossexception + * 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. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * 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 * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -189,7 +184,7 @@ BOOL LLKeyframeStandMotion::onUpdate(F32 time, U8* joint_mask) if (dot(mPelvisState->getJoint()->getWorldRotation(), mLastGoodPelvisRotation) < ROTATION_THRESHOLD) { mLastGoodPelvisRotation = mPelvisState->getJoint()->getWorldRotation(); - mLastGoodPelvisRotation.normQuat(); + mLastGoodPelvisRotation.normalize(); mTrackAnkles = TRUE; } else if ((mCharacter->getCharacterPosition() - mLastGoodPosition).magVecSquared() > POSITION_THRESHOLD) diff --git a/indra/llcharacter/llkeyframestandmotion.h b/indra/llcharacter/llkeyframestandmotion.h index f98a7e6a84..c2634ecd6d 100644 --- a/indra/llcharacter/llkeyframestandmotion.h +++ b/indra/llcharacter/llkeyframestandmotion.h @@ -2,30 +2,25 @@ * @file llkeyframestandmotion.h * @brief Implementation of LLKeyframeStandMotion class. * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2007, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlife.com/developers/opensource/gplv2 + * 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. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at http://secondlife.com/developers/opensource/flossexception + * 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. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * 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 * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ diff --git a/indra/llcharacter/llkeyframewalkmotion.cpp b/indra/llcharacter/llkeyframewalkmotion.cpp index 0d7e34bb4f..d52eb89a5c 100644 --- a/indra/llcharacter/llkeyframewalkmotion.cpp +++ b/indra/llcharacter/llkeyframewalkmotion.cpp @@ -2,30 +2,25 @@ * @file llkeyframewalkmotion.cpp * @brief Implementation of LLKeyframeWalkMotion class. * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2007, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlife.com/developers/opensource/gplv2 + * 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. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at http://secondlife.com/developers/opensource/flossexception + * 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. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * 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 * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -43,26 +38,31 @@ //----------------------------------------------------------------------------- // 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 MAX_TIME_DELTA = 2.f; //max two seconds a frame for calculating interpolation -const F32 SPEED_ADJUST_MAX = 2.5f; // maximum adjustment of walk animation playback speed -const F32 SPEED_ADJUST_MAX_SEC = 3.f; // maximum adjustment to walk animation playback speed for a second -const F32 DRIFT_COMP_MAX_TOTAL = 0.07f;//0.55f; // maximum drift compensation overall, in any direction -const F32 DRIFT_COMP_MAX_SPEED = 4.f; // speed at which drift compensation total maxes out +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 DRIFT_COMP_MAX_TOTAL = 0.1f; // maximum drift compensation overall, in any direction +const F32 DRIFT_COMP_MAX_SPEED = 4.f; // speed at which drift compensation total maxes out const F32 MAX_ROLL = 0.6f; +const F32 PELVIS_COMPENSATION_WIEGHT = 0.7f; // proportion of foot drift that is compensated by moving the avatar directly +const F32 SPEED_ADJUST_TIME_CONSTANT = 0.1f; // time constant for speed adjustment interpolation //----------------------------------------------------------------------------- // LLKeyframeWalkMotion() // Class Constructor //----------------------------------------------------------------------------- -LLKeyframeWalkMotion::LLKeyframeWalkMotion(const LLUUID &id) : LLKeyframeMotion(id) -{ - mRealTimeLast = 0.0f; - mAdjTimeLast = 0.0f; - mCharacter = NULL; -} +LLKeyframeWalkMotion::LLKeyframeWalkMotion(const LLUUID &id) +: LLKeyframeMotion(id), + mCharacter(NULL), + mCyclePhase(0.0f), + mRealTimeLast(0.0f), + mAdjTimeLast(0.0f), + mDownFoot(0) +{} //----------------------------------------------------------------------------- @@ -70,8 +70,7 @@ LLKeyframeWalkMotion::LLKeyframeWalkMotion(const LLUUID &id) : LLKeyframeMotion( // Class Destructor //----------------------------------------------------------------------------- LLKeyframeWalkMotion::~LLKeyframeWalkMotion() -{ -} +{} //----------------------------------------------------------------------------- @@ -139,11 +138,15 @@ BOOL LLKeyframeWalkMotion::onUpdate(F32 time, U8* joint_mask) // LLWalkAdjustMotion() // Class Constructor //----------------------------------------------------------------------------- -LLWalkAdjustMotion::LLWalkAdjustMotion(const LLUUID &id) : LLMotion(id) +LLWalkAdjustMotion::LLWalkAdjustMotion(const LLUUID &id) : + LLMotion(id), + mLastTime(0.f), + mAnimSpeed(0.f), + mAdjustedSpeed(0.f), + mRelativeDir(0.f), + mAnkleOffset(0.f) { - mLastTime = 0.f; mName = "walk_adjust"; - mPelvisState = new LLJointState; } @@ -175,15 +178,16 @@ LLMotion::LLMotionInitStatus LLWalkAdjustMotion::onInitialize(LLCharacter *chara //----------------------------------------------------------------------------- BOOL LLWalkAdjustMotion::onActivate() { - mAvgCorrection = 0.f; - mSpeedAdjust = 0.f; mAnimSpeed = 0.f; - mAvgSpeed = 0.f; + mAdjustedSpeed = 0.f; mRelativeDir = 1.f; mPelvisState->setPosition(LLVector3::zero); // store ankle positions for next frame - mLastLeftAnklePos = mCharacter->getPosGlobalFromAgent(mLeftAnkleJoint->getWorldPosition()); - mLastRightAnklePos = mCharacter->getPosGlobalFromAgent(mRightAnkleJoint->getWorldPosition()); + 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(); @@ -197,143 +201,121 @@ BOOL LLWalkAdjustMotion::onActivate() //----------------------------------------------------------------------------- BOOL LLWalkAdjustMotion::onUpdate(F32 time, U8* joint_mask) { - LLVector3 footCorrection; - LLVector3 vel = mCharacter->getCharacterVelocity() * mCharacter->getTimeDilation(); - F32 deltaTime = llclamp(time - mLastTime, 0.f, MAX_TIME_DELTA); + // delta_time is guaranteed to be non zero + F32 delta_time = llclamp(time - mLastTime, TIME_EPSILON, MAX_TIME_DELTA); mLastTime = time; - LLQuaternion inv_rotation = ~mPelvisJoint->getWorldRotation(); + // find the avatar motion vector in the XY plane + LLVector3 avatar_velocity = mCharacter->getCharacterVelocity() * mCharacter->getTimeDilation(); + avatar_velocity.mV[VZ] = 0.f; - // get speed and normalize velocity vector - LLVector3 ang_vel = mCharacter->getCharacterAngularVelocity() * mCharacter->getTimeDilation(); - F32 speed = llmin(vel.normVec(), MAX_WALK_PLAYBACK_SPEED); - mAvgSpeed = lerp(mAvgSpeed, speed, LLCriticalDamp::getInterpolant(0.2f)); + F32 speed = llclamp(avatar_velocity.magVec(), 0.f, MAX_WALK_PLAYBACK_SPEED); - // calculate facing vector in pelvis-local space - // (either straight forward or back, depending on velocity) - LLVector3 localVel = vel * inv_rotation; - if (localVel.mV[VX] > 0.f) - { - mRelativeDir = 1.f; - } - else if (localVel.mV[VX] < 0.f) - { - mRelativeDir = -1.f; - } + // grab avatar->world transforms + LLQuaternion avatar_to_world_rot = mCharacter->getRootJoint()->getWorldRotation(); - // calculate world-space foot drift - LLVector3 leftFootDelta; - LLVector3 leftFootWorldPosition = mLeftAnkleJoint->getWorldPosition(); - LLVector3d leftFootGlobalPosition = mCharacter->getPosGlobalFromAgent(leftFootWorldPosition); - leftFootDelta.setVec(mLastLeftAnklePos - leftFootGlobalPosition); - mLastLeftAnklePos = leftFootGlobalPosition; + LLQuaternion world_to_avatar_rot(avatar_to_world_rot); + world_to_avatar_rot.conjugate(); - LLVector3 rightFootDelta; - LLVector3 rightFootWorldPosition = mRightAnkleJoint->getWorldPosition(); - LLVector3d rightFootGlobalPosition = mCharacter->getPosGlobalFromAgent(rightFootWorldPosition); - rightFootDelta.setVec(mLastRightAnklePos - rightFootGlobalPosition); - mLastRightAnklePos = rightFootGlobalPosition; + LLVector3 foot_slip_vector; // find foot drift along velocity vector - if (mAvgSpeed > 0.1) - { - // walking/running - F32 leftFootDriftAmt = leftFootDelta * vel; - F32 rightFootDriftAmt = rightFootDelta * vel; - - if (rightFootDriftAmt > leftFootDriftAmt) - { - footCorrection = rightFootDelta; - } else - { - footCorrection = leftFootDelta; - } - } - else - { - mAvgSpeed = ang_vel.magVec() * mAnkleOffset; - mRelativeDir = 1.f; - - // standing/turning - // find the lower foot - if (leftFootWorldPosition.mV[VZ] < rightFootWorldPosition.mV[VZ]) - { - // pivot on left foot - footCorrection = leftFootDelta; - } + 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 - { - // pivot on right foot - footCorrection = rightFootDelta; + { // otherwise use the left foot + foot_slip_vector = leftFootDelta; } - } - - // rotate into avatar coordinates - footCorrection = footCorrection * inv_rotation; - - // calculate ideal pelvis offset so that foot is glued to ground and damp towards it - // the amount of foot slippage this frame + the offset applied last frame - mPelvisOffset = mPelvisState->getPosition() + lerp(LLVector3::zero, footCorrection, LLCriticalDamp::getInterpolant(0.2f)); - - // pelvis drift (along walk direction) - mAvgCorrection = lerp(mAvgCorrection, footCorrection.mV[VX] * mRelativeDir, LLCriticalDamp::getInterpolant(0.1f)); - - // calculate average velocity of foot slippage - F32 footSlipVelocity = (deltaTime != 0.f) ? (-mAvgCorrection / deltaTime) : 0.f; - F32 newSpeedAdjust = 0.f; - - // 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 - - F32 directional_factor = localVel.mV[VX] * mRelativeDir; - if (speed > 0.1f) - { - // calculate ratio of desired foot velocity to detected foot velocity - newSpeedAdjust = llclamp(footSlipVelocity - mAvgSpeed * (1.f - directional_factor), - -SPEED_ADJUST_MAX, SPEED_ADJUST_MAX); - newSpeedAdjust = lerp(mSpeedAdjust, newSpeedAdjust, LLCriticalDamp::getInterpolant(0.2f)); - - F32 speedDelta = newSpeedAdjust - mSpeedAdjust; - speedDelta = llclamp(speedDelta, -SPEED_ADJUST_MAX_SEC * deltaTime, SPEED_ADJUST_MAX_SEC * deltaTime); - - mSpeedAdjust = mSpeedAdjust + speedDelta; + // 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), LLCriticalDamp::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 = lerp(mAdjustedSpeed, desired_speed_multiplier, LLCriticalDamp::getInterpolant(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 - { - mSpeedAdjust = lerp(mSpeedAdjust, 0.f, LLCriticalDamp::getInterpolant(0.2f)); + { // standing/turning + + // damp out speed adjustment to 0 + mAnimSpeed = lerp(mAnimSpeed, 1.f, LLCriticalDamp::getInterpolant(0.2f)); + //mPelvisOffset = lerp(mPelvisOffset, LLVector3::zero, LLCriticalDamp::getInterpolant(0.2f)); } - mAnimSpeed = (mAvgSpeed + mSpeedAdjust) * mRelativeDir; -// char debug_text[64]; -// sprintf(debug_text, "Foot slip vel: %.2f", footSlipVelocity); -// mCharacter->addDebugText(debug_text); -// sprintf(debug_text, "Speed: %.2f", mAvgSpeed); -// mCharacter->addDebugText(debug_text); -// sprintf(debug_text, "Speed Adjust: %.2f", mSpeedAdjust); -// mCharacter->addDebugText(debug_text); -// sprintf(debug_text, "Animation Playback Speed: %.2f", mAnimSpeed); -// mCharacter->addDebugText(debug_text); - mCharacter->setAnimationData("Walk Speed", &mAnimSpeed); - - // clamp pelvis offset to a 90 degree arc behind the nominal position - F32 drift_comp_max = llclamp(speed, 0.f, DRIFT_COMP_MAX_SPEED) / DRIFT_COMP_MAX_SPEED; - drift_comp_max *= DRIFT_COMP_MAX_TOTAL; - - LLVector3 currentPelvisPos = mPelvisState->getJoint()->getPosition(); - - // 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 - mPelvisOffset.mV[VX] = llclamp( mPelvisOffset.mV[VX], -drift_comp_max - currentPelvisPos.mV[VX], drift_comp_max - currentPelvisPos.mV[VX] ); - mPelvisOffset.mV[VY] = llclamp( mPelvisOffset.mV[VY], -drift_comp_max - currentPelvisPos.mV[VY], drift_comp_max - currentPelvisPos.mV[VY]); - mPelvisOffset.mV[VZ] = 0.f; + // broadcast walk speed change + mCharacter->setAnimationData("Walk Speed", &mAnimSpeed); // set position + // need to update *some* joint to keep this animation active mPelvisState->setPosition(mPelvisOffset); - mCharacter->setAnimationData("Pelvis Offset", &mPelvisOffset); - return TRUE; } @@ -349,7 +331,8 @@ void LLWalkAdjustMotion::onDeactivate() // LLFlyAdjustMotion::LLFlyAdjustMotion() //----------------------------------------------------------------------------- LLFlyAdjustMotion::LLFlyAdjustMotion(const LLUUID &id) - : LLMotion(id) + : LLMotion(id), + mRoll(0.f) { mName = "fly_adjust"; @@ -402,14 +385,8 @@ BOOL LLFlyAdjustMotion::onUpdate(F32 time, U8* joint_mask) // roll is critically damped interpolation between current roll and angular velocity-derived target roll mRoll = lerp(mRoll, target_roll, LLCriticalDamp::getInterpolant(0.1f)); -// llinfos << mRoll << llendl; - LLQuaternion roll(mRoll, LLVector3(0.f, 0.f, 1.f)); mPelvisState->setRotation(roll); -// F32 lerp_amt = LLCriticalDamp::getInterpolant(0.2f); -// -// LLVector3 pelvis_correction = mPelvisState->getPosition() - lerp(LLVector3::zero, mPelvisState->getJoint()->getPosition() + mPelvisState->getPosition(), lerp_amt); -// mPelvisState->setPosition(pelvis_correction); return TRUE; } diff --git a/indra/llcharacter/llkeyframewalkmotion.h b/indra/llcharacter/llkeyframewalkmotion.h index bd30b5d11d..0e8d21b765 100644 --- a/indra/llcharacter/llkeyframewalkmotion.h +++ b/indra/llcharacter/llkeyframewalkmotion.h @@ -2,30 +2,25 @@ * @file llkeyframewalkmotion.h * @brief Implementation of LLKeframeWalkMotion class. * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2007, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlife.com/developers/opensource/gplv2 + * 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. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at http://secondlife.com/developers/opensource/flossexception + * 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. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * 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 * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -125,13 +120,11 @@ public: LLJoint* mRightAnkleJoint; LLPointer<LLJointState> mPelvisState; LLJoint* mPelvisJoint; - LLVector3d mLastLeftAnklePos; - LLVector3d mLastRightAnklePos; + LLVector3d mLastLeftFootGlobalPos; + LLVector3d mLastRightFootGlobalPos; F32 mLastTime; - F32 mAvgCorrection; - F32 mSpeedAdjust; + F32 mAdjustedSpeed; F32 mAnimSpeed; - F32 mAvgSpeed; F32 mRelativeDir; LLVector3 mPelvisOffset; F32 mAnkleOffset; diff --git a/indra/llcharacter/llmotion.cpp b/indra/llcharacter/llmotion.cpp index bf332ed838..2551f125d0 100644 --- a/indra/llcharacter/llmotion.cpp +++ b/indra/llcharacter/llmotion.cpp @@ -2,30 +2,25 @@ * @file llmotion.cpp * @brief Implementation of LLMotion class. * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2007, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlife.com/developers/opensource/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at http://secondlife.com/developers/opensource/flossexception + * 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. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * 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. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * 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$ */ @@ -47,22 +42,20 @@ // LLMotion() // Class Constructor //----------------------------------------------------------------------------- -LLMotion::LLMotion( const LLUUID &id ) +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) { - mActivationTimestamp = 0.f; - mStopTimestamp = 0.f; - mSendStopTimestamp = F32_MAX; - mResidualWeight = 0.f; - mFadeWeight = 1.f; - mStopped = TRUE; - mActive = FALSE; - mDeactivateCallback = NULL; - - memset(&mJointSignature[0][0], 0, sizeof(U8) * LL_CHARACTER_MAX_JOINTS); - memset(&mJointSignature[1][0], 0, sizeof(U8) * LL_CHARACTER_MAX_JOINTS); - memset(&mJointSignature[2][0], 0, sizeof(U8) * LL_CHARACTER_MAX_JOINTS); - - mID = id; + for (int i=0; i<3; ++i) + memset(&mJointSignature[i][0], 0, sizeof(U8) * LL_CHARACTER_MAX_JOINTS); } //----------------------------------------------------------------------------- @@ -129,6 +122,13 @@ void LLMotion::setDeactivateCallback( void (*cb)(void *), void* userdata ) mDeactivateCallbackUserData = userdata; } +//virtual +void LLMotion::setStopTime(F32 time) +{ + mStopTimestamp = time; + mStopped = TRUE; +} + BOOL LLMotion::isBlending() { return mPose.getWeight() < 1.f; @@ -137,8 +137,9 @@ BOOL LLMotion::isBlending() //----------------------------------------------------------------------------- // activate() //----------------------------------------------------------------------------- -void LLMotion::activate() +void LLMotion::activate(F32 time) { + mActivationTimestamp = time; mStopped = FALSE; mActive = TRUE; onActivate(); @@ -152,7 +153,12 @@ void LLMotion::deactivate() mActive = FALSE; mPose.setWeight(0.f); - if (mDeactivateCallback) (*mDeactivateCallback)(mDeactivateCallbackUserData); + if (mDeactivateCallback) + { + (*mDeactivateCallback)(mDeactivateCallbackUserData); + mDeactivateCallback = NULL; // only call callback once + mDeactivateCallbackUserData = NULL; + } onDeactivate(); } diff --git a/indra/llcharacter/llmotion.h b/indra/llcharacter/llmotion.h index 7669920339..6e532aac2f 100644 --- a/indra/llcharacter/llmotion.h +++ b/indra/llcharacter/llmotion.h @@ -2,30 +2,25 @@ * @file llmotion.h * @brief Implementation of LLMotion class. * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2007, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlife.com/developers/opensource/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at http://secondlife.com/developers/opensource/flossexception + * 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. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * 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. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * 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,6 +43,8 @@ class LLCharacter; //----------------------------------------------------------------------------- class LLMotion { + friend class LLMotionController; + public: enum LLMotionBlendType { @@ -73,10 +70,6 @@ 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 NULL; } - // get the name of this instance const std::string &getName() const { return mName; } @@ -96,7 +89,7 @@ public: F32 getStopTime() const { return mStopTimestamp; } - virtual void setStopTime(F32 time) { mStopTimestamp = time; mStopped = TRUE; } + virtual void setStopTime(F32 time); BOOL isStopped() const { return mStopped; } @@ -104,12 +97,18 @@ public: BOOL isBlending(); - void activate(); - + // 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; } - +public: + void activate(F32 time); + public: //------------------------------------------------------------------------- // animation callbacks to be implemented by subclasses @@ -170,14 +169,13 @@ protected: BOOL mStopped; // motion has been stopped; BOOL mActive; // motion is on active list (can be stopped or not stopped) -public: //------------------------------------------------------------------------- // 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 diff --git a/indra/llcharacter/llmotioncontroller.cpp b/indra/llcharacter/llmotioncontroller.cpp index fff19dbefe..bb892f4a7f 100644 --- a/indra/llcharacter/llmotioncontroller.cpp +++ b/indra/llcharacter/llmotioncontroller.cpp @@ -2,30 +2,25 @@ * @file llmotioncontroller.cpp * @brief Implementation of LLMotionController class. * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2007, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlife.com/developers/opensource/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at http://secondlife.com/developers/opensource/flossexception + * 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. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * 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. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * 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,6 +29,8 @@ //----------------------------------------------------------------------------- #include "linden_common.h" +#include "llmemtype.h" + #include "llmotioncontroller.h" #include "llkeyframemotion.h" #include "llmath.h" @@ -50,32 +47,6 @@ const U32 MAX_MOTION_INSTANCES = 32; LLMotionRegistry LLMotionController::sRegistry; //----------------------------------------------------------------------------- -// LLMotionTableEntry() -//----------------------------------------------------------------------------- -LLMotionTableEntry::LLMotionTableEntry() -{ - mConstructor = NULL; - mID.setNull(); -} - -LLMotionTableEntry::LLMotionTableEntry(LLMotionConstructor constructor, const LLUUID& id) - : mConstructor(constructor), mID(id) -{ - -} - -//----------------------------------------------------------------------------- -// create() -//----------------------------------------------------------------------------- -LLMotion* LLMotionTableEntry::create(const LLUUID &id) -{ - LLMotion* motionp = mConstructor(id); - - return motionp; -} - - -//----------------------------------------------------------------------------- //----------------------------------------------------------------------------- // LLMotionRegistry class //----------------------------------------------------------------------------- @@ -85,7 +56,7 @@ LLMotion* LLMotionTableEntry::create(const LLUUID &id) // LLMotionRegistry() // Class Constructor //----------------------------------------------------------------------------- -LLMotionRegistry::LLMotionRegistry() : mMotionTable(LLMotionTableEntry::uuidEq, LLMotionTableEntry()) +LLMotionRegistry::LLMotionRegistry() { } @@ -97,19 +68,19 @@ LLMotionRegistry::LLMotionRegistry() : mMotionTable(LLMotionTableEntry::uuidEq, //----------------------------------------------------------------------------- LLMotionRegistry::~LLMotionRegistry() { - mMotionTable.removeAll(); + mMotionTable.clear(); } //----------------------------------------------------------------------------- // addMotion() //----------------------------------------------------------------------------- -BOOL LLMotionRegistry::addMotion( const LLUUID& id, LLMotionConstructor constructor ) +BOOL LLMotionRegistry::registerMotion( const LLUUID& id, LLMotionConstructor constructor ) { -// llinfos << "Registering motion: " << name << llendl; - if (!mMotionTable.check(id)) + // llinfos << "Registering motion: " << name << llendl; + if (!is_in_map(mMotionTable, id)) { - mMotionTable.set(id, LLMotionTableEntry(constructor, id)); + mMotionTable[id] = constructor; return TRUE; } @@ -121,7 +92,7 @@ BOOL LLMotionRegistry::addMotion( const LLUUID& id, LLMotionConstructor construc //----------------------------------------------------------------------------- void LLMotionRegistry::markBad( const LLUUID& id ) { - mMotionTable.set(id, LLMotionTableEntry()); + mMotionTable[id] = LLMotionConstructor(NULL); } //----------------------------------------------------------------------------- @@ -129,17 +100,17 @@ void LLMotionRegistry::markBad( const LLUUID& id ) //----------------------------------------------------------------------------- LLMotion *LLMotionRegistry::createMotion( const LLUUID &id ) { - LLMotionTableEntry motion_entry = mMotionTable.get(id); + LLMotionConstructor constructor = get_if_there(mMotionTable, id, LLMotionConstructor(NULL)); LLMotion* motion = NULL; - if ( motion_entry.getID().isNull() ) + if ( constructor == NULL ) { // *FIX: need to replace with a better default scheme. RN motion = LLKeyframeMotion::create(id); } else { - motion = motion_entry.create(id); + motion = constructor(id); } return motion; @@ -155,18 +126,20 @@ LLMotion *LLMotionRegistry::createMotion( const LLUUID &id ) // LLMotionController() // Class Constructor //----------------------------------------------------------------------------- -LLMotionController::LLMotionController( ) +LLMotionController::LLMotionController() + : mTimeFactor(1.f), + mCharacter(NULL), + mAnimTime(0.f), + mPrevTimerElapsed(0.f), + mLastTime(0.0f), + mHasRunOnce(FALSE), + mPaused(FALSE), + mPauseTime(0.f), + mTimeStep(0.f), + mTimeStepCount(0), + mLastInterp(0.f), + mIsSelf(FALSE) { - mTime = 0.f; - mTimeOffset = 0.f; - mLastTime = 0.0f; - mHasRunOnce = FALSE; - mPaused = FALSE; - mPauseTime = 0.f; - mTimeStep = 0.f; - mTimeStepCount = 0; - mLastInterp = 0.f; - mTimeFactor = 1.f; } @@ -179,6 +152,15 @@ LLMotionController::~LLMotionController() 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(); +} + //----------------------------------------------------------------------------- // deleteAllMotions() //----------------------------------------------------------------------------- @@ -193,24 +175,38 @@ void LLMotionController::deleteAllMotions() } //----------------------------------------------------------------------------- -// addLoadedMotion() +// purgeExcessMotion() //----------------------------------------------------------------------------- -void LLMotionController::addLoadedMotion(LLMotion* motionp) +void LLMotionController::purgeExcessMotions() { - std::set<LLUUID> motions_to_kill; + 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); + } + } + } - // gather all inactive, loaded motions + std::set<LLUUID> motions_to_kill; if (mLoadedMotions.size() > MAX_MOTION_INSTANCES) { // too many motions active this frame, kill all blenders mPoseBlender.clearBlenders(); - - for (motion_list_t::iterator loaded_motion_it = mLoadedMotions.begin(); - loaded_motion_it != mLoadedMotions.end(); - ++loaded_motion_it) + for (motion_set_t::iterator loaded_motion_it = mLoadedMotions.begin(); + loaded_motion_it != mLoadedMotions.end(); + ++loaded_motion_it) { LLMotion* cur_motionp = *loaded_motion_it; - // motion isn't playing, delete it if (!isMotionActive(cur_motionp)) { @@ -218,7 +214,7 @@ void LLMotionController::addLoadedMotion(LLMotion* motionp) } } } - + // clean up all inactive, loaded motions for (std::set<LLUUID>::iterator motion_it = motions_to_kill.begin(); motion_it != motions_to_kill.end(); @@ -234,8 +230,28 @@ void LLMotionController::addLoadedMotion(LLMotion* motionp) } } - // add new motion to loaded list - mLoadedMotions.push_back(motionp); + if (mLoadedMotions.size() > 2*MAX_MOTION_INSTANCES) + { + LL_WARNS_ONCE("Animation") << "> " << 2*MAX_MOTION_INSTANCES << " Loaded Motions" << llendl; + } +} + +//----------------------------------------------------------------------------- +// deactivateStoppedMotions() +//----------------------------------------------------------------------------- +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); + } + } } //----------------------------------------------------------------------------- @@ -252,9 +268,10 @@ void LLMotionController::setTimeStep(F32 step) iter != mActiveMotions.end(); ++iter) { LLMotion* motionp = *iter; - motionp->mActivationTimestamp = (F32)llfloor(motionp->mActivationTimestamp / step) * step; + 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->setStopTime((F32)(llfloor(motionp->getStopTime() / step)) * step); motionp->setStopped(stopped); motionp->mSendStopTimestamp = (F32)llfloor(motionp->mSendStopTimestamp / step) * step; } @@ -266,7 +283,6 @@ void LLMotionController::setTimeStep(F32 step) //----------------------------------------------------------------------------- void LLMotionController::setTimeFactor(F32 time_factor) { - mTimeOffset += mTimer.getElapsedTimeAndResetF32() * mTimeFactor; mTimeFactor = time_factor; } @@ -280,11 +296,11 @@ void LLMotionController::setCharacter(LLCharacter *character) //----------------------------------------------------------------------------- -// addMotion() +// registerMotion() //----------------------------------------------------------------------------- -BOOL LLMotionController::addMotion( const LLUUID& id, LLMotionConstructor constructor ) +BOOL LLMotionController::registerMotion( const LLUUID& id, LLMotionConstructor constructor ) { - return sRegistry.addMotion(id, constructor); + return sRegistry.registerMotion(id, constructor); } //----------------------------------------------------------------------------- @@ -293,10 +309,8 @@ BOOL LLMotionController::addMotion( const LLUUID& id, LLMotionConstructor constr void LLMotionController::removeMotion( const LLUUID& id) { LLMotion* motionp = findMotion(id); - - removeMotionInstance(motionp); - mAllMotions.erase(id); + removeMotionInstance(motionp); } // removes instance of a motion from all runtime structures, but does @@ -306,10 +320,11 @@ void LLMotionController::removeMotionInstance(LLMotion* motionp) { if (motionp) { - stopMotionInstance(motionp, TRUE); - + llassert(findMotion(motionp->getID()) != motionp); + if (motionp->isActive()) + motionp->deactivate(); mLoadingMotions.erase(motionp); - mLoadedMotions.remove(motionp); + mLoadedMotions.erase(motionp); mActiveMotions.remove(motionp); delete motionp; } @@ -320,6 +335,7 @@ void LLMotionController::removeMotionInstance(LLMotion* motionp) //----------------------------------------------------------------------------- LLMotion* LLMotionController::createMotion( const LLUUID &id ) { + LLMemType mt(LLMemType::MTYPE_ANIMATION); // do we have an instance of this motion for this character? LLMotion *motion = findMotion(id); @@ -353,8 +369,8 @@ LLMotion* LLMotionController::createMotion( const LLUUID &id ) mLoadingMotions.insert(motion); break; case LLMotion::STATUS_SUCCESS: - // add motion to our list - addLoadedMotion(motion); + // add motion to our list + mLoadedMotions.insert(motion); break; default: llerrs << "Invalid initialization status" << llendl; @@ -377,6 +393,7 @@ BOOL LLMotionController::startMotion(const LLUUID &id, F32 start_offset) // 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)) @@ -403,7 +420,7 @@ BOOL LLMotionController::startMotion(const LLUUID &id, F32 start_offset) } // llinfos << "Starting motion " << name << llendl; - return activateMotionInstance(motion, mTime - start_offset); + return activateMotionInstance(motion, mAnimTime - start_offset); } @@ -414,7 +431,6 @@ BOOL LLMotionController::stopMotionLocally(const LLUUID &id, BOOL stop_immediate { // if already inactive, return false LLMotion *motion = findMotion(id); - return stopMotionInstance(motion, stop_immediate); } @@ -425,15 +441,11 @@ BOOL LLMotionController::stopMotionInstance(LLMotion* motion, BOOL stop_immediat return FALSE; } + // If on active list, stop it if (isMotionActive(motion) && !motion->isStopped()) { - // when using timesteps, set stop time to last frame's time, otherwise grab current timer value - // *FIX: should investigate this inconsistency...hints of obscure bugs - - F32 stop_time = (mTimeStep != 0.f || mPaused) ? (mTime) : mTimeOffset + (mTimer.getElapsedTimeF32() * mTimeFactor); - motion->setStopTime(stop_time); - + motion->setStopTime(mAnimTime); if (stop_immediate) { deactivateMotionInstance(motion); @@ -449,7 +461,6 @@ BOOL LLMotionController::stopMotionInstance(LLMotion* motion, BOOL stop_immediat return FALSE; } - //----------------------------------------------------------------------------- // updateRegularMotions() //----------------------------------------------------------------------------- @@ -476,6 +487,59 @@ void LLMotionController::resetJointSignatures() } //----------------------------------------------------------------------------- +// updateIdleMotion() +// minimal updates for active motions +//----------------------------------------------------------------------------- +void LLMotionController::updateIdleMotion(LLMotion* motionp) +{ + 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(); + } + } +} + +//----------------------------------------------------------------------------- +// updateIdleActiveMotions() +// Call this instead of updateMotionsByType for hidden avatars +//----------------------------------------------------------------------------- +void LLMotionController::updateIdleActiveMotions() +{ + for (motion_list_t::iterator iter = mActiveMotions.begin(); + iter != mActiveMotions.end(); ) + { + motion_list_t::iterator curiter = iter++; + LLMotion* motionp = *curiter; + updateIdleMotion(motionp); + } +} + +//----------------------------------------------------------------------------- // updateMotionsByType() //----------------------------------------------------------------------------- void LLMotionController::updateMotionsByType(LLMotion::LLMotionBlendType anim_type) @@ -530,36 +594,7 @@ void LLMotionController::updateMotionsByType(LLMotion::LLMotionBlendType anim_ty if (!update_motion) { - if (motionp->isStopped() && mTime > motionp->getStopTime() + motionp->getEaseOutDuration()) - { - deactivateMotionInstance(motionp); - } - else if (motionp->isStopped() && mTime > 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 (mTime > 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 (mTime >= motionp->mActivationTimestamp) - { - if (mLastTime < motionp->mActivationTimestamp) - { - motionp->mResidualWeight = motionp->getPose()->getWeight(); - } - } + updateIdleMotion(motionp); continue; } @@ -571,7 +606,7 @@ void LLMotionController::updateMotionsByType(LLMotion::LLMotionBlendType anim_ty motionp->fadeOut(); //should we notify the simulator that this motion should be stopped (check even if skipped by LOD logic) - if (mTime > motionp->mSendStopTimestamp) + 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) @@ -584,7 +619,7 @@ void LLMotionController::updateMotionsByType(LLMotion::LLMotionBlendType anim_ty if (motionp->getFadeWeight() < 0.01f) { - if (motionp->isStopped() && mTime > motionp->getStopTime() + motionp->getEaseOutDuration()) + if (motionp->isStopped() && mAnimTime > motionp->getStopTime() + motionp->getEaseOutDuration()) { posep->setWeight(0.f); deactivateMotionInstance(motionp); @@ -600,7 +635,7 @@ void LLMotionController::updateMotionsByType(LLMotion::LLMotionBlendType anim_ty //********************** // MOTION INACTIVE //********************** - if (motionp->isStopped() && mTime > motionp->getStopTime() + motionp->getEaseOutDuration()) + 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? @@ -622,7 +657,7 @@ void LLMotionController::updateMotionsByType(LLMotion::LLMotionBlendType anim_ty //********************** // MOTION EASE OUT //********************** - else if (motionp->isStopped() && mTime > motionp->getStopTime()) + else if (motionp->isStopped() && mAnimTime > motionp->getStopTime()) { // is this the first iteration in the ease out phase? if (mLastTime <= motionp->getStopTime()) @@ -637,22 +672,22 @@ void LLMotionController::updateMotionsByType(LLMotion::LLMotionBlendType anim_ty } else { - posep->setWeight(motionp->getFadeWeight() * motionp->mResidualWeight * cubic_step(1.f - ((mTime - motionp->getStopTime()) / motionp->getEaseOutDuration()))); + posep->setWeight(motionp->getFadeWeight() * motionp->mResidualWeight * cubic_step(1.f - ((mAnimTime - motionp->getStopTime()) / motionp->getEaseOutDuration()))); } // perform motion update - update_result = motionp->onUpdate(mTime - motionp->mActivationTimestamp, last_joint_signature); + update_result = motionp->onUpdate(mAnimTime - motionp->mActivationTimestamp, last_joint_signature); } //********************** // MOTION ACTIVE //********************** - else if (mTime > motionp->mActivationTimestamp + motionp->getEaseInDuration()) + else if (mAnimTime > motionp->mActivationTimestamp + motionp->getEaseInDuration()) { posep->setWeight(motionp->getFadeWeight()); //should we notify the simulator that this motion should be stopped? - if (mTime > motionp->mSendStopTimestamp) + 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) @@ -664,13 +699,13 @@ void LLMotionController::updateMotionsByType(LLMotion::LLMotionBlendType anim_ty } // perform motion update - update_result = motionp->onUpdate(mTime - motionp->mActivationTimestamp, last_joint_signature); + update_result = motionp->onUpdate(mAnimTime - motionp->mActivationTimestamp, last_joint_signature); } //********************** // MOTION EASE IN //********************** - else if (mTime >= motionp->mActivationTimestamp) + else if (mAnimTime >= motionp->mActivationTimestamp) { if (mLastTime < motionp->mActivationTimestamp) { @@ -683,10 +718,10 @@ void LLMotionController::updateMotionsByType(LLMotion::LLMotionBlendType anim_ty else { // perform motion update - posep->setWeight(motionp->getFadeWeight() * motionp->mResidualWeight + (1.f - motionp->mResidualWeight) * cubic_step((mTime - motionp->mActivationTimestamp) / motionp->getEaseInDuration())); + posep->setWeight(motionp->getFadeWeight() * motionp->mResidualWeight + (1.f - motionp->mResidualWeight) * cubic_step((mAnimTime - motionp->mActivationTimestamp) / motionp->getEaseInDuration())); } // perform motion update - update_result = motionp->onUpdate(mTime - motionp->mActivationTimestamp, last_joint_signature); + update_result = motionp->onUpdate(mAnimTime - motionp->mActivationTimestamp, last_joint_signature); } else { @@ -697,7 +732,7 @@ void LLMotionController::updateMotionsByType(LLMotion::LLMotionBlendType anim_ty // allow motions to deactivate themselves if (!update_result) { - if (!motionp->isStopped() || motionp->getStopTime() > mTime) + if (!motionp->isStopped() || motionp->getStopTime() > mAnimTime) { // animation has stopped itself due to internal logic // propagate this to the network @@ -713,18 +748,73 @@ void LLMotionController::updateMotionsByType(LLMotion::LLMotionBlendType anim_ty } } +//----------------------------------------------------------------------------- +// updateLoadingMotions() +//----------------------------------------------------------------------------- +void LLMotionController::updateLoadingMotions() +{ + // 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) + { + llinfos << "Motion " << motionp->getID() << " init failed." << llendl; + 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; + } + } +} + +//----------------------------------------------------------------------------- +// call updateMotion() or updateMotionsMinimal() every frame +//----------------------------------------------------------------------------- //----------------------------------------------------------------------------- // updateMotion() //----------------------------------------------------------------------------- -void LLMotionController::updateMotion() +void LLMotionController::updateMotions(bool force_update) { 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 = mTimeOffset + (mTimer.getElapsedTimeF32() * mTimeFactor); + F32 update_time = mAnimTime + delta_time * mTimeFactor; if (use_quantum) { F32 time_interval = fmodf(update_time, mTimeStep); @@ -740,7 +830,8 @@ void LLMotionController::updateMotion() mPoseBlender.interpolate(interp - mLastInterp); mLastInterp = interp; } - + + updateLoadingMotions(); return; } @@ -749,53 +840,24 @@ void LLMotionController::updateMotion() clearBlenders(); mTimeStepCount = quantum_count; - mLastTime = mTime; - mTime = (F32)quantum_count * mTimeStep; + mAnimTime = (F32)quantum_count * mTimeStep; mLastInterp = 0.f; } else { - mLastTime = mTime; - mTime = update_time; + mAnimTime = update_time; } } - // 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 - addLoadedMotion(motionp); - // this motion should be playing - if (!motionp->isStopped()) - { - activateMotionInstance(motionp, mTime); - } - } - else if (status == LLMotion::STATUS_FAILURE) - { - llinfos << "Motion " << motionp->getID() << " init failed." << llendl; - sRegistry.markBad(motionp->getID()); - mLoadingMotions.erase(curiter); - - mAllMotions.erase(motionp->getID()); - delete motionp; - } - } + updateLoadingMotions(); resetJointSignatures(); - if (!mPaused) + if (mPaused && !force_update) + { + updateIdleActiveMotions(); + } + else { // update additive motions updateAdditiveMotions(); @@ -818,6 +880,23 @@ void LLMotionController::updateMotion() // llinfos << "Motion controller time " << motionTimer.getElapsedTimeF32() << llendl; } +//----------------------------------------------------------------------------- +// updateMotionsMinimal() +// minimal update (e.g. while hidden) +//----------------------------------------------------------------------------- +void LLMotionController::updateMotionsMinimal() +{ + // Always update mPrevTimerElapsed + mPrevTimerElapsed = mTimer.getElapsedTimeF32(); + + purgeExcessMotions(); + updateLoadingMotions(); + resetJointSignatures(); + + deactivateStoppedMotions(); + + mHasRunOnce = TRUE; +} //----------------------------------------------------------------------------- // activateMotionInstance() @@ -840,7 +919,6 @@ BOOL LLMotionController::activateMotionInstance(LLMotion *motion, F32 time) } motion->mResidualWeight = motion->getPose()->getWeight(); - motion->mActivationTimestamp = time; // set stop time based on given duration and ease out time if (motion->getDuration() != 0.f && !motion->getLoop()) @@ -861,13 +939,26 @@ BOOL LLMotionController::activateMotionInstance(LLMotion *motion, F32 time) { motion->mSendStopTimestamp = F32_MAX; } - - mActiveMotions.remove(motion); // in case it is already in the active list + + if (motion->isActive()) + { + mActiveMotions.remove(motion); + } mActiveMotions.push_front(motion); - motion->activate(); + 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; } @@ -924,9 +1015,42 @@ bool LLMotionController::isMotionLoading(LLMotion* motion) //----------------------------------------------------------------------------- // findMotion() //----------------------------------------------------------------------------- -LLMotion *LLMotionController::findMotion(const LLUUID& id) +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; + } +} + +//----------------------------------------------------------------------------- +// dumpMotions() +//----------------------------------------------------------------------------- +void LLMotionController::dumpMotions() { - return get_if_there<LLUUID, LLMotion*>(mAllMotions, id, NULL); + llinfos << "=====================================" << llendl; + for (motion_map_t::iterator iter = mAllMotions.begin(); + iter != mAllMotions.end(); iter++) + { + LLUUID id = iter->first; + std::string state_string; + LLMotion *motion = iter->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"); + llinfos << gAnimLibrary.animationName(id) << " " << state_string << llendl; + + } } //----------------------------------------------------------------------------- @@ -934,16 +1058,12 @@ LLMotion *LLMotionController::findMotion(const LLUUID& id) //----------------------------------------------------------------------------- void LLMotionController::deactivateAllMotions() { - //They must all die, precious. - for (std::map<LLUUID, LLMotion*>::iterator iter = mAllMotions.begin(); + for (motion_map_t::iterator iter = mAllMotions.begin(); iter != mAllMotions.end(); iter++) { LLMotion* motionp = iter->second; - if (motionp) motionp->deactivate(); + deactivateMotionInstance(motionp); } - - // delete all motion instances - deleteAllMotions(); } @@ -959,11 +1079,12 @@ void LLMotionController::flushAllMotions() { motion_list_t::iterator curiter = iter++; LLMotion* motionp = *curiter; - F32 dtime = mTime - motionp->mActivationTimestamp; + F32 dtime = mAnimTime - motionp->mActivationTimestamp; active_motions.push_back(std::make_pair(motionp->getID(),dtime)); - motionp->deactivate(); + motionp->deactivate(); // don't call deactivateMotionInstance() because we are going to reactivate it } - + mActiveMotions.clear(); + // delete all motion instances deleteAllMotions(); @@ -982,12 +1103,11 @@ void LLMotionController::flushAllMotions() //----------------------------------------------------------------------------- // pause() //----------------------------------------------------------------------------- -void LLMotionController::pause() +void LLMotionController::pauseAllMotions() { if (!mPaused) { //llinfos << "Pausing animations..." << llendl; - mPauseTime = mTimer.getElapsedTimeF32(); mPaused = TRUE; } @@ -996,13 +1116,11 @@ void LLMotionController::pause() //----------------------------------------------------------------------------- // unpause() //----------------------------------------------------------------------------- -void LLMotionController::unpause() +void LLMotionController::unpauseAllMotions() { if (mPaused) { //llinfos << "Unpausing animations..." << llendl; - mTimer.reset(); - mTimer.setAge(mPauseTime); mPaused = FALSE; } } diff --git a/indra/llcharacter/llmotioncontroller.h b/indra/llcharacter/llmotioncontroller.h index effea0940a..b996f708d2 100644 --- a/indra/llcharacter/llmotioncontroller.h +++ b/indra/llcharacter/llmotioncontroller.h @@ -2,30 +2,25 @@ * @file llmotioncontroller.h * @brief Implementation of LLMotionController class. * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2007, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlife.com/developers/opensource/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at http://secondlife.com/developers/opensource/flossexception + * 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. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * 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. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * 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$ */ @@ -57,30 +52,6 @@ class LLCharacter; //----------------------------------------------------------------------------- typedef LLMotion*(*LLMotionConstructor)(const LLUUID &id); -class LLMotionTableEntry -{ -public: - LLMotionTableEntry(); - LLMotionTableEntry(LLMotionConstructor constructor, const LLUUID& id); - ~LLMotionTableEntry(){}; - - LLMotion* create(const LLUUID& id); - static BOOL uuidEq(const LLUUID &uuid, const LLMotionTableEntry &id_pair) - { - if (uuid == id_pair.mID) - { - return TRUE; - } - return FALSE; - } - - const LLUUID& getID() { return mID; } - -protected: - LLMotionConstructor mConstructor; - LLUUID mID; -}; - class LLMotionRegistry { public: @@ -92,7 +63,7 @@ public: // adds motion classes to the registry // returns true if successfull - BOOL addMotion( const LLUUID& id, LLMotionConstructor create); + BOOL registerMotion( const LLUUID& id, LLMotionConstructor create); // creates a new instance of a named motion // returns NULL motion is not registered @@ -103,7 +74,8 @@ public: protected: - LLUUIDHashMap<LLMotionTableEntry, 32> mMotionTable; + typedef std::map<LLUUID, LLMotionConstructor> motion_map_t; + motion_map_t mMotionTable; }; //----------------------------------------------------------------------------- @@ -114,6 +86,7 @@ class LLMotionController public: typedef std::list<LLMotion*> motion_list_t; typedef std::set<LLMotion*> motion_set_t; + BOOL mIsSelf; public: // Constructor @@ -130,7 +103,7 @@ public: // registers a motion with the controller // (actually just forwards call to motion registry) // returns true if successfull - BOOL addMotion( const LLUUID& id, LLMotionConstructor create ); + BOOL registerMotion( const LLUUID& id, LLMotionConstructor create ); // creates a motion from the registry LLMotion *createMotion( const LLUUID &id ); @@ -151,11 +124,17 @@ public: // 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 updateMotion(); + void updateMotions(bool force_update = false); + + // minimal update (e.g. while hidden) + void updateMotionsMinimal(); void clearBlenders() { mPoseBlender.clearBlenders(); } @@ -167,27 +146,32 @@ public: void deactivateAllMotions(); // pause and continue all motions - void pause(); - void unpause(); - BOOL isPaused() { return mPaused; } + void pauseAllMotions(); + void unpauseAllMotions(); + BOOL isPaused() const { return mPaused; } void setTimeStep(F32 step); void setTimeFactor(F32 time_factor); - F32 getTimeFactor() { return mTimeFactor; } + F32 getTimeFactor() const { return mTimeFactor; } 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 ); + LLMotion *findMotion( const LLUUID& id ) const; + + void dumpMotions(); + + const LLFrameTimer& getFrameTimer() { return mTimer; } protected: // internal operations act on motion instances directly // as there can be duplicate motions per id during blending overlap void deleteAllMotions(); - void addLoadedMotion(LLMotion *motion); BOOL activateMotionInstance(LLMotion *motion, F32 time); BOOL deactivateMotionInstance(LLMotion *motion); void deprecateMotionInstance(LLMotion* motion); @@ -197,6 +181,10 @@ protected: void updateAdditiveMotions(); void resetJointSignatures(); void updateMotionsByType(LLMotion::LLMotionBlendType motion_type); + void updateIdleMotion(LLMotion* motionp); + void updateIdleActiveMotions(); + void purgeExcessMotions(); + void deactivateStoppedMotions(); protected: F32 mTimeFactor; @@ -210,27 +198,27 @@ protected: // 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 deque. +// 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_list_t mLoadedMotions; + motion_set_t mLoadedMotions; motion_list_t mActiveMotions; motion_set_t mDeprecatedMotions; LLFrameTimer mTimer; - F32 mTime; - F32 mTimeOffset; + F32 mPrevTimerElapsed; + F32 mAnimTime; F32 mLastTime; BOOL mHasRunOnce; BOOL mPaused; + F32 mPauseTime; F32 mTimeStep; S32 mTimeStepCount; F32 mLastInterp; - F32 mPauseTime; U8 mJointSignature[2][LL_CHARACTER_MAX_JOINTS]; }; diff --git a/indra/llcharacter/llmultigesture.cpp b/indra/llcharacter/llmultigesture.cpp index d8db060a0c..e2d284834f 100644 --- a/indra/llcharacter/llmultigesture.cpp +++ b/indra/llcharacter/llmultigesture.cpp @@ -2,30 +2,25 @@ * @file llmultigesture.cpp * @brief Gestures that are asset-based and can have multiple steps. * - * $LicenseInfo:firstyear=2004&license=viewergpl$ - * - * Copyright (c) 2004-2007, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2004&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlife.com/developers/opensource/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at http://secondlife.com/developers/opensource/flossexception + * 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. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * 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. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * 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$ */ @@ -49,6 +44,7 @@ const S32 GESTURE_VERSION = 2; LLMultiGesture::LLMultiGesture() : mKey(), mMask(), + mName(), mTrigger(), mReplaceText(), mSteps(), @@ -124,8 +120,8 @@ BOOL LLMultiGesture::serialize(LLDataPacker& dp) const dp.packS32(GESTURE_VERSION, "version"); dp.packU8(mKey, "key"); dp.packU32(mMask, "mask"); - dp.packString(mTrigger.c_str(), "trigger"); - dp.packString(mReplaceText.c_str(), "replace"); + dp.packString(mTrigger, "trigger"); + dp.packString(mReplaceText, "replace"); S32 count = (S32)mSteps.size(); dp.packS32(count, "step_count"); @@ -242,7 +238,7 @@ void LLMultiGesture::dump() //--------------------------------------------------------------------------- LLGestureStepAnimation::LLGestureStepAnimation() : LLGestureStep(), - mAnimName("None"), + mAnimName("None"), mAnimAssetID(), mFlags(0x0) { } @@ -269,7 +265,7 @@ S32 LLGestureStepAnimation::getMaxSerialSize() const BOOL LLGestureStepAnimation::serialize(LLDataPacker& dp) const { - dp.packString(mAnimName.c_str(), "anim_name"); + dp.packString(mAnimName, "anim_name"); dp.packUUID(mAnimAssetID, "asset_id"); dp.packU32(mFlags, "flags"); return TRUE; @@ -291,20 +287,27 @@ BOOL LLGestureStepAnimation::deserialize(LLDataPacker& dp) dp.unpackU32(mFlags, "flags"); return TRUE; } - -std::string LLGestureStepAnimation::getLabel() const +// *NOTE: result is translated in LLPreviewGesture::getLabel() +std::vector<std::string> LLGestureStepAnimation::getLabel() const { - std::string label; + std::vector<std::string> strings; + +// std::string label; if (mFlags & ANIM_FLAG_STOP) { - label = "Stop Animation: "; + strings.push_back( "AnimFlagStop"); + +// label = "Stop Animation: "; } else { - label = "Start Animation: "; + strings.push_back( "AnimFlagStart"); + +// label = "Start Animation: "; } - label += mAnimName; - return label; + strings.push_back( mAnimName); +// label += mAnimName; + return strings; } void LLGestureStepAnimation::dump() @@ -344,7 +347,7 @@ S32 LLGestureStepSound::getMaxSerialSize() const BOOL LLGestureStepSound::serialize(LLDataPacker& dp) const { - dp.packString(mSoundName.c_str(), "sound_name"); + dp.packString(mSoundName, "sound_name"); dp.packUUID(mSoundAssetID, "asset_id"); dp.packU32(mFlags, "flags"); return TRUE; @@ -358,12 +361,15 @@ BOOL LLGestureStepSound::deserialize(LLDataPacker& dp) dp.unpackU32(mFlags, "flags"); return TRUE; } - -std::string LLGestureStepSound::getLabel() const +// *NOTE: result is translated in LLPreviewGesture::getLabel() +std::vector<std::string> LLGestureStepSound::getLabel() const { - std::string label("Sound: "); - label += mSoundName; - return label; + std::vector<std::string> strings; + strings.push_back( "Sound"); + strings.push_back( mSoundName); +// std::string label("Sound: "); +// label += mSoundName; + return strings; } void LLGestureStepSound::dump() @@ -401,7 +407,7 @@ S32 LLGestureStepChat::getMaxSerialSize() const BOOL LLGestureStepChat::serialize(LLDataPacker& dp) const { - dp.packString(mChatText.c_str(), "chat_text"); + dp.packString(mChatText, "chat_text"); dp.packU32(mFlags, "flags"); return TRUE; } @@ -413,12 +419,13 @@ BOOL LLGestureStepChat::deserialize(LLDataPacker& dp) dp.unpackU32(mFlags, "flags"); return TRUE; } - -std::string LLGestureStepChat::getLabel() const +// *NOTE: result is translated in LLPreviewGesture::getLabel() +std::vector<std::string> LLGestureStepChat::getLabel() const { - std::string label("Chat: "); - label += mChatText; - return label; + std::vector<std::string> strings; + strings.push_back("Chat"); + strings.push_back(mChatText); + return strings; } void LLGestureStepChat::dump() @@ -466,22 +473,31 @@ BOOL LLGestureStepWait::deserialize(LLDataPacker& dp) dp.unpackU32(mFlags, "flags"); return TRUE; } - -std::string LLGestureStepWait::getLabel() const +// *NOTE: result is translated in LLPreviewGesture::getLabel() +std::vector<std::string> LLGestureStepWait::getLabel() const { - std::string label("--- Wait: "); + 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 */ - label += buffer; + strings.push_back(buffer); +// label += buffer; } else if (mFlags & WAIT_FLAG_ALL_ANIM) { - label += "until animations are done"; + strings.push_back("until animations are done"); + // label += "until animations are done"; + } + else + { + strings.push_back(""); } - return label; + return strings; } diff --git a/indra/llcharacter/llmultigesture.h b/indra/llcharacter/llmultigesture.h index 84ca64198b..92820159d4 100644 --- a/indra/llcharacter/llmultigesture.h +++ b/indra/llcharacter/llmultigesture.h @@ -2,30 +2,25 @@ * @file llmultigesture.h * @brief Gestures that are asset-based and can have multiple steps. * - * $LicenseInfo:firstyear=2004&license=viewergpl$ - * - * Copyright (c) 2004-2007, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2004&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlife.com/developers/opensource/gplv2 + * 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. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at http://secondlife.com/developers/opensource/flossexception + * 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. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * 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 * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -64,11 +59,13 @@ protected: const LLMultiGesture& operator=(const LLMultiGesture& rhs); public: - // name is stored at asset level - // desc is stored at asset level KEY mKey; MASK mMask; + // 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; + // String, like "/foo" or "hello" that makes it play std::string mTrigger; @@ -107,6 +104,8 @@ public: }; +// Order must match the library_list in floater_preview_gesture.xml! + enum EStepType { STEP_ANIMATION = 0, @@ -127,7 +126,7 @@ public: virtual EStepType getType() = 0; // Return a user-readable label for this step - virtual std::string getLabel() const = 0; + virtual std::vector<std::string> getLabel() const = 0; virtual S32 getMaxSerialSize() const = 0; virtual BOOL serialize(LLDataPacker& dp) const = 0; @@ -149,7 +148,7 @@ public: virtual EStepType getType() { return STEP_ANIMATION; } - virtual std::string getLabel() const; + virtual std::vector<std::string> getLabel() const; virtual S32 getMaxSerialSize() const; virtual BOOL serialize(LLDataPacker& dp) const; @@ -172,7 +171,7 @@ public: virtual EStepType getType() { return STEP_SOUND; } - virtual std::string getLabel() const; + virtual std::vector<std::string> getLabel() const; virtual S32 getMaxSerialSize() const; virtual BOOL serialize(LLDataPacker& dp) const; @@ -195,7 +194,7 @@ public: virtual EStepType getType() { return STEP_CHAT; } - virtual std::string getLabel() const; + virtual std::vector<std::string> getLabel() const; virtual S32 getMaxSerialSize() const; virtual BOOL serialize(LLDataPacker& dp) const; @@ -220,7 +219,7 @@ public: virtual EStepType getType() { return STEP_WAIT; } - virtual std::string getLabel() const; + virtual std::vector<std::string> getLabel() const; virtual S32 getMaxSerialSize() const; virtual BOOL serialize(LLDataPacker& dp) const; diff --git a/indra/llcharacter/llpose.cpp b/indra/llcharacter/llpose.cpp index 2120cb223e..55e1b6e9ea 100644 --- a/indra/llcharacter/llpose.cpp +++ b/indra/llcharacter/llpose.cpp @@ -2,30 +2,25 @@ * @file llpose.cpp * @brief Implementation of LLPose class. * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2007, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlife.com/developers/opensource/gplv2 + * 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. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at http://secondlife.com/developers/opensource/flossexception + * 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. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * 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 * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -188,6 +183,7 @@ LLJointStateBlender::LLJointStateBlender() { mJointStates[i] = NULL; mPriorities[i] = S32_MIN; + mAdditiveBlends[i] = FALSE; } } @@ -458,6 +454,7 @@ void LLJointStateBlender::resetCachedJoint() //----------------------------------------------------------------------------- LLPoseBlender::LLPoseBlender() + : mNextPoseSlot(0) { } @@ -513,9 +510,9 @@ BOOL LLPoseBlender::addMotion(LLMotion* motion) void LLPoseBlender::blendAndApply() { for (blender_list_t::iterator iter = mActiveBlenders.begin(); - iter != mActiveBlenders.end(); ++iter) + iter != mActiveBlenders.end(); ) { - LLJointStateBlender* jsbp = *iter; + LLJointStateBlender* jsbp = *iter++; jsbp->blendJointStates(); } diff --git a/indra/llcharacter/llpose.h b/indra/llcharacter/llpose.h index 0c71fd77b3..b486852605 100644 --- a/indra/llcharacter/llpose.h +++ b/indra/llcharacter/llpose.h @@ -2,30 +2,25 @@ * @file llpose.h * @brief Implementation of LLPose class. * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2007, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlife.com/developers/opensource/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at http://secondlife.com/developers/opensource/flossexception + * 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. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * 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. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * 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,12 +30,14 @@ //----------------------------------------------------------------------------- // Header Files //----------------------------------------------------------------------------- -#include <string> -#include "llmap.h" #include "lljointstate.h" #include "lljoint.h" +#include "llmap.h" +#include "llpointer.h" + #include <map> +#include <string> //----------------------------------------------------------------------------- diff --git a/indra/llcharacter/llstatemachine.cpp b/indra/llcharacter/llstatemachine.cpp index b3432b2b49..e0454131a5 100644 --- a/indra/llcharacter/llstatemachine.cpp +++ b/indra/llcharacter/llstatemachine.cpp @@ -2,30 +2,25 @@ * @file llstatemachine.cpp * @brief LLStateMachine implementation file. * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2007, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlife.com/developers/opensource/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at http://secondlife.com/developers/opensource/flossexception + * 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. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * 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. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * 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$ */ @@ -53,6 +48,7 @@ bool operator!=(const LLUniqueID &a, const LLUniqueID &b) //----------------------------------------------------------------------------- LLStateDiagram::LLStateDiagram() { + mDefaultState = NULL; mUseDefaultState = FALSE; } @@ -206,9 +202,11 @@ LLFSMState* LLStateDiagram::getState(U32 state_id) return NULL; } -BOOL LLStateDiagram::saveDotFile(const char* filename) +BOOL LLStateDiagram::saveDotFile(const std::string& filename) { - apr_file_t* dot_file = ll_apr_file_open(filename, LL_APR_W); + LLAPRFile outfile ; + outfile.open(filename, LL_APR_W); + apr_file_t* dot_file = outfile.getFileHandle() ; if (!dot_file) { @@ -257,8 +255,6 @@ BOOL LLStateDiagram::saveDotFile(const char* filename) apr_file_printf(dot_file, "}\n"); - apr_file_close(dot_file); - return TRUE; } @@ -304,6 +300,7 @@ LLStateMachine::LLStateMachine() // we haven't received a starting state yet mCurrentState = NULL; mLastState = NULL; + mLastTransition = NULL; mStateDiagram = NULL; } diff --git a/indra/llcharacter/llstatemachine.h b/indra/llcharacter/llstatemachine.h index c19a926dbb..a2f7e59bd2 100644 --- a/indra/llcharacter/llstatemachine.h +++ b/indra/llcharacter/llstatemachine.h @@ -2,30 +2,25 @@ * @file llstatemachine.h * @brief LLStateMachine class header file. * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2007, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlife.com/developers/opensource/gplv2 + * 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. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at http://secondlife.com/developers/opensource/flossexception + * 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. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * 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 * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -54,7 +49,7 @@ class LLFSMTransition : public LLUniqueID { public: LLFSMTransition() : LLUniqueID(){}; - virtual std::string getName(){ return "unnamed"; } + virtual std::string getName()const { return "unnamed"; } }; class LLFSMState : public LLUniqueID @@ -64,7 +59,7 @@ public: virtual void onEntry(void *){}; virtual void onExit(void *){}; virtual void execute(void *){}; - virtual std::string getName(){ return "unnamed"; } + virtual std::string getName() const { return "unnamed"; } }; class LLStateDiagram @@ -115,7 +110,7 @@ protected: public: // save the graph in a DOT file for rendering and visualization - BOOL saveDotFile(const char* filename); + BOOL saveDotFile(const std::string& filename); }; class LLStateMachine diff --git a/indra/llcharacter/lltargetingmotion.cpp b/indra/llcharacter/lltargetingmotion.cpp index c0ce11cb85..489aef923c 100644 --- a/indra/llcharacter/lltargetingmotion.cpp +++ b/indra/llcharacter/lltargetingmotion.cpp @@ -2,30 +2,25 @@ * @file lltargetingmotion.cpp * @brief Implementation of LLTargetingMotion class. * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2007, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlife.com/developers/opensource/gplv2 + * 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. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at http://secondlife.com/developers/opensource/flossexception + * 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. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * 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 * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ diff --git a/indra/llcharacter/lltargetingmotion.h b/indra/llcharacter/lltargetingmotion.h index d72a8b11ec..0971417e1e 100644 --- a/indra/llcharacter/lltargetingmotion.h +++ b/indra/llcharacter/lltargetingmotion.h @@ -2,30 +2,25 @@ * @file lltargetingmotion.h * @brief Implementation of LLTargetingMotion class. * - * $LicenseInfo:firstyear=2002&license=viewergpl$ - * - * Copyright (c) 2002-2007, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2002&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlife.com/developers/opensource/gplv2 + * 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. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at http://secondlife.com/developers/opensource/flossexception + * 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. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * 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 * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ diff --git a/indra/llcharacter/llvisualparam.cpp b/indra/llcharacter/llvisualparam.cpp index 065bf9fabd..809b312abe 100644 --- a/indra/llcharacter/llvisualparam.cpp +++ b/indra/llcharacter/llvisualparam.cpp @@ -2,30 +2,25 @@ * @file llvisualparam.cpp * @brief Implementation of LLPolyMesh class. * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2007, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlife.com/developers/opensource/gplv2 + * 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. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at http://secondlife.com/developers/opensource/flossexception + * 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. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * 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 * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -89,7 +84,7 @@ BOOL LLVisualParamInfo::parseXml(LLXmlTreeNode *node) } // attribute: sex - LLString sex = "both"; + std::string sex = "both"; static LLStdStringHandle sex_string = LLXmlTree::addAttributeString("sex"); node->getFastAttributeString( sex_string, sex ); // optional if( sex == "both" ) @@ -127,7 +122,7 @@ BOOL LLVisualParamInfo::parseXml(LLXmlTreeNode *node) // JC - make sure the display name includes the capitalization in the XML file, // not the lowercased version. - LLString::toLower(mName); + LLStringUtil::toLower(mName); // attribute: label_min static LLStdStringHandle label_min_string = LLXmlTree::addAttributeString("label_min"); @@ -146,6 +141,21 @@ BOOL LLVisualParamInfo::parseXml(LLXmlTreeNode *node) 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"; +} + //----------------------------------------------------------------------------- // LLVisualParam() //----------------------------------------------------------------------------- @@ -157,7 +167,8 @@ LLVisualParam::LLVisualParam() mTargetWeight( 0.f ), mIsAnimating( FALSE ), mID( -1 ), - mInfo( 0 ) + mInfo( 0 ), + mIsDummy(FALSE) { } @@ -208,7 +219,7 @@ BOOL LLVisualParam::parseData(LLXmlTreeNode *node) //----------------------------------------------------------------------------- // setWeight() //----------------------------------------------------------------------------- -void LLVisualParam::setWeight(F32 weight, BOOL set_by_user) +void LLVisualParam::setWeight(F32 weight, BOOL upload_bake) { if (mIsAnimating) { @@ -226,18 +237,25 @@ void LLVisualParam::setWeight(F32 weight, BOOL set_by_user) if (mNext) { - mNext->setWeight(weight, set_by_user); + mNext->setWeight(weight, upload_bake); } } //----------------------------------------------------------------------------- // setAnimationTarget() //----------------------------------------------------------------------------- -void LLVisualParam::setAnimationTarget(F32 target_value, BOOL set_by_user) +void LLVisualParam::setAnimationTarget(F32 target_value, BOOL upload_bake) { + // don't animate dummy parameters + if (mIsDummy) + { + setWeight(target_value, upload_bake); + return; + } + if (mInfo) { - if (getGroup() == VISUAL_PARAM_GROUP_TWEAKABLE) + if (isTweakable()) { mTargetWeight = llclamp(target_value, mInfo->mMinWeight, mInfo->mMaxWeight); } @@ -250,7 +268,7 @@ void LLVisualParam::setAnimationTarget(F32 target_value, BOOL set_by_user) if (mNext) { - mNext->setAnimationTarget(target_value, set_by_user); + mNext->setAnimationTarget(target_value, upload_bake); } } @@ -260,30 +278,44 @@ void LLVisualParam::setAnimationTarget(F32 target_value, BOOL set_by_user) 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; } //----------------------------------------------------------------------------- // animate() //----------------------------------------------------------------------------- -void LLVisualParam::animate( F32 delta, BOOL set_by_user ) +void LLVisualParam::animate( F32 delta, BOOL upload_bake ) { if (mIsAnimating) { F32 new_weight = ((mTargetWeight - mCurWeight) * delta) + mCurWeight; - setWeight(new_weight, set_by_user); + setWeight(new_weight, upload_bake); } } //----------------------------------------------------------------------------- // stopAnimating() //----------------------------------------------------------------------------- -void LLVisualParam::stopAnimating(BOOL set_by_user) +void LLVisualParam::stopAnimating(BOOL upload_bake) { - if (mIsAnimating && getGroup() == VISUAL_PARAM_GROUP_TWEAKABLE) + if (mIsAnimating && isTweakable()) { mIsAnimating = FALSE; - setWeight(mTargetWeight, set_by_user); + setWeight(mTargetWeight, upload_bake); } } + +//virtual +BOOL LLVisualParam::linkDrivenParams(visual_param_mapper mapper, BOOL only_cross_params) +{ + // nothing to do for non-driver parameters + return TRUE; +} + +//virtual +void LLVisualParam::resetDrivenParams() +{ + // nothing to do for non-driver parameters + return; +} diff --git a/indra/llcharacter/llvisualparam.h b/indra/llcharacter/llvisualparam.h index 43911f4ed7..694e27f371 100644 --- a/indra/llcharacter/llvisualparam.h +++ b/indra/llcharacter/llvisualparam.h @@ -2,30 +2,25 @@ * @file llvisualparam.h * @brief Implementation of LLPolyMesh class. * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2007, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlife.com/developers/opensource/gplv2 + * 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. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at http://secondlife.com/developers/opensource/flossexception + * 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. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * 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 * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -35,6 +30,7 @@ #include "v3math.h" #include "llstring.h" #include "llxmltree.h" +#include <boost/function.hpp> class LLPolyMesh; class LLXmlTreeNode; @@ -50,6 +46,7 @@ enum EVisualParamGroup { VISUAL_PARAM_GROUP_TWEAKABLE, VISUAL_PARAM_GROUP_ANIMATABLE, + VISUAL_PARAM_GROUP_TWEAKABLE_NO_TRANSMIT, NUM_VISUAL_PARAM_GROUPS }; @@ -67,14 +64,18 @@ public: virtual ~LLVisualParamInfo() {}; virtual BOOL parseXml(LLXmlTreeNode *node); + + S32 getID() const { return mID; } + + virtual void toStream(std::ostream &out); protected: S32 mID; // ID associated with VisualParam - LLString mName; // name (for internal purposes) - LLString mDisplayName; // name displayed to the user - LLString mMinName; // name associated with minimum value - LLString mMaxName; // name associated with maximum value + 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 @@ -91,6 +92,8 @@ protected: class LLVisualParam { public: + typedef boost::function<LLVisualParam*(S32)> visual_param_mapper; + LLVisualParam(); virtual ~LLVisualParam(); @@ -105,40 +108,46 @@ public: //virtual BOOL parseData( LLXmlTreeNode *node ) = 0; virtual void apply( ESex avatar_sex ) = 0; // Default functions - virtual void setWeight(F32 weight, BOOL set_by_user); - virtual void setAnimationTarget( F32 target_value, BOOL set_by_user ); - virtual void animate(F32 delta, BOOL set_by_user); - virtual void stopAnimating(BOOL set_by_user); + virtual void setWeight(F32 weight, BOOL upload_bake); + virtual void setAnimationTarget( F32 target_value, BOOL upload_bake ); + virtual void animate(F32 delta, BOOL upload_bake); + virtual void stopAnimating(BOOL upload_bake); + + virtual BOOL linkDrivenParams(visual_param_mapper mapper, BOOL only_cross_params); + virtual void resetDrivenParams(); // Interface methods - S32 getID() { return mID; } + S32 getID() const { return mID; } void setID(S32 id) { llassert(!mInfo); mID = id; } - const LLString& getName() const { return mInfo->mName; } - const LLString& getDisplayName() const { return mInfo->mDisplayName; } - const LLString& getMaxDisplayName() const { return mInfo->mMaxName; } - const LLString& getMinDisplayName() const { return mInfo->mMinName; } - - void setDisplayName(const LLString& s) { mInfo->mDisplayName = s; } - void setMaxDisplayName(const LLString& s) { mInfo->mMaxName = s; } - void setMinDisplayName(const LLString& s) { mInfo->mMinName = s; } - - EVisualParamGroup getGroup() { return mInfo->mGroup; } - F32 getMinWeight() { return mInfo->mMinWeight; } - F32 getMaxWeight() { return mInfo->mMaxWeight; } - F32 getDefaultWeight() { return mInfo->mDefaultWeight; } - ESex getSex() { return mInfo->mSex; } - - F32 getWeight() { return mIsAnimating ? mTargetWeight : mCurWeight; } - F32 getCurrentWeight() { return mCurWeight; } - F32 getLastWeight() { return mLastWeight; } - BOOL isAnimating() { return mIsAnimating; } + 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; } + 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 ); - virtual void setAnimating(BOOL is_animating) { mIsAnimating = is_animating; } - BOOL getAnimating() { return mIsAnimating; } + virtual void setAnimating(BOOL is_animating) { mIsAnimating = is_animating && !mIsDummy; } + BOOL getAnimating() const { return mIsAnimating; } + + void setIsDummy(BOOL is_dummy) { mIsDummy = is_dummy; } protected: F32 mCurWeight; // current weight @@ -146,6 +155,8 @@ protected: 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; diff --git a/indra/llcharacter/tests/lljoint_test.cpp b/indra/llcharacter/tests/lljoint_test.cpp new file mode 100644 index 0000000000..e92aa832d6 --- /dev/null +++ b/indra/llcharacter/tests/lljoint_test.cpp @@ -0,0 +1,240 @@ +/** + * @file lljoint_test.cpp + * @author Adroit + * @date 2007-03 + * @brief lljoint test cases. + * + * $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$ + */ + +#include "linden_common.h" +#include "m4math.h" +#include "v3math.h" + +#include "../lljoint.h" + +#include "../test/lltut.h" + + +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); + 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); + 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>() + { + LLJoint lljoint("parent"); + S32 joint_num = 12; + lljoint.setJointNum(joint_num); + S32 jointNum = lljoint.getJointNum(); + ensure("setJointNum()/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(); + 5) LLXformMatrix *getXform() { return &mXform; } + 6) void setConstraintSilhouette(LLDynamicArray<LLVector3>& silhouette); + 7) void clampRotation(LLQuaternion old_rot, LLQuaternion new_rot); + + */ +} + |