llflexibleobject.cpp 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945
  1. /**
  2. * @file llflexibleobject.cpp
  3. * @brief Flexible object implementation
  4. *
  5. * $LicenseInfo:firstyear=2006&license=viewergpl$
  6. *
  7. * Copyright (c) 2006-2009, Linden Research, Inc.
  8. *
  9. * Second Life Viewer Source Code
  10. * The source code in this file ("Source Code") is provided by Linden Lab
  11. * to you under the terms of the GNU General Public License, version 2.0
  12. * ("GPL"), unless you have obtained a separate licensing agreement
  13. * ("Other License"), formally executed by you and Linden Lab. Terms of
  14. * the GPL can be found in doc/GPL-license.txt in this distribution, or
  15. * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
  16. *
  17. * There are special exceptions to the terms and conditions of the GPL as
  18. * it is applied to this Source Code. View the full text of the exception
  19. * in the file doc/FLOSS-exception.txt in this software distribution, or
  20. * online at
  21. * http://secondlifegrid.net/programs/open_source/licensing/flossexception
  22. *
  23. * By copying, modifying or distributing this software, you acknowledge
  24. * that you have read and understood your obligations described above,
  25. * and agree to abide by those obligations.
  26. *
  27. * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
  28. * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
  29. * COMPLETENESS OR PERFORMANCE.
  30. * $/LicenseInfo$
  31. */
  32. #include "llviewerprecompiledheaders.h"
  33. #include "llflexibleobject.h"
  34. #include "llfasttimer.h"
  35. #include "llglheaders.h"
  36. #include "llagent.h"
  37. #include "lldrawpoolbump.h"
  38. #include "llface.h"
  39. #include "llpipeline.h"
  40. #include "llsky.h"
  41. #include "llviewercamera.h"
  42. #include "llviewercontrol.h"
  43. #include "llviewerobjectlist.h"
  44. #include "llviewerregion.h"
  45. #include "llviewertexturelist.h"
  46. #include "llvoavatar.h"
  47. #include "llworld.h"
  48. //static
  49. F32 LLVolumeImplFlexible::sUpdateFactor = 1.f;
  50. LLVolumeImplFlexible::instances_list_t LLVolumeImplFlexible::sInstanceList;
  51. constexpr F32 FLEXI_FPS = 60.f; // 60 flexi updates per second
  52. // LLFlexibleObjectData::pack/unpack now in llprimitive.cpp
  53. LLVolumeImplFlexible::LLVolumeImplFlexible(LLViewerObject* vo,
  54. LLFlexibleObjectData* attributes)
  55. : mVO(vo),
  56. mAttributes(attributes),
  57. mLastFrameNum(0),
  58. mLastUpdatePeriod(0),
  59. mInitializedRes(-1),
  60. mSimulateRes(0),
  61. mRenderRes(1),
  62. mCollisionSphereRadius(0.f),
  63. mInitialized(false),
  64. mUpdated(false)
  65. {
  66. static U32 seed = 0;
  67. mID = seed++;
  68. if (mVO->mDrawable.notNull())
  69. {
  70. mVO->mDrawable->makeActive();
  71. }
  72. mInstanceIndex = sInstanceList.size();
  73. sInstanceList.push_back(this);
  74. }
  75. //virtual
  76. LLVolumeImplFlexible::~LLVolumeImplFlexible()
  77. {
  78. S32 end_idx = sInstanceList.size() - 1;
  79. if (end_idx != mInstanceIndex)
  80. {
  81. sInstanceList[mInstanceIndex] = sInstanceList[end_idx];
  82. sInstanceList[mInstanceIndex]->mInstanceIndex = mInstanceIndex;
  83. }
  84. sInstanceList.pop_back();
  85. }
  86. //static
  87. void LLVolumeImplFlexible::initClass()
  88. {
  89. // Let's avoid memory fragmentation over time...
  90. sInstanceList.reserve(8192);
  91. }
  92. //static
  93. void LLVolumeImplFlexible::updateClass()
  94. {
  95. U64 virtual_frame = LLTimer::getElapsedSeconds() * FLEXI_FPS;
  96. for (std::vector<LLVolumeImplFlexible*>::iterator
  97. iter = sInstanceList.begin(), end = sInstanceList.end();
  98. iter != end; ++iter)
  99. {
  100. LLVolumeImplFlexible* impl = *iter;
  101. // Note: by now update period might have changed
  102. if (impl->mRenderRes == -1 ||
  103. impl->mLastFrameNum +
  104. impl->mLastUpdatePeriod <= virtual_frame ||
  105. impl->mLastFrameNum > virtual_frame) // time issues, overflow
  106. {
  107. impl->doIdleUpdate();
  108. }
  109. }
  110. }
  111. //static
  112. void LLVolumeImplFlexible::dumpStats()
  113. {
  114. llinfos << "sInstanceList capacity reached: " << sInstanceList.capacity()
  115. << llendl;
  116. }
  117. LLVector3 LLVolumeImplFlexible::getFramePosition() const
  118. {
  119. return mVO->getRenderPosition();
  120. }
  121. LLQuaternion LLVolumeImplFlexible::getFrameRotation() const
  122. {
  123. return mVO->getRenderRotation();
  124. }
  125. //virtual
  126. void LLVolumeImplFlexible::onParameterChanged(U16 param_type,
  127. LLNetworkData* data,
  128. bool in_use,
  129. bool local_origin)
  130. {
  131. if (param_type == LLNetworkData::PARAMS_FLEXIBLE)
  132. {
  133. mAttributes = (LLFlexibleObjectData*)data;
  134. setAttributesOfAllSections();
  135. }
  136. }
  137. //virtual
  138. void LLVolumeImplFlexible::onShift(const LLVector4a& shift_vector)
  139. {
  140. // VECTORIZE THIS
  141. LLVector3 shift(shift_vector.getF32ptr());
  142. for (S32 section = 0; section < (1 << FLEXIBLE_OBJECT_MAX_SECTIONS) + 1;
  143. ++section)
  144. {
  145. mSection[section].mPosition += shift;
  146. }
  147. }
  148. void LLVolumeImplFlexible::setParentPositionAndRotationDirectly(LLVector3 p,
  149. LLQuaternion r)
  150. {
  151. mParentPosition = p;
  152. mParentRotation = r;
  153. }
  154. void LLVolumeImplFlexible::remapSections(LLFlexibleObjectSection* source,
  155. S32 source_sections,
  156. LLFlexibleObjectSection* dest,
  157. S32 dest_sections)
  158. {
  159. S32 num_output_sections = 1 << dest_sections;
  160. LLVector3 scale = mVO->mDrawable->getScale();
  161. F32 source_section_length = scale.mV[VZ] / (F32)(1 << source_sections);
  162. F32 section_length = scale.mV[VZ] / (F32)num_output_sections;
  163. if (source_sections == -1)
  164. {
  165. // Generate all from section 0
  166. dest[0] = source[0];
  167. for (S32 section = 0; section < num_output_sections; ++section)
  168. {
  169. dest[section + 1] = dest[section];
  170. dest[section + 1].mPosition += dest[section].mDirection *
  171. section_length;
  172. dest[section + 1].mVelocity.setZero();
  173. }
  174. }
  175. else if (source_sections > dest_sections)
  176. {
  177. // Copy, skipping sections
  178. S32 num_steps = 1 << (source_sections - dest_sections);
  179. // Copy from left to right since it may be an in-place computation
  180. for (S32 section = 0; section < num_output_sections; ++section)
  181. {
  182. dest[section + 1] = source[(section + 1) * num_steps];
  183. }
  184. dest[0] = source[0];
  185. }
  186. else if (source_sections < dest_sections)
  187. {
  188. // Interpolate section info
  189. // Iterate from right to left since it may be an in-place computation
  190. S32 step_shift = dest_sections - source_sections;
  191. S32 num_steps = 1 << step_shift;
  192. for (S32 section = num_output_sections - num_steps; section >= 0;
  193. section -= num_steps)
  194. {
  195. LLFlexibleObjectSection* last_source_section =
  196. &source[section >> step_shift];
  197. LLFlexibleObjectSection* source_section =
  198. &source[(section >> step_shift) + 1];
  199. // Cubic interpolation of position
  200. // At^3 + Bt^2 + Ct + D = f(t)
  201. LLVector3 d = last_source_section->mPosition;
  202. LLVector3 c = last_source_section->mdPosition *
  203. source_section_length;
  204. LLVector3 y = source_section->mdPosition * source_section_length -
  205. c;
  206. LLVector3 x = source_section->mPosition - d - c;
  207. LLVector3 a = y - 2 * x;
  208. LLVector3 b = x - a;
  209. F32 t_inc = 1.f / F32(num_steps);
  210. F32 t = t_inc;
  211. for (S32 step = 1; step < num_steps; ++step)
  212. {
  213. dest[section + step].mScale = lerp(last_source_section->mScale,
  214. source_section->mScale, t);
  215. dest[section + step].mAxisRotation =
  216. slerp(t, last_source_section->mAxisRotation,
  217. source_section->mAxisRotation);
  218. // Evaluate output interpolated values
  219. F32 t_sq = t * t;
  220. dest[section + step].mPosition = t_sq * (t * a + b) +
  221. t * c + d;
  222. dest[section + step].mRotation =
  223. slerp(t, last_source_section->mRotation,
  224. source_section->mRotation);
  225. dest[section + step].mVelocity =
  226. lerp(last_source_section->mVelocity,
  227. source_section->mVelocity, t);
  228. dest[section + step].mDirection =
  229. lerp(last_source_section->mDirection,
  230. source_section->mDirection, t);
  231. dest[section + step].mdPosition =
  232. lerp(last_source_section->mdPosition,
  233. source_section->mdPosition, t);
  234. dest[section + num_steps] = *source_section;
  235. t += t_inc;
  236. }
  237. }
  238. dest[0] = source[0];
  239. }
  240. else
  241. {
  242. // Numbers are equal. Copy info
  243. for (S32 section = 0; section <= num_output_sections; ++section)
  244. {
  245. dest[section] = source[section];
  246. }
  247. }
  248. }
  249. void LLVolumeImplFlexible::setAttributesOfAllSections(LLVector3* in_scale)
  250. {
  251. LLVector2 bottom_scale, top_scale;
  252. F32 begin_rot = 0, end_rot = 0;
  253. LLVolume* volumep = mVO->getVolume();
  254. if (volumep)
  255. {
  256. const LLPathParams& params = volumep->getParams().getPathParams();
  257. bottom_scale = params.getBeginScale();
  258. top_scale = params.getEndScale();
  259. begin_rot = F_PI * params.getTwistBegin();
  260. end_rot = F_PI * params.getTwistEnd();
  261. }
  262. if (!mVO->mDrawable)
  263. {
  264. return;
  265. }
  266. S32 num_sections = 1 << mSimulateRes;
  267. LLVector3 scale = in_scale ? *in_scale : mVO->mDrawable->getScale();
  268. mSection[0].mPosition = getAnchorPosition();
  269. mSection[0].mDirection = LLVector3::z_axis * getFrameRotation();
  270. mSection[0].mdPosition = mSection[0].mDirection;
  271. mSection[0].mScale.set(scale.mV[VX] * bottom_scale.mV[0],
  272. scale.mV[VY] * bottom_scale.mV[1]);
  273. mSection[0].mVelocity.setZero();
  274. mSection[0].mAxisRotation.setAngleAxis(begin_rot, 0.f, 0.f, 1.f);
  275. remapSections(mSection, mInitializedRes, mSection, mSimulateRes);
  276. mInitializedRes = mSimulateRes;
  277. F32 t_inc = 1.f / F32(num_sections);
  278. F32 t = t_inc;
  279. for (S32 i = 1; i <= num_sections; ++i)
  280. {
  281. mSection[i].mAxisRotation.setAngleAxis(lerp(begin_rot, end_rot, t),
  282. 0.f, 0.f, 1.f);
  283. mSection[i].mScale = LLVector2(scale.mV[VX] * lerp(bottom_scale.mV[0],
  284. top_scale.mV[0], t),
  285. scale.mV[VY] * lerp(bottom_scale.mV[1],
  286. top_scale.mV[1], t));
  287. t += t_inc;
  288. }
  289. }
  290. void LLVolumeImplFlexible::updateRenderRes()
  291. {
  292. if (!mAttributes) return;
  293. LLDrawable* drawablep = mVO->mDrawable;
  294. S32 new_res = mAttributes->getSimulateLOD();
  295. #if 1 // Optimal approximation of previous behavior that does not rely on atan2
  296. F32 app_angle = mVO->getScale().mV[2] / drawablep->mDistanceWRTCamera;
  297. // Rendering sections increases with visible angle on the screen
  298. mRenderRes = (S32)(12.f * app_angle);
  299. #else // legacy behavior
  300. // Number of segments only cares about z axis
  301. F32 app_angle = ll_round(atan2f(mVO->getScale().mV[2] * 2.f,
  302. drawablep->mDistanceWRTCamera) *
  303. RAD_TO_DEG, 0.01f);
  304. // Rendering sections increases with visible angle on the screen
  305. mRenderRes = (S32)(FLEXIBLE_OBJECT_MAX_SECTIONS * 4 * app_angle *
  306. DEG_TO_RAD / gViewerCamera.getView());
  307. #endif
  308. mRenderRes = llclamp(mRenderRes, new_res - 1,
  309. (S32)FLEXIBLE_OBJECT_MAX_SECTIONS);
  310. // Throttle back simulation of segments we're not rendering
  311. if (mRenderRes < new_res)
  312. {
  313. new_res = mRenderRes;
  314. }
  315. if (!mInitialized || mSimulateRes != new_res)
  316. {
  317. mSimulateRes = new_res;
  318. setAttributesOfAllSections();
  319. mInitialized = true;
  320. }
  321. }
  322. //-----------------------------------------------------------------------------
  323. // This calculates the physics of the flexible object. Note that it has to be 0
  324. // updated every time step. In the future, perhaps there could be an
  325. // optimization similar to what Havok does for objects that are stationary.
  326. //-----------------------------------------------------------------------------
  327. //virtual
  328. void LLVolumeImplFlexible::doIdleUpdate()
  329. {
  330. LLDrawable* drawablep = mVO->mDrawable;
  331. if (!drawablep) return;
  332. LL_FAST_TIMER(FTM_FLEXIBLE_UPDATE);
  333. // Ensure drawable is active
  334. drawablep->makeActive();
  335. if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_FLEXIBLE))
  336. {
  337. bool visible = drawablep->isVisible();
  338. if (!mInitialized || (mSimulateRes == 0 && visible))
  339. {
  340. updateRenderRes();
  341. gPipeline.markRebuild(drawablep, LLDrawable::REBUILD_POSITION);
  342. }
  343. else
  344. {
  345. F32 pixel_area = mVO->getPixelArea();
  346. U32 update_period = (U32)(gViewerCamera.getScreenPixelArea() *
  347. 0.01f / (pixel_area *
  348. (sUpdateFactor + 1.f))) + 1;
  349. // Note: flexies afar will be rarely updated, closer ones will be
  350. // updated more frequently. But frequency differences are extremely
  351. // noticeable, so consider modifying update factor, or at least
  352. // clamping value a bit more from both sides.
  353. update_period = llclamp(update_period, 1U, 32U);
  354. // We control how fast flexies update, buy splitting updates among
  355. // frames
  356. U64 virtual_frame = LLTimer::getElapsedSeconds() * FLEXI_FPS;
  357. if (visible)
  358. {
  359. if (!drawablep->isState(LLDrawable::IN_REBUILD_QUEUE) &&
  360. mVO->getPixelArea() > 256.f)
  361. {
  362. U32 id;
  363. if (mVO->isRootEdit())
  364. {
  365. id = mID;
  366. }
  367. else
  368. {
  369. LLVOVolume* parent = (LLVOVolume*)mVO->getParent();
  370. if (!parent) return; // Paranoia
  371. id = parent->getVolumeInterfaceID();
  372. }
  373. // Throttle flexies and spread load by preventing them from
  374. // updating in same frame. Reflects how many frames we need
  375. //to wait before next update.
  376. U64 throttling_delay = (virtual_frame + id) %
  377. update_period;
  378. if ((throttling_delay == 0 &&
  379. // One or more virtual frames per frame
  380. mLastFrameNum < virtual_frame) ||
  381. // ... or if we missed a virtual frame
  382. (mLastFrameNum + update_period < virtual_frame) ||
  383. // ... or in case of an overflow
  384. mLastFrameNum > virtual_frame)
  385. {
  386. // We need mLastFrameNum to compensate for 'unreliable
  387. // time' and to filter 'duplicate' frames. If it
  388. // happened too late, subtract throttling_delay (it is
  389. // zero otherwise)
  390. mLastFrameNum = virtual_frame - throttling_delay;
  391. // Store update period for updateClass().
  392. // Note: consider substituting update_period with
  393. // mLastUpdatePeriod everywhere.
  394. mLastUpdatePeriod = update_period;
  395. updateRenderRes();
  396. mVO->shrinkWrap();
  397. gPipeline.markRebuild(drawablep,
  398. LLDrawable::REBUILD_POSITION);
  399. }
  400. }
  401. }
  402. else
  403. {
  404. mLastFrameNum = virtual_frame;
  405. mLastUpdatePeriod = update_period;
  406. }
  407. }
  408. }
  409. }
  410. LL_INLINE S32 log2(S32 x)
  411. {
  412. S32 ret = 0;
  413. while (x > 1)
  414. {
  415. ++ret;
  416. x >>= 1;
  417. }
  418. return ret;
  419. }
  420. void LLVolumeImplFlexible::doFlexibleUpdate()
  421. {
  422. LL_FAST_TIMER(FTM_DO_FLEXIBLE_UPDATE);
  423. LLVolume* volume = mVO->getVolume();
  424. LLPath* path = &volume->getPath();
  425. if ((mSimulateRes == 0 || !mInitialized) && mVO->mDrawable->isVisible())
  426. {
  427. doIdleUpdate();
  428. if (mSimulateRes != 0 ||
  429. !gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_FLEXIBLE))
  430. {
  431. // We did not get updated or initialized, proceeding without can be
  432. // dangerous
  433. return;
  434. }
  435. }
  436. if (!mInitialized || !mAttributes)
  437. {
  438. // The object is not visible
  439. return;
  440. }
  441. // Fix for MAINT-1894
  442. // Skipping the flexible update if render res is negative. If we were to
  443. // continue with a negative value, the subsequent
  444. // S32 num_render_sections = 1 << mRenderRes;
  445. // code would result in a really large number of render sections which
  446. // would then create a length exception in the std::vector::resize()
  447. // method.
  448. if (mRenderRes < 0)
  449. {
  450. return;
  451. }
  452. S32 num_sections = 1 << mSimulateRes;
  453. LLVector3 base_pos = getFramePosition();
  454. LLQuaternion base_rot = getFrameRotation();
  455. LLQuaternion parent_segment_rot = base_rot;
  456. LLVector3 anchor_dir_rotated = LLVector3::z_axis * parent_segment_rot;
  457. LLVector3 anchor_scale = mVO->mDrawable->getScale();
  458. F32 section_length = anchor_scale.mV[VZ] / (F32)num_sections;
  459. F32 inv_section_length = 1.f / section_length;
  460. S32 i;
  461. // ANCHOR position is offset from BASE position (centroid) by half the
  462. // length
  463. LLVector3 anchor_pos = base_pos -
  464. anchor_scale.mV[VZ] * 0.5f * anchor_dir_rotated;
  465. mSection[0].mPosition = anchor_pos;
  466. mSection[0].mDirection = anchor_dir_rotated;
  467. mSection[0].mRotation = base_rot;
  468. // Coefficients which are constant across sections
  469. F32 seconds_this_frame = llmin(mTimer.getElapsedTimeAndResetF32(), 0.2f);
  470. F32 t_factor = mAttributes->getTension() * 0.1f;
  471. t_factor = llmin(t_factor *
  472. (1.f - powf(0.85f, seconds_this_frame * 30.f)),
  473. FLEXIBLE_OBJECT_MAX_INTERNAL_TENSION_FORCE);
  474. F32 friction_coeff = mAttributes->getAirFriction() * 2.f + 1.f;
  475. friction_coeff = llmax(powf(10.f, friction_coeff * seconds_this_frame),
  476. 1.f);
  477. F32 momentum = 1.f / friction_coeff;
  478. F32 wind_factor = mAttributes->getWindSensitivity() * 0.1f *
  479. section_length * seconds_this_frame;
  480. F32 max_angle = atanf(section_length * 2.f);
  481. F32 force_factor = section_length * seconds_this_frame;
  482. // Update simulated sections
  483. LLVector3 parent_section_vec, parent_section_pos, parent_dir, last_pos;
  484. LLQuaternion delta_rot;
  485. for (i = 1; i <= num_sections; ++i)
  486. {
  487. // Save value of position as last_pos
  488. last_pos = mSection[i].mPosition;
  489. // Gravity
  490. mSection[i].mPosition.mV[2] -= mAttributes->getGravity() * force_factor;
  491. // Wind force
  492. if (mAttributes->getWindSensitivity() > 0.001f && gAgent.getRegion())
  493. {
  494. mSection[i].mPosition +=
  495. gAgent.getRegion()->mWind.getVelocity(mSection[i].mPosition) *
  496. wind_factor;
  497. }
  498. // User-defined force
  499. mSection[i].mPosition += mAttributes->getUserForce() * force_factor;
  500. // Tension (rigidity, stiffness)
  501. parent_section_pos = mSection[i - 1].mPosition;
  502. parent_dir = mSection[i - 1].mDirection;
  503. if (i == 1)
  504. {
  505. parent_section_vec = mSection[0].mDirection;
  506. }
  507. else
  508. {
  509. parent_section_vec = mSection[i - 2].mDirection;
  510. }
  511. mSection[i].mPosition += (parent_section_vec * section_length -
  512. (mSection[i].mPosition -
  513. parent_section_pos)) * t_factor;
  514. #if 0 // Sphere collision, currently not used
  515. if (mAttributes->mUsingCollisionSphere)
  516. {
  517. LLVector3 center_collision_sphere_vec =
  518. mCollisionSpherePosition - mSection[i].mPosition;
  519. if (center_collision_sphere_vec.lengthSquared() <
  520. mCollisionSphereRadius * mCollisionSphereRadius)
  521. {
  522. F32 center_collision_sphere_dist =
  523. center_collision_sphere_vec.length();
  524. F32 penetration = mCollisionSphereRadius -
  525. center_collision_sphere_dist;
  526. LLVector3 center_collision_sphere_norm;
  527. if (center_collision_sphere_dist > 0.f)
  528. {
  529. center_collision_sphere_norm =
  530. center_collision_sphere_vec /
  531. center_collision_sphere_dist;
  532. }
  533. else // rare
  534. {
  535. // Arbitrary
  536. center_collision_sphere_norm = LLVector3::x_axis;
  537. }
  538. // Push the position out to the surface of the collision sphere
  539. mSection[i].mPosition -= center_collision_sphere_norm *
  540. penetration;
  541. }
  542. }
  543. #endif
  544. // Inertia
  545. mSection[i].mPosition += mSection[i].mVelocity * momentum;
  546. // Clamp length & rotation
  547. mSection[i].mDirection = mSection[i].mPosition - parent_section_pos;
  548. mSection[i].mDirection.normalize();
  549. delta_rot.shortestArc(parent_dir, mSection[i].mDirection);
  550. F32 angle;
  551. LLVector3 axis;
  552. delta_rot.getAngleAxis(&angle, axis);
  553. if (angle > F_PI)
  554. {
  555. angle -= 2.f * F_PI;
  556. }
  557. else if (angle < -F_PI)
  558. {
  559. angle += 2.f * F_PI;
  560. }
  561. if (angle > max_angle)
  562. {
  563. // Angle = 0.5f * (angle + max_angle);
  564. delta_rot.setAngleAxis(max_angle, axis);
  565. }
  566. else if (angle < -max_angle)
  567. {
  568. // Angle = 0.5f * (angle - max_angle);
  569. delta_rot.setAngleAxis(-max_angle, axis);
  570. }
  571. parent_segment_rot = parent_segment_rot * delta_rot;
  572. mSection[i].mDirection = parent_dir * delta_rot;
  573. mSection[i].mPosition = parent_section_pos + mSection[i].mDirection *
  574. section_length;
  575. mSection[i].mRotation = parent_segment_rot;
  576. if (i > 1)
  577. {
  578. // Propogate half the rotation up to the parent
  579. LLQuaternion half_delta_rot(angle * 0.5f, axis);
  580. mSection[i - 1].mRotation = mSection[i - 1].mRotation *
  581. half_delta_rot;
  582. }
  583. // Calculate velocity
  584. mSection[i].mVelocity = mSection[i].mPosition - last_pos;
  585. if (mSection[i].mVelocity.lengthSquared() > 1.f)
  586. {
  587. mSection[i].mVelocity.normalize();
  588. }
  589. }
  590. // Calculate derivatives (not necessary until normals are automagically
  591. // generated)
  592. mSection[0].mdPosition = (mSection[1].mPosition - mSection[0].mPosition) *
  593. inv_section_length;
  594. // i = 1..NumSections-1
  595. LLVector3 a, b;
  596. for (i = 1; i < num_sections; ++i)
  597. {
  598. // Quadratic numerical derivative of position
  599. // f(-L1) = aL1^2 - bL1 + c = f1
  600. // f(0) = c = f2
  601. // f(L2) = aL2^2 + bL2 + c = f3
  602. // f = ax^2 + bx + c
  603. // d/dx f = 2ax + b
  604. // d/dx f(0) = b
  605. // c = f2
  606. // a = [(f1-c)/L1 + (f3-c)/L2] / (L1+L2)
  607. // b = (f3-c-aL2^2)/L2
  608. a = (mSection[i - 1].mPosition - mSection[i].mPosition +
  609. mSection[i + 1].mPosition - mSection[i].mPosition) * 0.5f *
  610. inv_section_length * inv_section_length;
  611. b = mSection[i + 1].mPosition - mSection[i].mPosition -
  612. a * (section_length * section_length);
  613. b *= inv_section_length;
  614. mSection[i].mdPosition = b;
  615. }
  616. // i = NumSections
  617. mSection[i].mdPosition = (mSection[i].mPosition -
  618. mSection[i - 1].mPosition) * inv_section_length;
  619. // Create points
  620. S32 num_render_sections = 1 << mRenderRes;
  621. if (path->getPathLength() != num_render_sections + 1)
  622. {
  623. ((LLVOVolume*)mVO)->mVolumeChanged = true;
  624. volume->resizePath(num_render_sections + 1);
  625. }
  626. LLFlexibleObjectSection new_section[(1 << FLEXIBLE_OBJECT_MAX_SECTIONS) + 1];
  627. remapSections(mSection, mSimulateRes, new_section, mRenderRes);
  628. // Generate transform from global to prim space
  629. delta_rot = ~getFrameRotation();
  630. LLVector3 delta_pos = -getFramePosition() * delta_rot;
  631. // Vertex transform (4x4)
  632. LLVector3 x_axis = LLVector3::x_axis * delta_rot;
  633. LLVector3 y_axis = LLVector3::y_axis * delta_rot;
  634. LLVector3 z_axis = LLVector3::z_axis * delta_rot;
  635. LLMatrix4 rel_xform;
  636. rel_xform.initRows(LLVector4(x_axis, 0.f), LLVector4(y_axis, 0.f),
  637. LLVector4(z_axis, 0.f), LLVector4(delta_pos, 1.f));
  638. LLQuaternion rot;
  639. for (i = 0; i <= num_render_sections; ++i)
  640. {
  641. LLPath::PathPt* new_point = &path->mPath[i];
  642. LLVector3 pos = new_section[i].mPosition * rel_xform;
  643. rot = mSection[i].mAxisRotation * new_section[i].mRotation * delta_rot;
  644. LLVector3 np(new_point->mPos.getF32ptr());
  645. if (!mUpdated ||
  646. (np - pos).length() / mVO->mDrawable->mDistanceWRTCamera > .001f)
  647. {
  648. new_point->mPos.load3((new_section[i].mPosition * rel_xform).mV);
  649. mUpdated = false;
  650. }
  651. new_point->mRot.loadu(LLMatrix3(rot));
  652. new_point->mScale.set(new_section[i].mScale.mV[0],
  653. new_section[i].mScale.mV[1], 0.f, 1.f);
  654. new_point->mTexT = (F32)i / num_render_sections;
  655. }
  656. mLastSegmentRotation = parent_segment_rot;
  657. }
  658. //virtual
  659. void LLVolumeImplFlexible::preRebuild()
  660. {
  661. if (!mUpdated)
  662. {
  663. doFlexibleRebuild(false);
  664. }
  665. }
  666. void LLVolumeImplFlexible::doFlexibleRebuild(bool rebuild_volume)
  667. {
  668. LL_FAST_TIMER(FTM_FLEXIBLE_REBUILD);
  669. mUpdated = true;
  670. LLVolume* volume = mVO->getVolume();
  671. if (!volume)
  672. {
  673. return;
  674. }
  675. if (rebuild_volume)
  676. {
  677. volume->setDirty();
  678. }
  679. volume->regen();
  680. }
  681. //virtual
  682. void LLVolumeImplFlexible::onSetScale(const LLVector3& scale, bool damped)
  683. {
  684. setAttributesOfAllSections((LLVector3*)&scale);
  685. }
  686. //virtual
  687. bool LLVolumeImplFlexible::doUpdateGeometry(LLDrawable* drawable)
  688. {
  689. LLVOVolume* volume = (LLVOVolume*)mVO;
  690. if (!volume || volume->isDead() || volume->mDrawable.isNull() ||
  691. volume->mDrawable->isDead())
  692. {
  693. return true; // No update to complete
  694. }
  695. if (mVO->isAttachment())
  696. {
  697. // Do not update flexible attachments for impostored avatars unless the
  698. // impostor is being updated this frame.
  699. LLViewerObject* parent = (LLViewerObject*)mVO->getParent();
  700. while (parent && !parent->isAvatar())
  701. {
  702. parent = (LLViewerObject*)parent->getParent();
  703. }
  704. if (parent)
  705. {
  706. LLVOAvatar* avatar = (LLVOAvatar*)parent;
  707. if (avatar->isImpostor() && !avatar->needsImpostorUpdate())
  708. {
  709. return true;
  710. }
  711. }
  712. }
  713. if (volume->mLODChanged)
  714. {
  715. LLVolumeParams volume_params = volume->getVolume()->getParams();
  716. volume->setVolume(volume_params, 0);
  717. mUpdated = false;
  718. }
  719. volume->updateRelativeXform();
  720. doFlexibleUpdate();
  721. // Object may have been rotated, which means it needs a rebuild.
  722. bool rotated = false;
  723. LLQuaternion cur_rotation = getFrameRotation();
  724. if (cur_rotation != mLastFrameRotation)
  725. {
  726. mLastFrameRotation = cur_rotation;
  727. rotated = true;
  728. }
  729. if (volume->mLODChanged || volume->mFaceMappingChanged ||
  730. volume->mVolumeChanged ||
  731. drawable->isState(LLDrawable::REBUILD_MATERIAL))
  732. {
  733. volume->regenFaces();
  734. volume->mDrawable->setState(LLDrawable::REBUILD_VOLUME);
  735. volume->dirtySpatialGroup();
  736. doFlexibleRebuild(volume->mVolumeChanged);
  737. volume->genBBoxes(isVolumeGlobal());
  738. }
  739. else if (!mUpdated || rotated)
  740. {
  741. volume->mDrawable->setState(LLDrawable::REBUILD_POSITION);
  742. LLSpatialGroup* group = volume->mDrawable->getSpatialGroup();
  743. if (group)
  744. {
  745. group->dirtyMesh();
  746. }
  747. volume->genBBoxes(isVolumeGlobal());
  748. }
  749. volume->mVolumeChanged = false;
  750. volume->mLODChanged = false;
  751. volume->mFaceMappingChanged = false;
  752. // Clear UV flag
  753. drawable->clearState(LLDrawable::UV);
  754. return true;
  755. }
  756. LLVector3 LLVolumeImplFlexible::getEndPosition()
  757. {
  758. S32 num_sections = 1 << mAttributes->getSimulateLOD();
  759. return mSection[num_sections].mPosition;
  760. }
  761. LLVector3 LLVolumeImplFlexible::getNodePosition(S32 node_idx)
  762. {
  763. S32 num_sections = 1 << mAttributes->getSimulateLOD();
  764. if (node_idx > num_sections - 1)
  765. {
  766. node_idx = num_sections - 1;
  767. }
  768. else if (node_idx < 0)
  769. {
  770. node_idx = 0;
  771. }
  772. return mSection[node_idx].mPosition;
  773. }
  774. LLVector3 LLVolumeImplFlexible::getPivotPosition() const
  775. {
  776. return getAnchorPosition();
  777. }
  778. LLVector3 LLVolumeImplFlexible::getAnchorPosition() const
  779. {
  780. LLVector3 anchor_dir_rotated = LLVector3::z_axis * getFrameRotation();
  781. LLVector3 anchor_scale = mVO->mDrawable->getScale();
  782. return getFramePosition() - anchor_scale.mV[VZ] * 0.5f *
  783. anchor_dir_rotated;
  784. }
  785. LLQuaternion LLVolumeImplFlexible::getEndRotation()
  786. {
  787. return mLastSegmentRotation;
  788. }
  789. //virtual
  790. void LLVolumeImplFlexible::updateRelativeXform(bool force_identity)
  791. {
  792. LLVOVolume* vo = (LLVOVolume*)mVO;
  793. if (!vo || !vo->mDrawable) return; // Paranoia
  794. // Matrix from local space to parent relative/global space
  795. LLQuaternion delta_rot;
  796. LLVector3 delta_pos;
  797. bool use_identity = force_identity || vo->mDrawable->isSpatialRoot();
  798. if (!use_identity)
  799. {
  800. delta_rot = vo->mDrawable->getRotation();
  801. delta_pos = vo->mDrawable->getPosition();
  802. }
  803. // Vertex transform (4x4)
  804. LLVector3 x_axis = LLVector3::x_axis * delta_rot;
  805. LLVector3 y_axis = LLVector3::y_axis * delta_rot;
  806. LLVector3 z_axis = LLVector3::z_axis * delta_rot;
  807. vo->mRelativeXform.initRows(LLVector4(x_axis, 0.f), LLVector4(y_axis, 0.f),
  808. LLVector4(z_axis, 0.f),
  809. LLVector4(delta_pos, 1.f));
  810. x_axis.normalize();
  811. y_axis.normalize();
  812. z_axis.normalize();
  813. vo->mRelativeXformInvTrans.setRows(x_axis, y_axis, z_axis);
  814. }
  815. //virtual
  816. const LLMatrix4& LLVolumeImplFlexible::getWorldMatrix(LLXformMatrix* xform) const
  817. {
  818. return xform->getWorldMatrix();
  819. }