aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/llcharacter/llcharacter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'linden/indra/llcharacter/llcharacter.cpp')
-rw-r--r--linden/indra/llcharacter/llcharacter.cpp491
1 files changed, 491 insertions, 0 deletions
diff --git a/linden/indra/llcharacter/llcharacter.cpp b/linden/indra/llcharacter/llcharacter.cpp
new file mode 100644
index 0000000..45f692c
--- /dev/null
+++ b/linden/indra/llcharacter/llcharacter.cpp
@@ -0,0 +1,491 @@
1/**
2 * @file llcharacter.cpp
3 * @brief Implementation of LLCharacter class.
4 *
5 * Copyright (c) 2001-2007, Linden Research, Inc.
6 *
7 * The source code in this file ("Source Code") is provided by Linden Lab
8 * to you under the terms of the GNU General Public License, version 2.0
9 * ("GPL"), unless you have obtained a separate licensing agreement
10 * ("Other License"), formally executed by you and Linden Lab. Terms of
11 * the GPL can be found in doc/GPL-license.txt in this distribution, or
12 * online at http://secondlife.com/developers/opensource/gplv2
13 *
14 * There are special exceptions to the terms and conditions of the GPL as
15 * it is applied to this Source Code. View the full text of the exception
16 * in the file doc/FLOSS-exception.txt in this software distribution, or
17 * online at http://secondlife.com/developers/opensource/flossexception
18 *
19 * By copying, modifying or distributing this software, you acknowledge
20 * that you have read and understood your obligations described above,
21 * and agree to abide by those obligations.
22 *
23 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
24 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
25 * COMPLETENESS OR PERFORMANCE.
26 */
27
28//-----------------------------------------------------------------------------
29// Header Files
30//-----------------------------------------------------------------------------
31
32#include "linden_common.h"
33
34#include "llcharacter.h"
35#include "llstring.h"
36
37#define SKEL_HEADER "Linden Skeleton 1.0"
38
39LLStringTable LLCharacter::sVisualParamNames(1024);
40
41// helper functions
42BOOL larger_screen_area( LLCharacter* data_new, LLCharacter* data_tested )
43{
44 return data_new->getPixelArea() > data_tested->getPixelArea();
45}
46
47LLLinkedList< LLCharacter > LLCharacter::sInstances( larger_screen_area );
48
49
50//-----------------------------------------------------------------------------
51// LLCharacter()
52// Class Constructor
53//-----------------------------------------------------------------------------
54LLCharacter::LLCharacter()
55 :
56 mPreferredPelvisHeight( 0.f ),
57 mSex( SEX_FEMALE ),
58 mAppearanceSerialNum( 0 ),
59 mSkeletonSerialNum( 0 )
60{
61 mMotionController.setCharacter( this );
62 sInstances.addData(this);
63 mPauseRequest = new LLPauseRequestHandle();
64}
65
66
67//-----------------------------------------------------------------------------
68// ~LLCharacter()
69// Class Destructor
70//-----------------------------------------------------------------------------
71LLCharacter::~LLCharacter()
72{
73 for (LLVisualParam *param = getFirstVisualParam();
74 param;
75 param = getNextVisualParam())
76 {
77 delete param;
78 }
79 sInstances.removeData(this);
80}
81
82
83//-----------------------------------------------------------------------------
84// getJoint()
85//-----------------------------------------------------------------------------
86LLJoint *LLCharacter::getJoint( const std::string &name )
87{
88 LLJoint *joint = NULL;
89
90 LLJoint *root = getRootJoint();
91 if (root)
92 {
93 joint = root->findJoint(name);
94 }
95
96 if (!joint)
97 {
98 llwarns << "Failed to find joint." << llendl;
99 }
100 return joint;
101}
102
103//-----------------------------------------------------------------------------
104// addMotion()
105//-----------------------------------------------------------------------------
106BOOL LLCharacter::addMotion( const LLUUID& id, LLMotionConstructor create )
107{
108 return mMotionController.addMotion(id, create);
109}
110
111//-----------------------------------------------------------------------------
112// removeMotion()
113//-----------------------------------------------------------------------------
114void LLCharacter::removeMotion( const LLUUID& id )
115{
116 mMotionController.removeMotion(id);
117}
118
119//-----------------------------------------------------------------------------
120// getMotion()
121//-----------------------------------------------------------------------------
122LLMotion* LLCharacter::createMotion( const LLUUID &id )
123{
124 return mMotionController.createMotion( id );
125}
126
127//-----------------------------------------------------------------------------
128// startMotion()
129//-----------------------------------------------------------------------------
130BOOL LLCharacter::startMotion(const LLUUID &id, F32 start_offset)
131{
132 return mMotionController.startMotion(id, start_offset);
133}
134
135
136//-----------------------------------------------------------------------------
137// stopMotion()
138//-----------------------------------------------------------------------------
139BOOL LLCharacter::stopMotion(const LLUUID& id, BOOL stop_immediate)
140{
141 return mMotionController.stopMotionLocally(id, stop_immediate);
142}
143
144//-----------------------------------------------------------------------------
145// isMotionActive()
146//-----------------------------------------------------------------------------
147BOOL LLCharacter::isMotionActive(const LLUUID& id)
148{
149 LLMotion *motionp = mMotionController.findMotion(id);
150 if (motionp)
151 {
152 return mMotionController.isMotionActive(motionp);
153 }
154
155 return FALSE;
156}
157
158
159//-----------------------------------------------------------------------------
160// onDeactivateMotion()
161//-----------------------------------------------------------------------------
162void LLCharacter::requestStopMotion( LLMotion* motion)
163{
164// llinfos << "DEBUG: Char::onDeactivateMotion( " << motionName << " )" << llendl;
165}
166
167
168//-----------------------------------------------------------------------------
169// updateMotion()
170//-----------------------------------------------------------------------------
171void LLCharacter::updateMotion(BOOL force_update)
172{
173 // unpause if we're forcing an update or
174 // number of outstanding pause requests has dropped
175 // to the initial one
176 if (mMotionController.isPaused() &&
177 (force_update || mPauseRequest->getNumRefs() == 1))
178 {
179 mMotionController.unpause();
180 }
181
182 mMotionController.updateMotion();
183
184 // pause once again, after forced update, if there are outstanding
185 // pause requests
186 if (force_update && mPauseRequest->getNumRefs() > 1)
187 {
188 mMotionController.pause();
189 }
190}
191
192
193//-----------------------------------------------------------------------------
194// flushAllMotions()
195//-----------------------------------------------------------------------------
196void LLCharacter::flushAllMotions()
197{
198 mMotionController.flushAllMotions();
199}
200
201
202//-----------------------------------------------------------------------------
203// dumpCharacter()
204//-----------------------------------------------------------------------------
205void LLCharacter::dumpCharacter( LLJoint *joint )
206{
207 // handle top level entry into recursion
208 if (joint == NULL)
209 {
210 llinfos << "DEBUG: Dumping Character @" << this << llendl;
211 dumpCharacter( getRootJoint() );
212 llinfos << "DEBUG: Done." << llendl;
213 return;
214 }
215
216 // print joint info
217 llinfos << "DEBUG: " << joint->getName() << " (" << (joint->getParent()?joint->getParent()->getName():std::string("ROOT")) << ")" << llendl;
218
219 // recurse
220 for ( LLJoint *j = joint->mChildren.getFirstData();
221 j != NULL;
222 j = joint->mChildren.getNextData() )
223 {
224 dumpCharacter(j);
225 }
226}
227
228//-----------------------------------------------------------------------------
229// setAnimationData()
230//-----------------------------------------------------------------------------
231void LLCharacter::setAnimationData(std::string name, void *data)
232{
233 if(mAnimationData.getValue(name))
234 {
235 *mAnimationData[name] = data;
236 }
237 else
238 {
239 mAnimationData.addToHead(name, data);
240 }
241}
242
243//-----------------------------------------------------------------------------
244// getAnimationData()
245//-----------------------------------------------------------------------------
246void * LLCharacter::getAnimationData(std::string name)
247{
248 void **result = mAnimationData.getValue(name);
249 void *return_value; // Necessary to suppress VC6 warning. JC
250 if (!result)
251 {
252 return_value = NULL;
253 }
254 else
255 {
256 return_value = *result;
257 }
258
259 return return_value;
260}
261
262//-----------------------------------------------------------------------------
263// removeAnimationData()
264//-----------------------------------------------------------------------------
265void LLCharacter::removeAnimationData(std::string name)
266{
267 mAnimationData.remove(name);
268}
269
270//-----------------------------------------------------------------------------
271// setVisualParamWeight()
272//-----------------------------------------------------------------------------
273BOOL LLCharacter::setVisualParamWeight(LLVisualParam* which_param, F32 weight, BOOL set_by_user)
274{
275 S32 index = which_param->getID();
276 VisualParamIndexMap_t::iterator index_iter = mVisualParamIndexMap.find(index);
277 if (index_iter != mVisualParamIndexMap.end())
278 {
279 index_iter->second->setWeight(weight, set_by_user);
280 return TRUE;
281 }
282 return FALSE;
283}
284
285//-----------------------------------------------------------------------------
286// setVisualParamWeight()
287//-----------------------------------------------------------------------------
288BOOL LLCharacter::setVisualParamWeight(const char* param_name, F32 weight, BOOL set_by_user)
289{
290 LLString tname(param_name);
291 LLString::toLower(tname);
292 char *tableptr = sVisualParamNames.checkString(tname);
293 VisualParamNameMap_t::iterator name_iter = mVisualParamNameMap.find(tableptr);
294 if (name_iter != mVisualParamNameMap.end())
295 {
296 name_iter->second->setWeight(weight, set_by_user);
297 return TRUE;
298 }
299 llwarns << "LLCharacter::setVisualParamWeight() Invalid visual parameter: " << param_name << llendl;
300 return FALSE;
301}
302
303//-----------------------------------------------------------------------------
304// setVisualParamWeight()
305//-----------------------------------------------------------------------------
306BOOL LLCharacter::setVisualParamWeight(S32 index, F32 weight, BOOL set_by_user)
307{
308 VisualParamIndexMap_t::iterator index_iter = mVisualParamIndexMap.find(index);
309 if (index_iter != mVisualParamIndexMap.end())
310 {
311 index_iter->second->setWeight(weight, set_by_user);
312 return TRUE;
313 }
314 llwarns << "LLCharacter::setVisualParamWeight() Invalid visual parameter index: " << index << llendl;
315 return FALSE;
316}
317
318//-----------------------------------------------------------------------------
319// getVisualParamWeight()
320//-----------------------------------------------------------------------------
321F32 LLCharacter::getVisualParamWeight(LLVisualParam *which_param)
322{
323 S32 index = which_param->getID();
324 VisualParamIndexMap_t::iterator index_iter = mVisualParamIndexMap.find(index);
325 if (index_iter != mVisualParamIndexMap.end())
326 {
327 return index_iter->second->getWeight();
328 }
329 else
330 {
331 llwarns << "LLCharacter::getVisualParamWeight() Invalid visual parameter*, index= " << index << llendl;
332 return 0.f;
333 }
334}
335
336//-----------------------------------------------------------------------------
337// getVisualParamWeight()
338//-----------------------------------------------------------------------------
339F32 LLCharacter::getVisualParamWeight(const char* param_name)
340{
341 LLString tname(param_name);
342 LLString::toLower(tname);
343 char *tableptr = sVisualParamNames.checkString(tname);
344 VisualParamNameMap_t::iterator name_iter = mVisualParamNameMap.find(tableptr);
345 if (name_iter != mVisualParamNameMap.end())
346 {
347 return name_iter->second->getWeight();
348 }
349 llwarns << "LLCharacter::getVisualParamWeight() Invalid visual parameter: " << param_name << llendl;
350 return 0.f;
351}
352
353//-----------------------------------------------------------------------------
354// getVisualParamWeight()
355//-----------------------------------------------------------------------------
356F32 LLCharacter::getVisualParamWeight(S32 index)
357{
358 VisualParamIndexMap_t::iterator index_iter = mVisualParamIndexMap.find(index);
359 if (index_iter != mVisualParamIndexMap.end())
360 {
361 return index_iter->second->getWeight();
362 }
363 else
364 {
365 llwarns << "LLCharacter::getVisualParamWeight() Invalid visual parameter index: " << index << llendl;
366 return 0.f;
367 }
368}
369
370//-----------------------------------------------------------------------------
371// clearVisualParamWeights()
372//-----------------------------------------------------------------------------
373void LLCharacter::clearVisualParamWeights()
374{
375 for (LLVisualParam *param = getFirstVisualParam();
376 param;
377 param = getNextVisualParam())
378 {
379 if (param->getGroup() == VISUAL_PARAM_GROUP_TWEAKABLE)
380 {
381 param->setWeight( param->getDefaultWeight(), FALSE );
382 }
383 }
384}
385
386//-----------------------------------------------------------------------------
387// getVisualParam()
388//-----------------------------------------------------------------------------
389LLVisualParam* LLCharacter::getVisualParam(const char *param_name)
390{
391 LLString tname(param_name);
392 LLString::toLower(tname);
393 char *tableptr = sVisualParamNames.checkString(tname);
394 VisualParamNameMap_t::iterator name_iter = mVisualParamNameMap.find(tableptr);
395 if (name_iter != mVisualParamNameMap.end())
396 {
397 return name_iter->second;
398 }
399 llwarns << "LLCharacter::getVisualParam() Invalid visual parameter: " << param_name << llendl;
400 return NULL;
401}
402
403//-----------------------------------------------------------------------------
404// addSharedVisualParam()
405//-----------------------------------------------------------------------------
406void LLCharacter::addSharedVisualParam(LLVisualParam *param)
407{
408 S32 index = param->getID();
409 VisualParamIndexMap_t::iterator index_iter = mVisualParamIndexMap.find(index);
410 LLVisualParam* current_param = 0;
411 if (index_iter != mVisualParamIndexMap.end())
412 current_param = index_iter->second;
413 if( current_param )
414 {
415 LLVisualParam* next_param = current_param;
416 while(next_param->getNextParam())
417 {
418 next_param = next_param->getNextParam();
419 }
420 next_param->setNextParam(param);
421 }
422 else
423 {
424 llwarns << "Shared visual parameter " << param->getName() << " does not already exist with ID " <<
425 param->getID() << llendl;
426 }
427}
428
429//-----------------------------------------------------------------------------
430// addVisualParam()
431//-----------------------------------------------------------------------------
432void LLCharacter::addVisualParam(LLVisualParam *param)
433{
434 S32 index = param->getID();
435 // Add Index map
436 std::pair<VisualParamIndexMap_t::iterator, bool> idxres;
437 idxres = mVisualParamIndexMap.insert(VisualParamIndexMap_t::value_type(index, param));
438 if (!idxres.second)
439 {
440 llwarns << "Visual parameter " << param->getName() << " already exists with same ID as " <<
441 param->getName() << llendl;
442 VisualParamIndexMap_t::iterator index_iter = idxres.first;
443 index_iter->second = param;
444 }
445
446 if (param->getInfo())
447 {
448 // Add name map
449 LLString tname(param->getName());
450 LLString::toLower(tname);
451 char *tableptr = sVisualParamNames.addString(tname);
452 std::pair<VisualParamNameMap_t::iterator, bool> nameres;
453 nameres = mVisualParamNameMap.insert(VisualParamNameMap_t::value_type(tableptr, param));
454 if (!nameres.second)
455 {
456 // Already exists, copy param
457 VisualParamNameMap_t::iterator name_iter = nameres.first;
458 name_iter->second = param;
459 }
460 }
461 //llinfos << "Adding Visual Param '" << param->getName() << "' ( " << index << " )" << llendl;
462}
463
464//-----------------------------------------------------------------------------
465// updateVisualParams()
466//-----------------------------------------------------------------------------
467void LLCharacter::updateVisualParams()
468{
469 for (LLVisualParam *param = getFirstVisualParam();
470 param;
471 param = getNextVisualParam())
472 {
473 if (param->isAnimating())
474 {
475 continue;
476 }
477 // only apply parameters whose effective weight has changed
478 F32 effective_weight = ( param->getSex() & mSex ) ? param->getWeight() : param->getDefaultWeight();
479 if (effective_weight != param->getLastWeight())
480 {
481 param->apply( mSex );
482 }
483 }
484}
485
486LLAnimPauseRequest LLCharacter::requestPause()
487{
488 mMotionController.pause();
489 return mPauseRequest;
490}
491