PageRenderTime 63ms CodeModel.GetById 30ms app.highlight 16ms RepoModel.GetById 14ms app.codeStats 1ms

/indra/llcharacter/llhandmotion.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 220 lines | 127 code | 31 blank | 62 comment | 28 complexity | 3efe1b2be6f01875e0f8767d27fd9bf1 MD5 | raw file
  1/** 
  2 * @file llhandmotion.cpp
  3 * @brief Implementation of LLHandMotion class.
  4 *
  5 * $LicenseInfo:firstyear=2001&license=viewerlgpl$
  6 * Second Life Viewer Source Code
  7 * Copyright (C) 2010, Linden Research, Inc.
  8 * 
  9 * This library is free software; you can redistribute it and/or
 10 * modify it under the terms of the GNU Lesser General Public
 11 * License as published by the Free Software Foundation;
 12 * version 2.1 of the License only.
 13 * 
 14 * This library is distributed in the hope that it will be useful,
 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 17 * Lesser General Public License for more details.
 18 * 
 19 * You should have received a copy of the GNU Lesser General Public
 20 * License along with this library; if not, write to the Free Software
 21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 22 * 
 23 * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 24 * $/LicenseInfo$
 25 */
 26
 27//-----------------------------------------------------------------------------
 28// Header Files
 29//-----------------------------------------------------------------------------
 30#include "linden_common.h"
 31
 32#include "llhandmotion.h"
 33#include "llcharacter.h"
 34#include "m3math.h"
 35
 36//-----------------------------------------------------------------------------
 37// Constants
 38//-----------------------------------------------------------------------------
 39
 40const char *gHandPoseNames[LLHandMotion::NUM_HAND_POSES] =  /* Flawfinder: ignore */
 41{
 42	"",
 43	"Hands_Relaxed",
 44	"Hands_Point",
 45	"Hands_Fist",
 46	"Hands_Relaxed_L",
 47	"Hands_Point_L",
 48	"Hands_Fist_L",
 49	"Hands_Relaxed_R",
 50	"Hands_Point_R",
 51	"Hands_Fist_R",
 52	"Hands_Salute_R",
 53	"Hands_Typing",
 54	"Hands_Peace_R",
 55	"Hands_Spread_R"
 56};
 57
 58const F32 HAND_MORPH_BLEND_TIME = 0.2f;
 59
 60//-----------------------------------------------------------------------------
 61// LLHandMotion()
 62// Class Constructor
 63//-----------------------------------------------------------------------------
 64LLHandMotion::LLHandMotion(const LLUUID &id) : LLMotion(id)
 65{
 66	mCharacter = NULL;
 67	mLastTime = 0.f;
 68	mCurrentPose = HAND_POSE_RELAXED;
 69	mNewPose = HAND_POSE_RELAXED;
 70	mName = "hand_motion";
 71
 72	//RN: flag hand joint as highest priority for now, until we implement a proper animation track
 73	mJointSignature[0][LL_HAND_JOINT_NUM] = 0xff;
 74	mJointSignature[1][LL_HAND_JOINT_NUM] = 0xff;
 75	mJointSignature[2][LL_HAND_JOINT_NUM] = 0xff;
 76}
 77
 78
 79//-----------------------------------------------------------------------------
 80// ~LLHandMotion()
 81// Class Destructor
 82//-----------------------------------------------------------------------------
 83LLHandMotion::~LLHandMotion()
 84{
 85}
 86
 87//-----------------------------------------------------------------------------
 88// LLHandMotion::onInitialize(LLCharacter *character)
 89//-----------------------------------------------------------------------------
 90LLMotion::LLMotionInitStatus LLHandMotion::onInitialize(LLCharacter *character)
 91{
 92	mCharacter = character;
 93
 94	return STATUS_SUCCESS;
 95}
 96
 97
 98//-----------------------------------------------------------------------------
 99// LLHandMotion::onActivate()
