PageRenderTime 42ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/indra/newview/lldriverparam.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 634 lines | 484 code | 72 blank | 78 comment | 95 complexity | 9ecd7b9ea2bdd59af92f178d502851d1 MD5 | raw file
Possible License(s): LGPL-2.1
  1. /**
  2. * @file lldriverparam.cpp
  3. * @brief A visual parameter that drives (controls) other visual parameters.
  4. *
  5. * $LicenseInfo:firstyear=2002&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. #include "llviewerprecompiledheaders.h"
  27. #include "lldriverparam.h"
  28. #include "llfasttimer.h"
  29. #include "llvoavatar.h"
  30. #include "llvoavatarself.h"
  31. #include "llagent.h"
  32. #include "llwearable.h"
  33. #include "llagentwearables.h"
  34. //-----------------------------------------------------------------------------
  35. // LLDriverParamInfo
  36. //-----------------------------------------------------------------------------
  37. LLDriverParamInfo::LLDriverParamInfo()
  38. {
  39. }
  40. BOOL LLDriverParamInfo::parseXml(LLXmlTreeNode* node)
  41. {
  42. llassert( node->hasName( "param" ) && node->getChildByName( "param_driver" ) );
  43. if( !LLViewerVisualParamInfo::parseXml( node ))
  44. return FALSE;
  45. LLXmlTreeNode* param_driver_node = node->getChildByName( "param_driver" );
  46. if( !param_driver_node )
  47. return FALSE;
  48. for (LLXmlTreeNode* child = param_driver_node->getChildByName( "driven" );
  49. child;
  50. child = param_driver_node->getNextNamedChild())
  51. {
  52. S32 driven_id;
  53. static LLStdStringHandle id_string = LLXmlTree::addAttributeString("id");
  54. if( child->getFastAttributeS32( id_string, driven_id ) )
  55. {
  56. F32 min1 = mMinWeight;
  57. F32 max1 = mMaxWeight;
  58. F32 max2 = max1;
  59. F32 min2 = max1;
  60. // driven ________ //
  61. // ^ /| |\ //
  62. // | / | | \ //
  63. // | / | | \ //
  64. // | / | | \ //
  65. // | / | | \ //
  66. //-------|----|-------|----|-------> driver //
  67. // | min1 max1 max2 min2
  68. static LLStdStringHandle min1_string = LLXmlTree::addAttributeString("min1");
  69. child->getFastAttributeF32( min1_string, min1 ); // optional
  70. static LLStdStringHandle max1_string = LLXmlTree::addAttributeString("max1");
  71. child->getFastAttributeF32( max1_string, max1 ); // optional
  72. static LLStdStringHandle max2_string = LLXmlTree::addAttributeString("max2");
  73. child->getFastAttributeF32( max2_string, max2 ); // optional
  74. static LLStdStringHandle min2_string = LLXmlTree::addAttributeString("min2");
  75. child->getFastAttributeF32( min2_string, min2 ); // optional
  76. // Push these on the front of the deque, so that we can construct
  77. // them in order later (faster)
  78. mDrivenInfoList.push_front( LLDrivenEntryInfo( driven_id, min1, max1, max2, min2 ) );
  79. }
  80. else
  81. {
  82. llerrs << "<driven> Unable to resolve driven parameter: " << driven_id << llendl;
  83. return FALSE;
  84. }
  85. }
  86. return TRUE;
  87. }
  88. //virtual
  89. void LLDriverParamInfo::toStream(std::ostream &out)
  90. {
  91. LLViewerVisualParamInfo::toStream(out);
  92. out << "driver" << "\t";
  93. out << mDrivenInfoList.size() << "\t";
  94. for (entry_info_list_t::iterator iter = mDrivenInfoList.begin(); iter != mDrivenInfoList.end(); iter++)
  95. {
  96. LLDrivenEntryInfo driven = *iter;
  97. out << driven.mDrivenID << "\t";
  98. }
  99. out << std::endl;
  100. if(isAgentAvatarValid())
  101. {
  102. for (entry_info_list_t::iterator iter = mDrivenInfoList.begin(); iter != mDrivenInfoList.end(); iter++)
  103. {
  104. LLDrivenEntryInfo driven = *iter;
  105. LLViewerVisualParam *param = (LLViewerVisualParam*)gAgentAvatarp->getVisualParam(driven.mDrivenID);
  106. if (param)
  107. {
  108. param->getInfo()->toStream(out);
  109. if (param->getWearableType() != mWearableType)
  110. {
  111. if(param->getCrossWearable())
  112. {
  113. out << "cross-wearable" << "\t";
  114. }
  115. else
  116. {
  117. out << "ERROR!" << "\t";
  118. }
  119. }
  120. else
  121. {
  122. out << "valid" << "\t";
  123. }
  124. }
  125. else
  126. {
  127. llwarns << "could not get parameter " << driven.mDrivenID << " from avatar " << gAgentAvatarp << " for driver parameter " << getID() << llendl;
  128. }
  129. out << std::endl;
  130. }
  131. }
  132. }
  133. //-----------------------------------------------------------------------------
  134. // LLDriverParam
  135. //-----------------------------------------------------------------------------
  136. LLDriverParam::LLDriverParam(LLVOAvatar *avatarp) :
  137. mCurrentDistortionParam( NULL ),
  138. mAvatarp(avatarp),
  139. mWearablep(NULL)
  140. {
  141. }
  142. LLDriverParam::LLDriverParam(LLWearable *wearablep) :
  143. mCurrentDistortionParam( NULL ),
  144. mAvatarp(NULL),
  145. mWearablep(wearablep)
  146. {
  147. }
  148. LLDriverParam::~LLDriverParam()
  149. {
  150. }
  151. BOOL LLDriverParam::setInfo(LLDriverParamInfo *info)
  152. {
  153. llassert(mInfo == NULL);
  154. if (info->mID < 0)
  155. return FALSE;
  156. mInfo = info;
  157. mID = info->mID;
  158. setWeight(getDefaultWeight(), FALSE );
  159. return TRUE;
  160. }
  161. void LLDriverParam::setWearable(LLWearable *wearablep)
  162. {
  163. if (wearablep)
  164. {
  165. mWearablep = wearablep;
  166. mAvatarp = NULL;
  167. }
  168. }
  169. void LLDriverParam::setAvatar(LLVOAvatar *avatarp)
  170. {
  171. if (avatarp)
  172. {
  173. mWearablep = NULL;
  174. mAvatarp = avatarp;
  175. }
  176. }
  177. /*virtual*/ LLViewerVisualParam* LLDriverParam::cloneParam(LLWearable* wearable) const
  178. {
  179. LLDriverParam *new_param;
  180. if (wearable)
  181. {
  182. new_param = new LLDriverParam(wearable);
  183. }
  184. else
  185. {
  186. if (mWearablep)
  187. {
  188. new_param = new LLDriverParam(mWearablep);
  189. }
  190. else
  191. {
  192. new_param = new LLDriverParam(mAvatarp);
  193. }
  194. }
  195. *new_param = *this;
  196. return new_param;
  197. }
  198. #if 0 // obsolete
  199. BOOL LLDriverParam::parseData(LLXmlTreeNode* node)
  200. {
  201. LLDriverParamInfo* info = new LLDriverParamInfo;
  202. info->parseXml(node);
  203. if (!setInfo(info))
  204. {
  205. delete info;
  206. return FALSE;
  207. }
  208. return TRUE;
  209. }
  210. #endif
  211. void LLDriverParam::setWeight(F32 weight, BOOL upload_bake)
  212. {
  213. F32 min_weight = getMinWeight();
  214. F32 max_weight = getMaxWeight();
  215. if (mIsAnimating)
  216. {
  217. // allow overshoot when animating
  218. mCurWeight = weight;
  219. }
  220. else
  221. {
  222. mCurWeight = llclamp(weight, min_weight, max_weight);
  223. }
  224. // driven ________
  225. // ^ /| |\ ^
  226. // | / | | \ |
  227. // | / | | \ |
  228. // | / | | \ |
  229. // | / | | \ |
  230. //-------|----|-------|----|-------> driver
  231. // | min1 max1 max2 min2
  232. for( entry_list_t::iterator iter = mDriven.begin(); iter != mDriven.end(); iter++ )
  233. {
  234. LLDrivenEntry* driven = &(*iter);
  235. LLDrivenEntryInfo* info = driven->mInfo;
  236. F32 driven_weight = 0.f;
  237. F32 driven_min = driven->mParam->getMinWeight();
  238. F32 driven_max = driven->mParam->getMaxWeight();
  239. if (mIsAnimating)
  240. {
  241. // driven param doesn't interpolate (textures, for example)
  242. if (!driven->mParam->getAnimating())
  243. {
  244. continue;
  245. }
  246. if( mCurWeight < info->mMin1 )
  247. {
  248. if (info->mMin1 == min_weight)
  249. {
  250. if (info->mMin1 == info->mMax1)
  251. {
  252. driven_weight = driven_max;
  253. }
  254. else
  255. {
  256. //up slope extrapolation
  257. F32 t = (mCurWeight - info->mMin1) / (info->mMax1 - info->mMin1 );
  258. driven_weight = driven_min + t * (driven_max - driven_min);
  259. }
  260. }
  261. else
  262. {
  263. driven_weight = driven_min;
  264. }
  265. setDrivenWeight(driven,driven_weight,upload_bake);
  266. continue;
  267. }
  268. else
  269. if ( mCurWeight > info->mMin2 )
  270. {
  271. if (info->mMin2 == max_weight)
  272. {
  273. if (info->mMin2 == info->mMax2)
  274. {
  275. driven_weight = driven_max;
  276. }
  277. else
  278. {
  279. //down slope extrapolation
  280. F32 t = (mCurWeight - info->mMax2) / (info->mMin2 - info->mMax2 );
  281. driven_weight = driven_max + t * (driven_min - driven_max);
  282. }
  283. }
  284. else
  285. {
  286. driven_weight = driven_min;
  287. }
  288. setDrivenWeight(driven,driven_weight,upload_bake);
  289. continue;
  290. }
  291. }
  292. driven_weight = getDrivenWeight(driven, mCurWeight);
  293. setDrivenWeight(driven,driven_weight,upload_bake);
  294. }
  295. }
  296. F32 LLDriverParam::getTotalDistortion()
  297. {
  298. F32 sum = 0.f;
  299. for( entry_list_t::iterator iter = mDriven.begin(); iter != mDriven.end(); iter++ )
  300. {
  301. LLDrivenEntry* driven = &(*iter);
  302. sum += driven->mParam->getTotalDistortion();
  303. }
  304. return sum;
  305. }
  306. const LLVector3 &LLDriverParam::getAvgDistortion()
  307. {
  308. // It's not actually correct to take the average of averages, but it good enough here.
  309. LLVector3 sum;
  310. S32 count = 0;
  311. for( entry_list_t::iterator iter = mDriven.begin(); iter != mDriven.end(); iter++ )
  312. {
  313. LLDrivenEntry* driven = &(*iter);
  314. sum += driven->mParam->getAvgDistortion();
  315. count++;
  316. }
  317. sum /= (F32)count;
  318. mDefaultVec = sum;
  319. return mDefaultVec;
  320. }
  321. F32 LLDriverParam::getMaxDistortion()
  322. {
  323. F32 max = 0.f;
  324. for( entry_list_t::iterator iter = mDriven.begin(); iter != mDriven.end(); iter++ )
  325. {
  326. LLDrivenEntry* driven = &(*iter);
  327. F32 param_max = driven->mParam->getMaxDistortion();
  328. if( param_max > max )
  329. {
  330. max = param_max;
  331. }
  332. }
  333. return max;
  334. }
  335. LLVector3 LLDriverParam::getVertexDistortion(S32 index, LLPolyMesh *poly_mesh)
  336. {
  337. LLVector3 sum;
  338. for( entry_list_t::iterator iter = mDriven.begin(); iter != mDriven.end(); iter++ )
  339. {
  340. LLDrivenEntry* driven = &(*iter);
  341. sum += driven->mParam->getVertexDistortion( index, poly_mesh );
  342. }
  343. return sum;
  344. }
  345. const LLVector3* LLDriverParam::getFirstDistortion(U32 *index, LLPolyMesh **poly_mesh)
  346. {
  347. mCurrentDistortionParam = NULL;
  348. const LLVector3* v = NULL;
  349. for( entry_list_t::iterator iter = mDriven.begin(); iter != mDriven.end(); iter++ )
  350. {
  351. LLDrivenEntry* driven = &(*iter);
  352. v = driven->mParam->getFirstDistortion( index, poly_mesh );
  353. if( v )
  354. {
  355. mCurrentDistortionParam = driven->mParam;
  356. break;
  357. }
  358. }
  359. return v;
  360. };
  361. const LLVector3* LLDriverParam::getNextDistortion(U32 *index, LLPolyMesh **poly_mesh)
  362. {
  363. llassert( mCurrentDistortionParam );
  364. if( !mCurrentDistortionParam )
  365. {
  366. return NULL;
  367. }
  368. LLDrivenEntry* driven = NULL;
  369. entry_list_t::iterator iter;
  370. // Set mDriven iteration to the right point
  371. for( iter = mDriven.begin(); iter != mDriven.end(); iter++ )
  372. {
  373. driven = &(*iter);
  374. if( driven->mParam == mCurrentDistortionParam )
  375. {
  376. break;
  377. }
  378. }
  379. llassert(driven);
  380. if (!driven)
  381. {
  382. return NULL; // shouldn't happen, but...
  383. }
  384. // We're already in the middle of a param's distortions, so get the next one.
  385. const LLVector3* v = driven->mParam->getNextDistortion( index, poly_mesh );
  386. if( (!v) && (iter != mDriven.end()) )
  387. {
  388. // This param is finished, so start the next param. It might not have any
  389. // distortions, though, so we have to loop to find the next param that does.
  390. for( iter++; iter != mDriven.end(); iter++ )
  391. {
  392. driven = &(*iter);
  393. v = driven->mParam->getFirstDistortion( index, poly_mesh );
  394. if( v )
  395. {
  396. mCurrentDistortionParam = driven->mParam;
  397. break;
  398. }
  399. }
  400. }
  401. return v;
  402. };
  403. //-----------------------------------------------------------------------------
  404. // setAnimationTarget()
  405. //-----------------------------------------------------------------------------
  406. void LLDriverParam::setAnimationTarget( F32 target_value, BOOL upload_bake )
  407. {
  408. LLVisualParam::setAnimationTarget(target_value, upload_bake);
  409. for( entry_list_t::iterator iter = mDriven.begin(); iter != mDriven.end(); iter++ )
  410. {
  411. LLDrivenEntry* driven = &(*iter);
  412. F32 driven_weight = getDrivenWeight(driven, mTargetWeight);
  413. // this isn't normally necessary, as driver params handle interpolation of their driven params
  414. // but texture params need to know to assume their final value at beginning of interpolation
  415. driven->mParam->setAnimationTarget(driven_weight, upload_bake);
  416. }
  417. }
  418. //-----------------------------------------------------------------------------
  419. // stopAnimating()
  420. //-----------------------------------------------------------------------------
  421. void LLDriverParam::stopAnimating(BOOL upload_bake)
  422. {
  423. LLVisualParam::stopAnimating(upload_bake);
  424. for( entry_list_t::iterator iter = mDriven.begin(); iter != mDriven.end(); iter++ )
  425. {
  426. LLDrivenEntry* driven = &(*iter);
  427. driven->mParam->setAnimating(FALSE);
  428. }
  429. }
  430. /*virtual*/
  431. BOOL LLDriverParam::linkDrivenParams(visual_param_mapper mapper, BOOL only_cross_params)
  432. {
  433. BOOL success = TRUE;
  434. LLDriverParamInfo::entry_info_list_t::iterator iter;
  435. for (iter = getInfo()->mDrivenInfoList.begin(); iter != getInfo()->mDrivenInfoList.end(); ++iter)
  436. {
  437. LLDrivenEntryInfo *driven_info = &(*iter);
  438. S32 driven_id = driven_info->mDrivenID;
  439. // check for already existing links. Do not overwrite.
  440. BOOL found = FALSE;
  441. for (entry_list_t::iterator driven_iter = mDriven.begin(); driven_iter != mDriven.end() && !found; ++driven_iter)
  442. {
  443. if (driven_iter->mInfo->mDrivenID == driven_id)
  444. {
  445. found = TRUE;
  446. }
  447. }
  448. if (!found)
  449. {
  450. LLViewerVisualParam* param = (LLViewerVisualParam*)mapper(driven_id);
  451. bool push = param && (!only_cross_params || param->getCrossWearable());
  452. if (push)
  453. {
  454. mDriven.push_back(LLDrivenEntry( param, driven_info ));
  455. }
  456. else
  457. {
  458. success = FALSE;
  459. }
  460. }
  461. }
  462. return success;
  463. }
  464. void LLDriverParam::resetDrivenParams()
  465. {
  466. mDriven.clear();
  467. mDriven.reserve(getInfo()->mDrivenInfoList.size());
  468. }
  469. void LLDriverParam::updateCrossDrivenParams(LLWearableType::EType driven_type)
  470. {
  471. bool needs_update = (getWearableType()==driven_type);
  472. // if the driver has a driven entry for the passed-in wearable type, we need to refresh the value
  473. for( entry_list_t::iterator iter = mDriven.begin(); iter != mDriven.end(); iter++ )
  474. {
  475. LLDrivenEntry* driven = &(*iter);
  476. if (driven && driven->mParam && driven->mParam->getCrossWearable() && driven->mParam->getWearableType() == driven_type)
  477. {
  478. needs_update = true;
  479. }
  480. }
  481. if (needs_update)
  482. {
  483. LLWearableType::EType driver_type = (LLWearableType::EType)getWearableType();
  484. // If we've gotten here, we've added a new wearable of type "type"
  485. // Thus this wearable needs to get updates from the driver wearable.
  486. // The call to setVisualParamWeight seems redundant, but is necessary
  487. // as the number of driven wearables has changed since the last update. -Nyx
  488. LLWearable *wearable = gAgentWearables.getTopWearable(driver_type);
  489. if (wearable)
  490. {
  491. wearable->setVisualParamWeight(mID, wearable->getVisualParamWeight(mID), false);
  492. }
  493. }
  494. }
  495. //-----------------------------------------------------------------------------
  496. // getDrivenWeight()
  497. //-----------------------------------------------------------------------------
  498. F32 LLDriverParam::getDrivenWeight(const LLDrivenEntry* driven, F32 input_weight)
  499. {
  500. F32 min_weight = getMinWeight();
  501. F32 max_weight = getMaxWeight();
  502. const LLDrivenEntryInfo* info = driven->mInfo;
  503. F32 driven_weight = 0.f;
  504. F32 driven_min = driven->mParam->getMinWeight();
  505. F32 driven_max = driven->mParam->getMaxWeight();
  506. if( input_weight <= info->mMin1 )
  507. {
  508. if( info->mMin1 == info->mMax1 &&
  509. info->mMin1 <= min_weight)
  510. {
  511. driven_weight = driven_max;
  512. }
  513. else
  514. {
  515. driven_weight = driven_min;
  516. }
  517. }
  518. else
  519. if( input_weight <= info->mMax1 )
  520. {
  521. F32 t = (input_weight - info->mMin1) / (info->mMax1 - info->mMin1 );
  522. driven_weight = driven_min + t * (driven_max - driven_min);
  523. }
  524. else
  525. if( input_weight <= info->mMax2 )
  526. {
  527. driven_weight = driven_max;
  528. }
  529. else
  530. if( input_weight <= info->mMin2 )
  531. {
  532. F32 t = (input_weight - info->mMax2) / (info->mMin2 - info->mMax2 );
  533. driven_weight = driven_max + t * (driven_min - driven_max);
  534. }
  535. else
  536. {
  537. if (info->mMax2 >= max_weight)
  538. {
  539. driven_weight = driven_max;
  540. }
  541. else
  542. {
  543. driven_weight = driven_min;
  544. }
  545. }
  546. return driven_weight;
  547. }
  548. void LLDriverParam::setDrivenWeight(LLDrivenEntry *driven, F32 driven_weight, bool upload_bake)
  549. {
  550. if(isAgentAvatarValid() &&
  551. mWearablep &&
  552. driven->mParam->getCrossWearable() &&
  553. mWearablep->isOnTop())
  554. {
  555. // call setWeight through LLVOAvatarSelf so other wearables can be updated with the correct values
  556. gAgentAvatarp->setVisualParamWeight( (LLVisualParam*)driven->mParam, driven_weight, upload_bake );
  557. }
  558. else
  559. {
  560. driven->mParam->setWeight( driven_weight, upload_bake );
  561. }
  562. }