llflexibleobject.cpp
上传用户:king477883
上传日期:2021-03-01
资源大小:9553k
文件大小:26k
源码类别:

游戏引擎

开发平台:

C++ Builder

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