100//-----------------------------------------------------------------------------
101BOOL LLHandMotion::onActivate()
102{
103	LLPolyMesh *upperBodyMesh = mCharacter->getUpperBodyMesh();
104
105	if (upperBodyMesh)
106	{
107		// Note: 0 is the default
108		for (S32 i = 1; i < LLHandMotion::NUM_HAND_POSES; i++)
109		{
110			mCharacter->setVisualParamWeight(gHandPoseNames[i], 0.f);
111		}
112		mCharacter->setVisualParamWeight(gHandPoseNames[mCurrentPose], 1.f);
113		mCharacter->updateVisualParams();
114	}
115	return TRUE;
116}
117
118
119//-----------------------------------------------------------------------------
120// LLHandMotion::onUpdate()
121//-----------------------------------------------------------------------------
122BOOL LLHandMotion::onUpdate(F32 time, U8* joint_mask)
123{
124	eHandPose *requestedHandPose;
125
126	F32 timeDelta = time - mLastTime;
127	mLastTime = time;
128
129	requestedHandPose = (eHandPose *)mCharacter->getAnimationData("Hand Pose");
130	// check to see if requested pose has changed
131	if (!requestedHandPose)
132	{
133		if (mNewPose != HAND_POSE_RELAXED && mNewPose != mCurrentPose)
134		{
135			mCharacter->setVisualParamWeight(gHandPoseNames[mNewPose], 0.f);
136		}
137		mNewPose = HAND_POSE_RELAXED;
138	}
139	else
140	{
141		// this is a new morph we didn't know about before
142		if (*requestedHandPose != mNewPose && mNewPose != mCurrentPose && mNewPose != HAND_POSE_SPREAD)
143		{
144			mCharacter->setVisualParamWeight(gHandPoseNames[mNewPose], 0.f);
145		}
146		mNewPose = *requestedHandPose;
147	}
148
149	mCharacter->removeAnimationData("Hand Pose");
150	mCharacter->removeAnimationData("Hand Pose Priority");
151
152//	if (requestedHandPose)
153//		llinfos << "Hand Pose " << *requestedHandPose << llendl;
154
155	// if we are still blending...
156	if (mCurrentPose != mNewPose)
157	{
158		F32 incomingWeight = 1.f;
159		F32 outgoingWeight = 0.f;
160
161		if (mNewPose != HAND_POSE_SPREAD)
162		{
163			incomingWeight = mCharacter->getVisualParamWeight(gHandPoseNames[mNewPose]);
164			incomingWeight += (timeDelta / HAND_MORPH_BLEND_TIME);
165			incomingWeight = llclamp(incomingWeight, 0.f, 1.f);
166			mCharacter->setVisualParamWeight(gHandPoseNames[mNewPose], incomingWeight);
167		}
168
169		if (mCurrentPose != HAND_POSE_SPREAD)
170		{
171			outgoingWeight = mCharacter->getVisualParamWeight(gHandPoseNames[mCurrentPose]);
172			outgoingWeight -= (timeDelta / HAND_MORPH_BLEND_TIME);
173			outgoingWeight = llclamp(outgoingWeight, 0.f, 1.f);
174			mCharacter->setVisualParamWeight(gHandPoseNames[mCurrentPose], outgoingWeight);
175		}
176
177		mCharacter->updateVisualParams();
178		
179		if (incomingWeight == 1.f && outgoingWeight == 0.f)
180		{
181			mCurrentPose = mNewPose;
182		}
183	}
184
185	return TRUE;
186}
187
188
189//-----------------------------------------------------------------------------
190// LLHandMotion::onDeactivate()
191//-----------------------------------------------------------------------------
192void LLHandMotion::onDeactivate()
193{
194}
195
196//-----------------------------------------------------------------------------
197// LLHandMotion::getHandPoseName()
198//-----------------------------------------------------------------------------
199std::string LLHandMotion::getHandPoseName(eHandPose pose)
200{
201	if ((S32)pose < LLHandMotion::NUM_HAND_POSES && (S32)pose >= 0)
202	{
203		return std::string(gHandPoseNames[pose]);
204	}
205	return LLStringUtil::null;
206}
207
208LLHandMotion::eHandPose LLHandMotion::getHandPose(std::string posename)
209{
210	for (S32 pose = 0; pose < LLHandMotion::NUM_HAND_POSES; ++pose)
211	{
212		if (gHandPoseNames[pose] == posename)
213		{
214			return (eHandPose)pose;
215		}
216	}
217	return (eHandPose)0;
218}
219
220// End