PageRenderTime 46ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/indra/newview/llflexibleobject.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 848 lines | 571 code | 139 blank | 138 comment | 83 complexity | c4e4d131f0078bbca37ae5879ee2a70f MD5 | raw file
Possible License(s): LGPL-2.1
  1. /**
  2. * @file llflexibleobject.cpp
  3. * @brief Flexible object implementation
  4. *
  5. * $LicenseInfo:firstyear=2006&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 "pipeline.h"
  28. #include "lldrawpoolbump.h"
  29. #include "llface.h"
  30. #include "llflexibleobject.h"
  31. #include "llglheaders.h"
  32. #include "llrendersphere.h"
  33. #include "llviewerobject.h"
  34. #include "llagent.h"
  35. #include "llsky.h"
  36. #include "llviewercamera.h"
  37. #include "llviewertexturelist.h"
  38. #include "llviewercontrol.h"
  39. #include "llviewerobjectlist.h"
  40. #include "llviewerregion.h"
  41. #include "llworld.h"
  42. #include "llvoavatar.h"
  43. /*static*/ F32 LLVolumeImplFlexible::sUpdateFactor = 1.0f;
  44. static LLFastTimer::DeclareTimer FTM_FLEXIBLE_REBUILD("Rebuild");
  45. static LLFastTimer::DeclareTimer FTM_DO_FLEXIBLE_UPDATE("Update");
  46. // LLFlexibleObjectData::pack/unpack now in llprimitive.cpp
  47. //-----------------------------------------------
  48. // constructor
  49. //-----------------------------------------------
  50. LLVolumeImplFlexible::LLVolumeImplFlexible(LLViewerObject* vo, LLFlexibleObjectData* attributes) :
  51. mVO(vo), mAttributes(attributes)
  52. {
  53. static U32 seed = 0;
  54. mID = seed++;
  55. mInitialized = FALSE;
  56. mUpdated = FALSE;
  57. mInitializedRes = -1;
  58. mSimulateRes = 0;
  59. mFrameNum = 0;
  60. mCollisionSphereRadius = 0.f;
  61. mRenderRes = 1;
  62. if(mVO->mDrawable.notNull())
  63. {
  64. mVO->mDrawable->makeActive() ;
  65. }
  66. }//-----------------------------------------------
  67. LLVector3 LLVolumeImplFlexible::getFramePosition() const
  68. {
  69. return mVO->getRenderPosition();
  70. }
  71. LLQuaternion LLVolumeImplFlexible::getFrameRotation() const
  72. {
  73. return mVO->getRenderRotation();
  74. }
  75. void LLVolumeImplFlexible::onParameterChanged(U16 param_type, LLNetworkData *data, BOOL in_use, bool local_origin)
  76. {
  77. if (param_type == LLNetworkData::PARAMS_FLEXIBLE)
  78. {
  79. mAttributes = (LLFlexibleObjectData*)data;
  80. setAttributesOfAllSections();
  81. }
  82. }
  83. void LLVolumeImplFlexible::onShift(const LLVector4a &shift_vector)
  84. {
  85. //VECTORIZE THIS
  86. LLVector3 shift(shift_vector.getF32ptr());
  87. for (int section = 0; section < (1<<FLEXIBLE_OBJECT_MAX_SECTIONS)+1; ++section)
  88. {
  89. mSection[section].mPosition += shift;
  90. }
  91. }
  92. //-----------------------------------------------------------------------------------------------
  93. void LLVolumeImplFlexible::setParentPositionAndRotationDirectly( LLVector3 p, LLQuaternion r )
  94. {
  95. mParentPosition = p;
  96. mParentRotation = r;
  97. }//-----------------------------------------------------------------------------------------------------
  98. void LLVolumeImplFlexible::remapSections(LLFlexibleObjectSection *source, S32 source_sections,
  99. LLFlexibleObjectSection *dest, S32 dest_sections)
  100. {
  101. S32 num_output_sections = 1<<dest_sections;
  102. LLVector3 scale = mVO->mDrawable->getScale();
  103. F32 source_section_length = scale.mV[VZ] / (F32)(1<<source_sections);
  104. F32 section_length = scale.mV[VZ] / (F32)num_output_sections;
  105. if (source_sections == -1)
  106. {
  107. // Generate all from section 0
  108. dest[0] = source[0];
  109. for (S32 section=0; section<num_output_sections; ++section)
  110. {
  111. dest[section+1] = dest[section];
  112. dest[section+1].mPosition += dest[section].mDirection * section_length;
  113. dest[section+1].mVelocity.setVec( LLVector3::zero );
  114. }
  115. }
  116. else if (source_sections > dest_sections)
  117. {
  118. // Copy, skipping sections
  119. S32 num_steps = 1<<(source_sections-dest_sections);
  120. // Copy from left to right since it may be an in-place computation
  121. for (S32 section=0; section<num_output_sections; ++section)
  122. {
  123. dest[section+1] = source[(section+1)*num_steps];
  124. }
  125. dest[0] = source[0];
  126. }
  127. else if (source_sections < dest_sections)
  128. {
  129. // Interpolate section info
  130. // Iterate from right to left since it may be an in-place computation
  131. S32 step_shift = dest_sections-source_sections;
  132. S32 num_steps = 1<<step_shift;
  133. for (S32 section=num_output_sections-num_steps; section>=0; section -= num_steps)
  134. {
  135. LLFlexibleObjectSection *last_source_section = &source[section>>step_shift];
  136. LLFlexibleObjectSection *source_section = &source[(section>>step_shift)+1];
  137. // Cubic interpolation of position
  138. // At^3 + Bt^2 + Ct + D = f(t)
  139. LLVector3 D = last_source_section->mPosition;
  140. LLVector3 C = last_source_section->mdPosition * source_section_length;
  141. LLVector3 Y = source_section->mdPosition * source_section_length - C; // Helper var
  142. LLVector3 X = (source_section->mPosition - D - C); // Helper var
  143. LLVector3 A = Y - 2*X;
  144. LLVector3 B = X - A;
  145. F32 t_inc = 1.f/F32(num_steps);
  146. F32 t = t_inc;
  147. for (S32 step=1; step<num_steps; ++step)
  148. {
  149. dest[section+step].mScale =
  150. lerp(last_source_section->mScale, source_section->mScale, t);
  151. dest[section+step].mAxisRotation =
  152. slerp(t, last_source_section->mAxisRotation, source_section->mAxisRotation);
  153. // Evaluate output interpolated values
  154. F32 t_sq = t*t;
  155. dest[section+step].mPosition = t_sq*(t*A + B) + t*C + D;
  156. dest[section+step].mRotation =
  157. slerp(t, last_source_section->mRotation, source_section->mRotation);
  158. dest[section+step].mVelocity = lerp(last_source_section->mVelocity, source_section->mVelocity, t);
  159. dest[section+step].mDirection = lerp(last_source_section->mDirection, source_section->mDirection, t);
  160. dest[section+step].mdPosition = lerp(last_source_section->mdPosition, source_section->mdPosition, t);
  161. dest[section+num_steps] = *source_section;
  162. t += t_inc;
  163. }
  164. }
  165. dest[0] = source[0];
  166. }
  167. else
  168. {
  169. // numbers are equal. copy info
  170. for (S32 section=0; section <= num_output_sections; ++section)
  171. {
  172. dest[section] = source[section];
  173. }
  174. }
  175. }
  176. //-----------------------------------------------------------------------------
  177. void LLVolumeImplFlexible::setAttributesOfAllSections(LLVector3* inScale)
  178. {
  179. LLVector2 bottom_scale, top_scale;
  180. F32 begin_rot = 0, end_rot = 0;
  181. if (mVO->getVolume())
  182. {
  183. const LLPathParams &params = mVO->getVolume()->getParams().getPathParams();
  184. bottom_scale = params.getBeginScale();
  185. top_scale = params.getEndScale();
  186. begin_rot = F_PI * params.getTwistBegin();
  187. end_rot = F_PI * params.getTwist();
  188. }
  189. if (!mVO->mDrawable)
  190. {
  191. return;
  192. }
  193. S32 num_sections = 1 << mSimulateRes;
  194. LLVector3 scale;
  195. if (inScale == (LLVector3*)NULL)
  196. {
  197. scale = mVO->mDrawable->getScale();
  198. }
  199. else
  200. {
  201. scale = *inScale;
  202. }
  203. mSection[0].mPosition = getAnchorPosition();
  204. mSection[0].mDirection = LLVector3::z_axis * getFrameRotation();
  205. mSection[0].mdPosition = mSection[0].mDirection;
  206. mSection[0].mScale.setVec(scale.mV[VX]*bottom_scale.mV[0], scale.mV[VY]*bottom_scale.mV[1]);
  207. mSection[0].mVelocity.setVec(0,0,0);
  208. mSection[0].mAxisRotation.setQuat(begin_rot,0,0,1);
  209. LLVector3 parentSectionPosition = mSection[0].mPosition;
  210. LLVector3 last_direction = mSection[0].mDirection;
  211. remapSections(mSection, mInitializedRes, mSection, mSimulateRes);
  212. mInitializedRes = mSimulateRes;
  213. F32 t_inc = 1.f/F32(num_sections);
  214. F32 t = t_inc;
  215. for ( int i=1; i<= num_sections; i++)
  216. {
  217. mSection[i].mAxisRotation.setQuat(lerp(begin_rot,end_rot,t),0,0,1);
  218. mSection[i].mScale = LLVector2(
  219. scale.mV[VX] * lerp(bottom_scale.mV[0], top_scale.mV[0], t),
  220. scale.mV[VY] * lerp(bottom_scale.mV[1], top_scale.mV[1], t));
  221. t += t_inc;
  222. }
  223. }//-----------------------------------------------------------------------------------
  224. void LLVolumeImplFlexible::onSetVolume(const LLVolumeParams &volume_params, const S32 detail)
  225. {
  226. }
  227. //---------------------------------------------------------------------------------
  228. // This calculates the physics of the flexible object. Note that it has to be 0
  229. // updated every time step. In the future, perhaps there could be an
  230. // optimization similar to what Havok does for objects that are stationary.
  231. //---------------------------------------------------------------------------------
  232. static LLFastTimer::DeclareTimer FTM_FLEXIBLE_UPDATE("Update Flexies");
  233. BOOL LLVolumeImplFlexible::doIdleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)
  234. {
  235. if (mVO->mDrawable.isNull())
  236. {
  237. // Don't do anything until we have a drawable
  238. return FALSE; // (we are not initialized or updated)
  239. }
  240. BOOL force_update = mSimulateRes == 0 ? TRUE : FALSE;
  241. //flexible objects never go static
  242. mVO->mDrawable->mQuietCount = 0;
  243. if (!mVO->mDrawable->isRoot())
  244. {
  245. LLViewerObject* parent = (LLViewerObject*) mVO->getParent();
  246. parent->mDrawable->mQuietCount = 0;
  247. }
  248. LLFastTimer ftm(FTM_FLEXIBLE_UPDATE);
  249. S32 new_res = mAttributes->getSimulateLOD();
  250. //number of segments only cares about z axis
  251. F32 app_angle = llround((F32) atan2( mVO->getScale().mV[2]*2.f, mVO->mDrawable->mDistanceWRTCamera) * RAD_TO_DEG, 0.01f);
  252. // Rendering sections increases with visible angle on the screen
  253. mRenderRes = (S32)(FLEXIBLE_OBJECT_MAX_SECTIONS*4*app_angle*DEG_TO_RAD/LLViewerCamera::getInstance()->getView());
  254. if (mRenderRes > FLEXIBLE_OBJECT_MAX_SECTIONS)
  255. {
  256. mRenderRes = FLEXIBLE_OBJECT_MAX_SECTIONS;
  257. }
  258. // Bottom cap at 1/4 the original number of sections
  259. if (mRenderRes < mAttributes->getSimulateLOD()-1)
  260. {
  261. mRenderRes = mAttributes->getSimulateLOD()-1;
  262. }
  263. // Throttle back simulation of segments we're not rendering
  264. if (mRenderRes < new_res)
  265. {
  266. new_res = mRenderRes;
  267. }
  268. if (!mInitialized || (mSimulateRes != new_res))
  269. {
  270. mSimulateRes = new_res;
  271. setAttributesOfAllSections();
  272. mInitialized = TRUE;
  273. }
  274. if (!gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_FLEXIBLE))
  275. {
  276. return FALSE; // (we are not initialized or updated)
  277. }
  278. bool visible = mVO->mDrawable->isVisible();
  279. if (force_update && visible)
  280. {
  281. gPipeline.markRebuild(mVO->mDrawable, LLDrawable::REBUILD_POSITION, FALSE);
  282. }
  283. else if (visible &&
  284. !mVO->mDrawable->isState(LLDrawable::IN_REBUILD_Q1) &&
  285. mVO->getPixelArea() > 256.f)
  286. {
  287. U32 id;
  288. F32 pixel_area = mVO->getPixelArea();
  289. if (mVO->isRootEdit())
  290. {
  291. id = mID;
  292. }
  293. else
  294. {
  295. LLVOVolume* parent = (LLVOVolume*) mVO->getParent();
  296. id = parent->getVolumeInterfaceID();
  297. }
  298. U32 update_period = (U32) (LLViewerCamera::getInstance()->getScreenPixelArea()*0.01f/(pixel_area*(sUpdateFactor+1.f)))+1;
  299. if ((LLDrawable::getCurrentFrame()+id)%update_period == 0)
  300. {
  301. gPipeline.markRebuild(mVO->mDrawable, LLDrawable::REBUILD_POSITION, FALSE);
  302. }
  303. }
  304. return force_update;
  305. }
  306. inline S32 log2(S32 x)
  307. {
  308. S32 ret = 0;
  309. while (x > 1)
  310. {
  311. ++ret;
  312. x >>= 1;
  313. }
  314. return ret;
  315. }
  316. void LLVolumeImplFlexible::doFlexibleUpdate()
  317. {
  318. LLFastTimer ftm(FTM_DO_FLEXIBLE_UPDATE);
  319. LLVolume* volume = mVO->getVolume();
  320. LLPath *path = &volume->getPath();
  321. if ((mSimulateRes == 0 || !mInitialized) && mVO->mDrawable->isVisible())
  322. {
  323. mVO->markForUpdate(TRUE);
  324. if (!doIdleUpdate(gAgent, *LLWorld::getInstance(), 0.0))
  325. {
  326. return; // we did not get updated or initialized, proceeding without can be dangerous
  327. }
  328. }
  329. if(!mInitialized)
  330. {
  331. //the object is not visible
  332. return ;
  333. }
  334. S32 num_sections = 1 << mSimulateRes;
  335. F32 secondsThisFrame = mTimer.getElapsedTimeAndResetF32();
  336. if (secondsThisFrame > 0.2f)
  337. {
  338. secondsThisFrame = 0.2f;
  339. }
  340. LLVector3 BasePosition = getFramePosition();
  341. LLQuaternion BaseRotation = getFrameRotation();
  342. LLQuaternion parentSegmentRotation = BaseRotation;
  343. LLVector3 anchorDirectionRotated = LLVector3::z_axis * parentSegmentRotation;
  344. LLVector3 anchorScale = mVO->mDrawable->getScale();
  345. F32 section_length = anchorScale.mV[VZ] / (F32)num_sections;
  346. F32 inv_section_length = 1.f / section_length;
  347. S32 i;
  348. // ANCHOR position is offset from BASE position (centroid) by half the length
  349. LLVector3 AnchorPosition = BasePosition - (anchorScale.mV[VZ]/2 * anchorDirectionRotated);
  350. mSection[0].mPosition = AnchorPosition;
  351. mSection[0].mDirection = anchorDirectionRotated;
  352. mSection[0].mRotation = BaseRotation;
  353. LLQuaternion deltaRotation;
  354. LLVector3 lastPosition;
  355. // Coefficients which are constant across sections
  356. F32 t_factor = mAttributes->getTension() * 0.1f;
  357. t_factor = t_factor*(1 - pow(0.85f, secondsThisFrame*30));
  358. if ( t_factor > FLEXIBLE_OBJECT_MAX_INTERNAL_TENSION_FORCE )
  359. {
  360. t_factor = FLEXIBLE_OBJECT_MAX_INTERNAL_TENSION_FORCE;
  361. }
  362. F32 friction_coeff = (mAttributes->getAirFriction()*2+1);
  363. friction_coeff = pow(10.f, friction_coeff*secondsThisFrame);
  364. friction_coeff = (friction_coeff > 1) ? friction_coeff : 1;
  365. F32 momentum = 1.0f / friction_coeff;
  366. F32 wind_factor = (mAttributes->getWindSensitivity()*0.1f) * section_length * secondsThisFrame;
  367. F32 max_angle = atan(section_length*2.f);
  368. F32 force_factor = section_length * secondsThisFrame;
  369. // Update simulated sections
  370. for (i=1; i<=num_sections; ++i)
  371. {
  372. LLVector3 parentSectionVector;
  373. LLVector3 parentSectionPosition;
  374. LLVector3 parentDirection;
  375. //---------------------------------------------------
  376. // save value of position as lastPosition
  377. //---------------------------------------------------
  378. lastPosition = mSection[i].mPosition;
  379. //------------------------------------------------------------------------------------------
  380. // gravity
  381. //------------------------------------------------------------------------------------------
  382. mSection[i].mPosition.mV[2] -= mAttributes->getGravity() * force_factor;
  383. //------------------------------------------------------------------------------------------
  384. // wind force
  385. //------------------------------------------------------------------------------------------
  386. if (mAttributes->getWindSensitivity() > 0.001f)
  387. {
  388. mSection[i].mPosition += gAgent.getRegion()->mWind.getVelocity( mSection[i].mPosition ) * wind_factor;
  389. }
  390. //------------------------------------------------------------------------------------------
  391. // user-defined force
  392. //------------------------------------------------------------------------------------------
  393. mSection[i].mPosition += mAttributes->getUserForce() * force_factor;
  394. //---------------------------------------------------
  395. // tension (rigidity, stiffness)
  396. //---------------------------------------------------
  397. parentSectionPosition = mSection[i-1].mPosition;
  398. parentDirection = mSection[i-1].mDirection;
  399. if ( i == 1 )
  400. {
  401. parentSectionVector = mSection[0].mDirection;
  402. }
  403. else
  404. {
  405. parentSectionVector = mSection[i-2].mDirection;
  406. }
  407. LLVector3 currentVector = mSection[i].mPosition - parentSectionPosition;
  408. LLVector3 difference = (parentSectionVector*section_length) - currentVector;
  409. LLVector3 tensionForce = difference * t_factor;
  410. mSection[i].mPosition += tensionForce;
  411. //------------------------------------------------------------------------------------------
  412. // sphere collision, currently not used
  413. //------------------------------------------------------------------------------------------
  414. /*if ( mAttributes->mUsingCollisionSphere )
  415. {
  416. LLVector3 vectorToCenterOfCollisionSphere = mCollisionSpherePosition - mSection[i].mPosition;
  417. if ( vectorToCenterOfCollisionSphere.magVecSquared() < mCollisionSphereRadius * mCollisionSphereRadius )
  418. {
  419. F32 distanceToCenterOfCollisionSphere = vectorToCenterOfCollisionSphere.magVec();
  420. F32 penetration = mCollisionSphereRadius - distanceToCenterOfCollisionSphere;
  421. LLVector3 normalToCenterOfCollisionSphere;
  422. if ( distanceToCenterOfCollisionSphere > 0.0f )
  423. {
  424. normalToCenterOfCollisionSphere = vectorToCenterOfCollisionSphere / distanceToCenterOfCollisionSphere;
  425. }
  426. else // rare
  427. {
  428. normalToCenterOfCollisionSphere = LLVector3::x_axis; // arbitrary
  429. }
  430. // push the position out to the surface of the collision sphere
  431. mSection[i].mPosition -= normalToCenterOfCollisionSphere * penetration;
  432. }
  433. }*/
  434. //------------------------------------------------------------------------------------------
  435. // inertia
  436. //------------------------------------------------------------------------------------------
  437. mSection[i].mPosition += mSection[i].mVelocity * momentum;
  438. //------------------------------------------------------------------------------------------
  439. // clamp length & rotation
  440. //------------------------------------------------------------------------------------------
  441. mSection[i].mDirection = mSection[i].mPosition - parentSectionPosition;
  442. mSection[i].mDirection.normVec();
  443. deltaRotation.shortestArc( parentDirection, mSection[i].mDirection );
  444. F32 angle;
  445. LLVector3 axis;
  446. deltaRotation.getAngleAxis(&angle, axis);
  447. if (angle > F_PI) angle -= 2.f*F_PI;
  448. if (angle < -F_PI) angle += 2.f*F_PI;
  449. if (angle > max_angle)
  450. {
  451. //angle = 0.5f*(angle+max_angle);
  452. deltaRotation.setQuat(max_angle, axis);
  453. } else if (angle < -max_angle)
  454. {
  455. //angle = 0.5f*(angle-max_angle);
  456. deltaRotation.setQuat(-max_angle, axis);
  457. }
  458. LLQuaternion segment_rotation = parentSegmentRotation * deltaRotation;
  459. parentSegmentRotation = segment_rotation;
  460. mSection[i].mDirection = (parentDirection * deltaRotation);
  461. mSection[i].mPosition = parentSectionPosition + mSection[i].mDirection * section_length;
  462. mSection[i].mRotation = segment_rotation;
  463. if (i > 1)
  464. {
  465. // Propogate half the rotation up to the parent
  466. LLQuaternion halfDeltaRotation(angle/2, axis);
  467. mSection[i-1].mRotation = mSection[i-1].mRotation * halfDeltaRotation;
  468. }
  469. //------------------------------------------------------------------------------------------
  470. // calculate velocity
  471. //------------------------------------------------------------------------------------------
  472. mSection[i].mVelocity = mSection[i].mPosition - lastPosition;
  473. if (mSection[i].mVelocity.magVecSquared() > 1.f)
  474. {
  475. mSection[i].mVelocity.normVec();
  476. }
  477. }
  478. // Calculate derivatives (not necessary until normals are automagically generated)
  479. mSection[0].mdPosition = (mSection[1].mPosition - mSection[0].mPosition) * inv_section_length;
  480. // i = 1..NumSections-1
  481. for (i=1; i<num_sections; ++i)
  482. {
  483. // Quadratic numerical derivative of position
  484. // f(-L1) = aL1^2 - bL1 + c = f1
  485. // f(0) = c = f2
  486. // f(L2) = aL2^2 + bL2 + c = f3
  487. // f = ax^2 + bx + c
  488. // d/dx f = 2ax + b
  489. // d/dx f(0) = b
  490. // c = f2
  491. // a = [(f1-c)/L1 + (f3-c)/L2] / (L1+L2)
  492. // b = (f3-c-aL2^2)/L2
  493. LLVector3 a = (mSection[i-1].mPosition-mSection[i].mPosition +
  494. mSection[i+1].mPosition-mSection[i].mPosition) * 0.5f * inv_section_length * inv_section_length;
  495. LLVector3 b = (mSection[i+1].mPosition-mSection[i].mPosition - a*(section_length*section_length));
  496. b *= inv_section_length;
  497. mSection[i].mdPosition = b;
  498. }
  499. // i = NumSections
  500. mSection[i].mdPosition = (mSection[i].mPosition - mSection[i-1].mPosition) * inv_section_length;
  501. // Create points
  502. S32 num_render_sections = 1<<mRenderRes;
  503. if (path->getPathLength() != num_render_sections+1)
  504. {
  505. ((LLVOVolume*) mVO)->mVolumeChanged = TRUE;
  506. volume->resizePath(num_render_sections+1);
  507. }
  508. LLPath::PathPt *new_point;
  509. LLFlexibleObjectSection newSection[ (1<<FLEXIBLE_OBJECT_MAX_SECTIONS)+1 ];
  510. remapSections(mSection, mSimulateRes, newSection, mRenderRes);
  511. //generate transform from global to prim space
  512. LLVector3 delta_scale = LLVector3(1,1,1);
  513. LLVector3 delta_pos;
  514. LLQuaternion delta_rot;
  515. delta_rot = ~getFrameRotation();
  516. delta_pos = -getFramePosition()*delta_rot;
  517. // Vertex transform (4x4)
  518. LLVector3 x_axis = LLVector3(delta_scale.mV[VX], 0.f, 0.f) * delta_rot;
  519. LLVector3 y_axis = LLVector3(0.f, delta_scale.mV[VY], 0.f) * delta_rot;
  520. LLVector3 z_axis = LLVector3(0.f, 0.f, delta_scale.mV[VZ]) * delta_rot;
  521. LLMatrix4 rel_xform;
  522. rel_xform.initRows(LLVector4(x_axis, 0.f),
  523. LLVector4(y_axis, 0.f),
  524. LLVector4(z_axis, 0.f),
  525. LLVector4(delta_pos, 1.f));
  526. for (i=0; i<=num_render_sections; ++i)
  527. {
  528. new_point = &path->mPath[i];
  529. LLVector3 pos = newSection[i].mPosition * rel_xform;
  530. LLQuaternion rot = mSection[i].mAxisRotation * newSection[i].mRotation * delta_rot;
  531. if (!mUpdated || (new_point->mPos-pos).magVec()/mVO->mDrawable->mDistanceWRTCamera > 0.001f)
  532. {
  533. new_point->mPos = newSection[i].mPosition * rel_xform;
  534. mUpdated = FALSE;
  535. }
  536. new_point->mRot = rot;
  537. new_point->mScale = newSection[i].mScale;
  538. new_point->mTexT = ((F32)i)/(num_render_sections);
  539. }
  540. mLastSegmentRotation = parentSegmentRotation;
  541. }
  542. void LLVolumeImplFlexible::preRebuild()
  543. {
  544. if (!mUpdated)
  545. {
  546. doFlexibleRebuild();
  547. }
  548. }
  549. void LLVolumeImplFlexible::doFlexibleRebuild()
  550. {
  551. LLVolume* volume = mVO->getVolume();
  552. volume->regen();
  553. mUpdated = TRUE;
  554. }
  555. //------------------------------------------------------------------
  556. void LLVolumeImplFlexible::onSetScale(const LLVector3& scale, BOOL damped)
  557. {
  558. setAttributesOfAllSections((LLVector3*) &scale);
  559. }
  560. BOOL LLVolumeImplFlexible::doUpdateGeometry(LLDrawable *drawable)
  561. {
  562. LLVOVolume *volume = (LLVOVolume*)mVO;
  563. if (mVO->isAttachment())
  564. { //don't update flexible attachments for impostored avatars unless the
  565. //impostor is being updated this frame (w00!)
  566. LLViewerObject* parent = (LLViewerObject*) mVO->getParent();
  567. while (parent && !parent->isAvatar())
  568. {
  569. parent = (LLViewerObject*) parent->getParent();
  570. }
  571. if (parent)
  572. {
  573. LLVOAvatar* avatar = (LLVOAvatar*) parent;
  574. if (avatar->isImpostor() && !avatar->needsImpostorUpdate())
  575. {
  576. return TRUE;
  577. }
  578. }
  579. }
  580. if (volume->mDrawable.isNull())
  581. {
  582. return TRUE; // No update to complete
  583. }
  584. if (volume->mLODChanged)
  585. {
  586. LLVolumeParams volume_params = volume->getVolume()->getParams();
  587. volume->setVolume(volume_params, 0);
  588. mUpdated = FALSE;
  589. }
  590. volume->updateRelativeXform();
  591. if (mRenderRes > -1)
  592. {
  593. LLFastTimer t(FTM_DO_FLEXIBLE_UPDATE);
  594. doFlexibleUpdate();
  595. }
  596. // Object may have been rotated, which means it needs a rebuild. See SL-47220
  597. BOOL rotated = FALSE;
  598. LLQuaternion cur_rotation = getFrameRotation();
  599. if ( cur_rotation != mLastFrameRotation )
  600. {
  601. mLastFrameRotation = cur_rotation;
  602. rotated = TRUE;
  603. }
  604. if (volume->mLODChanged || volume->mFaceMappingChanged ||
  605. volume->mVolumeChanged || drawable->isState(LLDrawable::REBUILD_MATERIAL))
  606. {
  607. volume->regenFaces();
  608. volume->mDrawable->setState(LLDrawable::REBUILD_VOLUME);
  609. volume->dirtySpatialGroup();
  610. {
  611. LLFastTimer t(FTM_FLEXIBLE_REBUILD);
  612. doFlexibleRebuild();
  613. }
  614. volume->genBBoxes(isVolumeGlobal());
  615. }
  616. else if (!mUpdated || rotated)
  617. {
  618. volume->mDrawable->setState(LLDrawable::REBUILD_POSITION);
  619. volume->dirtyMesh();
  620. volume->genBBoxes(isVolumeGlobal());
  621. }
  622. volume->mVolumeChanged = FALSE;
  623. volume->mLODChanged = FALSE;
  624. volume->mFaceMappingChanged = FALSE;
  625. // clear UV flag
  626. drawable->clearState(LLDrawable::UV);
  627. return TRUE;
  628. }
  629. //----------------------------------------------------------------------------------
  630. void LLVolumeImplFlexible::setCollisionSphere( LLVector3 p, F32 r )
  631. {
  632. mCollisionSpherePosition = p;
  633. mCollisionSphereRadius = r;
  634. }//------------------------------------------------------------------
  635. //----------------------------------------------------------------------------------
  636. void LLVolumeImplFlexible::setUsingCollisionSphere( bool u )
  637. {
  638. }//------------------------------------------------------------------
  639. //----------------------------------------------------------------------------------
  640. void LLVolumeImplFlexible::setRenderingCollisionSphere( bool r )
  641. {
  642. }//------------------------------------------------------------------
  643. //------------------------------------------------------------------
  644. LLVector3 LLVolumeImplFlexible::getEndPosition()
  645. {
  646. S32 num_sections = 1 << mAttributes->getSimulateLOD();
  647. return mSection[ num_sections ].mPosition;
  648. }//------------------------------------------------------------------
  649. //------------------------------------------------------------------
  650. LLVector3 LLVolumeImplFlexible::getNodePosition( int nodeIndex )
  651. {
  652. S32 num_sections = 1 << mAttributes->getSimulateLOD();
  653. if ( nodeIndex > num_sections - 1 )
  654. {
  655. nodeIndex = num_sections - 1;
  656. }
  657. else if ( nodeIndex < 0 )
  658. {
  659. nodeIndex = 0;
  660. }
  661. return mSection[ nodeIndex ].mPosition;
  662. }//------------------------------------------------------------------
  663. LLVector3 LLVolumeImplFlexible::getPivotPosition() const
  664. {
  665. return getAnchorPosition();
  666. }
  667. //------------------------------------------------------------------
  668. LLVector3 LLVolumeImplFlexible::getAnchorPosition() const
  669. {
  670. LLVector3 BasePosition = getFramePosition();
  671. LLQuaternion parentSegmentRotation = getFrameRotation();
  672. LLVector3 anchorDirectionRotated = LLVector3::z_axis * parentSegmentRotation;
  673. LLVector3 anchorScale = mVO->mDrawable->getScale();
  674. return BasePosition - (anchorScale.mV[VZ]/2 * anchorDirectionRotated);
  675. }//------------------------------------------------------------------
  676. //------------------------------------------------------------------
  677. LLQuaternion LLVolumeImplFlexible::getEndRotation()
  678. {
  679. return mLastSegmentRotation;
  680. }//------------------------------------------------------------------
  681. void LLVolumeImplFlexible::updateRelativeXform()
  682. {
  683. LLQuaternion delta_rot;
  684. LLVector3 delta_pos, delta_scale;
  685. LLVOVolume* vo = (LLVOVolume*) mVO;
  686. //matrix from local space to parent relative/global space
  687. delta_rot = vo->mDrawable->isSpatialRoot() ? LLQuaternion() : vo->mDrawable->getRotation();
  688. delta_pos = vo->mDrawable->isSpatialRoot() ? LLVector3(0,0,0) : vo->mDrawable->getPosition();
  689. delta_scale = LLVector3(1,1,1);
  690. // Vertex transform (4x4)
  691. LLVector3 x_axis = LLVector3(delta_scale.mV[VX], 0.f, 0.f) * delta_rot;
  692. LLVector3 y_axis = LLVector3(0.f, delta_scale.mV[VY], 0.f) * delta_rot;
  693. LLVector3 z_axis = LLVector3(0.f, 0.f, delta_scale.mV[VZ]) * delta_rot;
  694. vo->mRelativeXform.initRows(LLVector4(x_axis, 0.f),
  695. LLVector4(y_axis, 0.f),
  696. LLVector4(z_axis, 0.f),
  697. LLVector4(delta_pos, 1.f));
  698. x_axis.normVec();
  699. y_axis.normVec();
  700. z_axis.normVec();
  701. vo->mRelativeXformInvTrans.setRows(x_axis, y_axis, z_axis);
  702. }
  703. const LLMatrix4& LLVolumeImplFlexible::getWorldMatrix(LLXformMatrix* xform) const
  704. {
  705. return xform->getWorldMatrix();
  706. }