diff options
Diffstat (limited to 'linden/indra/llcharacter/llcharacter.cpp')
-rw-r--r-- | linden/indra/llcharacter/llcharacter.cpp | 491 |
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 | |||
39 | LLStringTable LLCharacter::sVisualParamNames(1024); | ||
40 | |||
41 | // helper functions | ||
42 | BOOL larger_screen_area( LLCharacter* data_new, LLCharacter* data_tested ) | ||
43 | { | ||
44 | return data_new->getPixelArea() > data_tested->getPixelArea(); | ||
45 | } | ||
46 | |||
47 | LLLinkedList< LLCharacter > LLCharacter::sInstances( larger_screen_area ); | ||
48 | |||
49 | |||
50 | //----------------------------------------------------------------------------- | ||
51 | // LLCharacter() | ||
52 | // Class Constructor | ||
53 | //----------------------------------------------------------------------------- | ||
54 | LLCharacter::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 | //----------------------------------------------------------------------------- | ||
71 | LLCharacter::~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 | //----------------------------------------------------------------------------- | ||
86 | LLJoint *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 | //----------------------------------------------------------------------------- | ||
106 | BOOL LLCharacter::addMotion( const LLUUID& id, LLMotionConstructor create ) | ||
107 | { | ||
108 | return mMotionController.addMotion(id, create); | ||
109 | } | ||
110 | |||
111 | //----------------------------------------------------------------------------- | ||
112 | // removeMotion() | ||
113 | //----------------------------------------------------------------------------- | ||
114 | void LLCharacter::removeMotion( const LLUUID& id ) | ||
115 | { | ||
116 | mMotionController.removeMotion(id); | ||
117 | } | ||
118 | |||
119 | //----------------------------------------------------------------------------- | ||
120 | // getMotion() | ||
121 | //----------------------------------------------------------------------------- | ||
122 | LLMotion* LLCharacter::createMotion( const LLUUID &id ) | ||
123 | { | ||
124 | return mMotionController.createMotion( id ); | ||
125 | } | ||
126 | |||
127 | //----------------------------------------------------------------------------- | ||
128 | // startMotion() | ||
129 | //----------------------------------------------------------------------------- | ||
130 | BOOL LLCharacter::startMotion(const LLUUID &id, F32 start_offset) | ||
131 | { | ||
132 | return mMotionController.startMotion(id, start_offset); | ||
133 | } | ||
134 | |||
135 | |||
136 | //----------------------------------------------------------------------------- | ||
137 | // stopMotion() | ||
138 | //----------------------------------------------------------------------------- | ||
139 | BOOL LLCharacter::stopMotion(const LLUUID& id, BOOL stop_immediate) | ||
140 | { | ||
141 | return mMotionController.stopMotionLocally(id, stop_immediate); | ||
142 | } | ||
143 | |||
144 | //----------------------------------------------------------------------------- | ||
145 | // isMotionActive() | ||
146 | //----------------------------------------------------------------------------- | ||
147 | BOOL 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 | //----------------------------------------------------------------------------- | ||
162 | void LLCharacter::requestStopMotion( LLMotion* motion) | ||
163 | { | ||
164 | // llinfos << "DEBUG: Char::onDeactivateMotion( " << motionName << " )" << llendl; | ||
165 | } | ||
166 | |||
167 | |||
168 | //----------------------------------------------------------------------------- | ||
169 | // updateMotion() | ||
170 | //----------------------------------------------------------------------------- | ||
171 | void 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 | //----------------------------------------------------------------------------- | ||
196 | void LLCharacter::flushAllMotions() | ||
197 | { | ||
198 | mMotionController.flushAllMotions(); | ||
199 | } | ||
200 | |||
201 | |||
202 | //----------------------------------------------------------------------------- | ||
203 | // dumpCharacter() | ||
204 | //----------------------------------------------------------------------------- | ||
205 | void 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 | //----------------------------------------------------------------------------- | ||
231 | void 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 | //----------------------------------------------------------------------------- | ||
246 | void * 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 | //----------------------------------------------------------------------------- | ||
265 | void LLCharacter::removeAnimationData(std::string name) | ||
266 | { | ||
267 | mAnimationData.remove(name); | ||
268 | } | ||
269 | |||
270 | //----------------------------------------------------------------------------- | ||
271 | // setVisualParamWeight() | ||
272 | //----------------------------------------------------------------------------- | ||
273 | BOOL 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 | //----------------------------------------------------------------------------- | ||
288 | BOOL 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 | //----------------------------------------------------------------------------- | ||
306 | BOOL 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 | //----------------------------------------------------------------------------- | ||
321 | F32 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 | //----------------------------------------------------------------------------- | ||
339 | F32 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 | //----------------------------------------------------------------------------- | ||
356 | F32 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 | //----------------------------------------------------------------------------- | ||
373 | void 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 | //----------------------------------------------------------------------------- | ||
389 | LLVisualParam* 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 | //----------------------------------------------------------------------------- | ||
406 | void 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 | //----------------------------------------------------------------------------- | ||
432 | void 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 | //----------------------------------------------------------------------------- | ||
467 | void 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 | |||
486 | LLAnimPauseRequest LLCharacter::requestPause() | ||
487 | { | ||
488 | mMotionController.pause(); | ||
489 | return mPauseRequest; | ||
490 | } | ||
491 | |||