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

游戏引擎

开发平台:

C++ Builder

  1. {
  2. const F32 SMOOTHING_HALF_LIFE = 0.02f;
  3. F32 smoothing = LLCriticalDamp::getInterpolant(gSavedSettings.getF32("CameraPositionSmoothing") * SMOOTHING_HALF_LIFE, FALSE);
  4. if (!mFocusObject)  // we differentiate on avatar mode 
  5. {
  6. // for avatar-relative focus, we smooth in avatar space -
  7. // the avatar moves too jerkily w/r/t global space to smooth there.
  8. LLVector3d delta = camera_pos_agent - mCameraSmoothingLastPositionAgent;
  9. if (delta.magVec() < MAX_CAMERA_SMOOTH_DISTANCE)  // only smooth over short distances please
  10. {
  11. camera_pos_agent = lerp(mCameraSmoothingLastPositionAgent, camera_pos_agent, smoothing);
  12. camera_pos_global = camera_pos_agent + agent_pos;
  13. }
  14. }
  15. else
  16. {
  17. LLVector3d delta = camera_pos_global - mCameraSmoothingLastPositionGlobal;
  18. if (delta.magVec() < MAX_CAMERA_SMOOTH_DISTANCE) // only smooth over short distances please
  19. {
  20. camera_pos_global = lerp(mCameraSmoothingLastPositionGlobal, camera_pos_global, smoothing);
  21. }
  22. }
  23. }
  24.  
  25. mCameraSmoothingLastPositionGlobal = camera_pos_global;
  26. mCameraSmoothingLastPositionAgent = camera_pos_agent;
  27. mCameraSmoothingStop = FALSE;
  28. }
  29. mCameraCurrentFOVZoomFactor = lerp(mCameraCurrentFOVZoomFactor, mCameraFOVZoomFactor, LLCriticalDamp::getInterpolant(FOV_ZOOM_HALF_LIFE));
  30. // llinfos << "Current FOV Zoom: " << mCameraCurrentFOVZoomFactor << " Target FOV Zoom: " << mCameraFOVZoomFactor << " Object penetration: " << mFocusObjectDist << llendl;
  31. F32 ui_offset = 0.f;
  32. if( CAMERA_MODE_CUSTOMIZE_AVATAR == mCameraMode ) 
  33. {
  34. ui_offset = calcCustomizeAvatarUIOffset( camera_pos_global );
  35. }
  36. LLVector3 focus_agent = getPosAgentFromGlobal(mFocusGlobal);
  37. mCameraPositionAgent = getPosAgentFromGlobal(camera_pos_global);
  38. // Move the camera
  39. //Ventrella
  40. LLViewerCamera::getInstance()->updateCameraLocation(mCameraPositionAgent, mCameraUpVector, focus_agent);
  41. //LLViewerCamera::getInstance()->updateCameraLocation(mCameraPositionAgent, camera_skyward, focus_agent);
  42. //end Ventrella
  43. //RN: translate UI offset after camera is oriented properly
  44. LLViewerCamera::getInstance()->translate(LLViewerCamera::getInstance()->getLeftAxis() * ui_offset);
  45. // Change FOV
  46. LLViewerCamera::getInstance()->setView(LLViewerCamera::getInstance()->getDefaultFOV() / (1.f + mCameraCurrentFOVZoomFactor));
  47. // follow camera when in customize mode
  48. if (cameraCustomizeAvatar())
  49. {
  50. setLookAt(LOOKAT_TARGET_FOCUS, NULL, mCameraPositionAgent);
  51. }
  52. // update the travel distance stat
  53. // this isn't directly related to the camera
  54. // but this seemed like the best place to do this
  55. LLVector3d global_pos = getPositionGlobal(); 
  56. if (! mLastPositionGlobal.isExactlyZero())
  57. {
  58. LLVector3d delta = global_pos - mLastPositionGlobal;
  59. mDistanceTraveled += delta.magVec();
  60. }
  61. mLastPositionGlobal = global_pos;
  62. if (LLVOAvatar::sVisibleInFirstPerson && mAvatarObject.notNull() && !mAvatarObject->isSitting() && cameraMouselook())
  63. {
  64. LLVector3 head_pos = mAvatarObject->mHeadp->getWorldPosition() + 
  65. LLVector3(0.08f, 0.f, 0.05f) * mAvatarObject->mHeadp->getWorldRotation() + 
  66. LLVector3(0.1f, 0.f, 0.f) * mAvatarObject->mPelvisp->getWorldRotation();
  67. LLVector3 diff = mCameraPositionAgent - head_pos;
  68. diff = diff * ~mAvatarObject->mRoot.getWorldRotation();
  69. LLJoint* torso_joint = mAvatarObject->mTorsop;
  70. LLJoint* chest_joint = mAvatarObject->mChestp;
  71. LLVector3 torso_scale = torso_joint->getScale();
  72. LLVector3 chest_scale = chest_joint->getScale();
  73. // shorten avatar skeleton to avoid foot interpenetration
  74. if (!mAvatarObject->mInAir)
  75. {
  76. LLVector3 chest_offset = LLVector3(0.f, 0.f, chest_joint->getPosition().mV[VZ]) * torso_joint->getWorldRotation();
  77. F32 z_compensate = llclamp(-diff.mV[VZ], -0.2f, 1.f);
  78. F32 scale_factor = llclamp(1.f - ((z_compensate * 0.5f) / chest_offset.mV[VZ]), 0.5f, 1.2f);
  79. torso_joint->setScale(LLVector3(1.f, 1.f, scale_factor));
  80. LLJoint* neck_joint = mAvatarObject->mNeckp;
  81. LLVector3 neck_offset = LLVector3(0.f, 0.f, neck_joint->getPosition().mV[VZ]) * chest_joint->getWorldRotation();
  82. scale_factor = llclamp(1.f - ((z_compensate * 0.5f) / neck_offset.mV[VZ]), 0.5f, 1.2f);
  83. chest_joint->setScale(LLVector3(1.f, 1.f, scale_factor));
  84. diff.mV[VZ] = 0.f;
  85. }
  86. mAvatarObject->mPelvisp->setPosition(mAvatarObject->mPelvisp->getPosition() + diff);
  87. mAvatarObject->mRoot.updateWorldMatrixChildren();
  88. for (LLVOAvatar::attachment_map_t::iterator iter = mAvatarObject->mAttachmentPoints.begin(); 
  89.  iter != mAvatarObject->mAttachmentPoints.end(); )
  90. {
  91. LLVOAvatar::attachment_map_t::iterator curiter = iter++;
  92. LLViewerJointAttachment* attachment = curiter->second;
  93. for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin();
  94.  attachment_iter != attachment->mAttachedObjects.end();
  95.  ++attachment_iter)
  96. {
  97. LLViewerObject *attached_object = (*attachment_iter);
  98. if (attached_object && !attached_object->isDead() && attached_object->mDrawable.notNull())
  99. {
  100. // clear any existing "early" movements of attachment
  101. attached_object->mDrawable->clearState(LLDrawable::EARLY_MOVE);
  102. gPipeline.updateMoveNormalAsync(attached_object->mDrawable);
  103. attached_object->updateText();
  104. }
  105. }
  106. }
  107. torso_joint->setScale(torso_scale);
  108. chest_joint->setScale(chest_scale);
  109. }
  110. }
  111. void LLAgent::updateFocusOffset()
  112. {
  113. validateFocusObject();
  114. if (mFocusObject.notNull())
  115. {
  116. LLVector3d obj_pos = getPosGlobalFromAgent(mFocusObject->getRenderPosition());
  117. mFocusObjectOffset.setVec(mFocusTargetGlobal - obj_pos);
  118. }
  119. }
  120. void LLAgent::validateFocusObject()
  121. {
  122. if (mFocusObject.notNull() && 
  123. (mFocusObject->isDead()))
  124. {
  125. mFocusObjectOffset.clearVec();
  126. clearFocusObject();
  127. mCameraFOVZoomFactor = 0.f;
  128. }
  129. }
  130. //-----------------------------------------------------------------------------
  131. // calcCustomizeAvatarUIOffset()
  132. //-----------------------------------------------------------------------------
  133. F32 LLAgent::calcCustomizeAvatarUIOffset( const LLVector3d& camera_pos_global )
  134. {
  135. F32 ui_offset = 0.f;
  136. if( gFloaterCustomize )
  137. {
  138. const LLRect& rect = gFloaterCustomize->getRect();
  139. // Move the camera so that the avatar isn't covered up by this floater.
  140. F32 fraction_of_fov = 0.5f - (0.5f * (1.f - llmin(1.f, ((F32)rect.getWidth() / (F32)gViewerWindow->getWindowWidthScaled()))));
  141. F32 apparent_angle = fraction_of_fov * LLViewerCamera::getInstance()->getView() * LLViewerCamera::getInstance()->getAspect();  // radians
  142. F32 offset = tan(apparent_angle);
  143. if( rect.mLeft < (gViewerWindow->getWindowWidthScaled() - rect.mRight) )
  144. {
  145. // Move the avatar to the right (camera to the left)
  146. ui_offset = offset;
  147. }
  148. else
  149. {
  150. // Move the avatar to the left (camera to the right)
  151. ui_offset = -offset;
  152. }
  153. }
  154. F32 range = (F32)dist_vec(camera_pos_global, gAgent.getFocusGlobal());
  155. mUIOffset = lerp(mUIOffset, ui_offset, LLCriticalDamp::getInterpolant(0.05f));
  156. return mUIOffset * range;
  157. }
  158. //-----------------------------------------------------------------------------
  159. // calcFocusPositionTargetGlobal()
  160. //-----------------------------------------------------------------------------
  161. LLVector3d LLAgent::calcFocusPositionTargetGlobal()
  162. {
  163. if (mFocusObject.notNull() && mFocusObject->isDead())
  164. {
  165. clearFocusObject();
  166. }
  167. // Ventrella
  168. if ( mCameraMode == CAMERA_MODE_FOLLOW && mFocusOnAvatar )
  169. {
  170. mFocusTargetGlobal = gAgent.getPosGlobalFromAgent(mFollowCam.getSimulatedFocus());
  171. return mFocusTargetGlobal;
  172. }// End Ventrella 
  173. else if (mCameraMode == CAMERA_MODE_MOUSELOOK)
  174. {
  175. LLVector3d at_axis(1.0, 0.0, 0.0);
  176. LLQuaternion agent_rot = mFrameAgent.getQuaternion();
  177. if (mAvatarObject.notNull() && mAvatarObject->getParent())
  178. {
  179. LLViewerObject* root_object = (LLViewerObject*)mAvatarObject->getRoot();
  180. if (!root_object->flagCameraDecoupled())
  181. {
  182. agent_rot *= ((LLViewerObject*)(mAvatarObject->getParent()))->getRenderRotation();
  183. }
  184. }
  185. at_axis = at_axis * agent_rot;
  186. mFocusTargetGlobal = calcCameraPositionTargetGlobal() + at_axis;
  187. return mFocusTargetGlobal;
  188. }
  189. else if (mCameraMode == CAMERA_MODE_CUSTOMIZE_AVATAR)
  190. {
  191. return mFocusTargetGlobal;
  192. }
  193. else if (!mFocusOnAvatar)
  194. {
  195. if (mFocusObject.notNull() && !mFocusObject->isDead() && mFocusObject->mDrawable.notNull())
  196. {
  197. LLDrawable* drawablep = mFocusObject->mDrawable;
  198. if (mTrackFocusObject &&
  199. drawablep && 
  200. drawablep->isActive())
  201. {
  202. if (!mFocusObject->isAvatar())
  203. {
  204. if (mFocusObject->isSelected())
  205. {
  206. gPipeline.updateMoveNormalAsync(drawablep);
  207. }
  208. else
  209. {
  210. if (drawablep->isState(LLDrawable::MOVE_UNDAMPED))
  211. {
  212. gPipeline.updateMoveNormalAsync(drawablep);
  213. }
  214. else
  215. {
  216. gPipeline.updateMoveDampedAsync(drawablep);
  217. }
  218. }
  219. }
  220. }
  221. // if not tracking object, update offset based on new object position
  222. else
  223. {
  224. updateFocusOffset();
  225. }
  226. LLVector3 focus_agent = mFocusObject->getRenderPosition() + mFocusObjectOffset;
  227. mFocusTargetGlobal.setVec(getPosGlobalFromAgent(focus_agent));
  228. }
  229. return mFocusTargetGlobal;
  230. }
  231. else if (mSitCameraEnabled && mAvatarObject.notNull() && mAvatarObject->isSitting() && mSitCameraReferenceObject.notNull())
  232. {
  233. // sit camera
  234. LLVector3 object_pos = mSitCameraReferenceObject->getRenderPosition();
  235. LLQuaternion object_rot = mSitCameraReferenceObject->getRenderRotation();
  236. LLVector3 target_pos = object_pos + (mSitCameraFocus * object_rot);
  237. return getPosGlobalFromAgent(target_pos);
  238. }
  239. else
  240. {
  241. return getPositionGlobal() + calcThirdPersonFocusOffset();
  242. }
  243. }
  244. LLVector3d LLAgent::calcThirdPersonFocusOffset()
  245. {
  246. // ...offset from avatar
  247. LLVector3d focus_offset;
  248. LLQuaternion agent_rot = mFrameAgent.getQuaternion();
  249. if (!mAvatarObject.isNull() && mAvatarObject->getParent())
  250. {
  251. agent_rot *= ((LLViewerObject*)(mAvatarObject->getParent()))->getRenderRotation();
  252. }
  253. focus_offset = mFocusOffsetInitial[mCameraPreset] * agent_rot;
  254. return focus_offset;
  255. }
  256. void LLAgent::setupSitCamera()
  257. {
  258. // agent frame entering this function is in world coordinates
  259. if (mAvatarObject.notNull() && mAvatarObject->getParent())
  260. {
  261. LLQuaternion parent_rot = ((LLViewerObject*)mAvatarObject->getParent())->getRenderRotation();
  262. // slam agent coordinate frame to proper parent local version
  263. LLVector3 at_axis = mFrameAgent.getAtAxis();
  264. at_axis.mV[VZ] = 0.f;
  265. at_axis.normalize();
  266. resetAxes(at_axis * ~parent_rot);
  267. }
  268. }
  269. //-----------------------------------------------------------------------------
  270. // getCameraPositionAgent()
  271. //-----------------------------------------------------------------------------
  272. const LLVector3 &LLAgent::getCameraPositionAgent() const
  273. {
  274. return LLViewerCamera::getInstance()->getOrigin();
  275. }
  276. //-----------------------------------------------------------------------------
  277. // getCameraPositionGlobal()
  278. //-----------------------------------------------------------------------------
  279. LLVector3d LLAgent::getCameraPositionGlobal() const
  280. {
  281. return getPosGlobalFromAgent(LLViewerCamera::getInstance()->getOrigin());
  282. }
  283. //-----------------------------------------------------------------------------
  284. // calcCameraFOVZoomFactor()
  285. //-----------------------------------------------------------------------------
  286. F32 LLAgent::calcCameraFOVZoomFactor()
  287. {
  288. LLVector3 camera_offset_dir;
  289. camera_offset_dir.setVec(mCameraFocusOffset);
  290. if (mCameraMode == CAMERA_MODE_MOUSELOOK)
  291. {
  292. return 0.f;
  293. }
  294. else if (mFocusObject.notNull() && !mFocusObject->isAvatar() && !mFocusOnAvatar)
  295. {
  296. // don't FOV zoom on mostly transparent objects
  297. LLVector3 focus_offset = mFocusObjectOffset;
  298. F32 obj_min_dist = 0.f;
  299. calcCameraMinDistance(obj_min_dist);
  300. F32 current_distance = llmax(0.001f, camera_offset_dir.magVec());
  301. mFocusObjectDist = obj_min_dist - current_distance;
  302. F32 new_fov_zoom = llclamp(mFocusObjectDist / current_distance, 0.f, 1000.f);
  303. return new_fov_zoom;
  304. }
  305. else // focusing on land or avatar
  306. {
  307. // keep old field of view until user changes focus explicitly
  308. return mCameraFOVZoomFactor;
  309. //return 0.f;
  310. }
  311. }
  312. //-----------------------------------------------------------------------------
  313. // calcCameraPositionTargetGlobal()
  314. //-----------------------------------------------------------------------------
  315. LLVector3d LLAgent::calcCameraPositionTargetGlobal(BOOL *hit_limit)
  316. {
  317. // Compute base camera position and look-at points.
  318. F32 camera_land_height;
  319. LLVector3d frame_center_global = mAvatarObject.isNull() ? getPositionGlobal() 
  320.  : getPosGlobalFromAgent(mAvatarObject->mRoot.getWorldPosition());
  321. BOOL isConstrained = FALSE;
  322. LLVector3d head_offset;
  323. head_offset.setVec(mThirdPersonHeadOffset);
  324. LLVector3d camera_position_global;
  325. // Ventrella 
  326. if ( mCameraMode == CAMERA_MODE_FOLLOW && mFocusOnAvatar )
  327. {
  328. camera_position_global = gAgent.getPosGlobalFromAgent(mFollowCam.getSimulatedPosition());
  329. }// End Ventrella
  330. else if (mCameraMode == CAMERA_MODE_MOUSELOOK)
  331. {
  332. if (mAvatarObject.isNull() || mAvatarObject->mDrawable.isNull())
  333. {
  334. llwarns << "Null avatar drawable!" << llendl;
  335. return LLVector3d::zero;
  336. }
  337. head_offset.clearVec();
  338. if (mAvatarObject->isSitting() && mAvatarObject->getParent())
  339. {
  340. mAvatarObject->updateHeadOffset();
  341. head_offset.mdV[VX] = mAvatarObject->mHeadOffset.mV[VX];
  342. head_offset.mdV[VY] = mAvatarObject->mHeadOffset.mV[VY];
  343. head_offset.mdV[VZ] = mAvatarObject->mHeadOffset.mV[VZ] + 0.1f;
  344. const LLMatrix4& mat = ((LLViewerObject*) mAvatarObject->getParent())->getRenderMatrix();
  345. camera_position_global = getPosGlobalFromAgent
  346. ((mAvatarObject->getPosition()+
  347.  LLVector3(head_offset)*mAvatarObject->getRotation()) * mat);
  348. }
  349. else
  350. {
  351. head_offset.mdV[VZ] = mAvatarObject->mHeadOffset.mV[VZ];
  352. if (mAvatarObject->isSitting())
  353. {
  354. head_offset.mdV[VZ] += 0.1;
  355. }
  356. camera_position_global = getPosGlobalFromAgent(mAvatarObject->getRenderPosition());//frame_center_global;
  357. head_offset = head_offset * mAvatarObject->getRenderRotation();
  358. camera_position_global = camera_position_global + head_offset;
  359. }
  360. }
  361. else if (mCameraMode == CAMERA_MODE_THIRD_PERSON && mFocusOnAvatar)
  362. {
  363. LLVector3 local_camera_offset;
  364. F32 camera_distance = 0.f;
  365. if (mSitCameraEnabled 
  366. && mAvatarObject.notNull() 
  367. && mAvatarObject->isSitting() 
  368. && mSitCameraReferenceObject.notNull())
  369. {
  370. // sit camera
  371. LLVector3 object_pos = mSitCameraReferenceObject->getRenderPosition();
  372. LLQuaternion object_rot = mSitCameraReferenceObject->getRenderRotation();
  373. LLVector3 target_pos = object_pos + (mSitCameraPos * object_rot);
  374. camera_position_global = getPosGlobalFromAgent(target_pos);
  375. }
  376. else
  377. {
  378. local_camera_offset = mCameraZoomFraction * getCameraOffsetInitial() * gSavedSettings.getF32("CameraOffsetScale");
  379. // are we sitting down?
  380. if (mAvatarObject.notNull() && mAvatarObject->getParent())
  381. {
  382. LLQuaternion parent_rot = ((LLViewerObject*)mAvatarObject->getParent())->getRenderRotation();
  383. // slam agent coordinate frame to proper parent local version
  384. LLVector3 at_axis = mFrameAgent.getAtAxis() * parent_rot;
  385. at_axis.mV[VZ] = 0.f;
  386. at_axis.normalize();
  387. resetAxes(at_axis * ~parent_rot);
  388. local_camera_offset = local_camera_offset * mFrameAgent.getQuaternion() * parent_rot;
  389. }
  390. else
  391. {
  392. local_camera_offset = mFrameAgent.rotateToAbsolute( local_camera_offset );
  393. }
  394. if (!mCameraCollidePlane.isExactlyZero() && (mAvatarObject.isNull() || !mAvatarObject->isSitting()))
  395. {
  396. LLVector3 plane_normal;
  397. plane_normal.setVec(mCameraCollidePlane.mV);
  398. F32 offset_dot_norm = local_camera_offset * plane_normal;
  399. if (llabs(offset_dot_norm) < 0.001f)
  400. {
  401. offset_dot_norm = 0.001f;
  402. }
  403. camera_distance = local_camera_offset.normalize();
  404. F32 pos_dot_norm = getPosAgentFromGlobal(frame_center_global + head_offset) * plane_normal;
  405. // if agent is outside the colliding half-plane
  406. if (pos_dot_norm > mCameraCollidePlane.mV[VW])
  407. {
  408. // check to see if camera is on the opposite side (inside) the half-plane
  409. if (offset_dot_norm + pos_dot_norm < mCameraCollidePlane.mV[VW])
  410. {
  411. // diminish offset by factor to push it back outside the half-plane
  412. camera_distance *= (pos_dot_norm - mCameraCollidePlane.mV[VW] - CAMERA_COLLIDE_EPSILON) / -offset_dot_norm;
  413. }
  414. }
  415. else
  416. {
  417. if (offset_dot_norm + pos_dot_norm > mCameraCollidePlane.mV[VW])
  418. {
  419. camera_distance *= (mCameraCollidePlane.mV[VW] - pos_dot_norm - CAMERA_COLLIDE_EPSILON) / offset_dot_norm;
  420. }
  421. }
  422. }
  423. else
  424. {
  425. camera_distance = local_camera_offset.normalize();
  426. }
  427. mTargetCameraDistance = llmax(camera_distance, MIN_CAMERA_DISTANCE);
  428. if (mTargetCameraDistance != mCurrentCameraDistance)
  429. {
  430. F32 camera_lerp_amt = LLCriticalDamp::getInterpolant(CAMERA_ZOOM_HALF_LIFE);
  431. mCurrentCameraDistance = lerp(mCurrentCameraDistance, mTargetCameraDistance, camera_lerp_amt);
  432. }
  433. // Make the camera distance current
  434. local_camera_offset *= mCurrentCameraDistance;
  435. // set the global camera position
  436. LLVector3d camera_offset;
  437. LLVector3 av_pos = mAvatarObject.isNull() ? LLVector3::zero : mAvatarObject->getRenderPosition();
  438. camera_offset.setVec( local_camera_offset );
  439. camera_position_global = frame_center_global + head_offset + camera_offset;
  440. if (mAvatarObject.notNull())
  441. {
  442. LLVector3d camera_lag_d;
  443. F32 lag_interp = LLCriticalDamp::getInterpolant(CAMERA_LAG_HALF_LIFE);
  444. LLVector3 target_lag;
  445. LLVector3 vel = getVelocity();
  446. // lag by appropriate amount for flying
  447. F32 time_in_air = mAvatarObject->mTimeInAir.getElapsedTimeF32();
  448. if(!mCameraAnimating && mAvatarObject->mInAir && time_in_air > GROUND_TO_AIR_CAMERA_TRANSITION_START_TIME)
  449. {
  450. LLVector3 frame_at_axis = mFrameAgent.getAtAxis();
  451. frame_at_axis -= projected_vec(frame_at_axis, getReferenceUpVector());
  452. frame_at_axis.normalize();
  453. //transition smoothly in air mode, to avoid camera pop
  454. F32 u = (time_in_air - GROUND_TO_AIR_CAMERA_TRANSITION_START_TIME) / GROUND_TO_AIR_CAMERA_TRANSITION_TIME;
  455. u = llclamp(u, 0.f, 1.f);
  456. lag_interp *= u;
  457. if (gViewerWindow->getLeftMouseDown() && gViewerWindow->getLastPick().mObjectID == mAvatarObject->getID())
  458. {
  459. // disable camera lag when using mouse-directed steering
  460. target_lag.clearVec();
  461. }
  462. else
  463. {
  464. target_lag = vel * gSavedSettings.getF32("DynamicCameraStrength") / 30.f;
  465. }
  466. mCameraLag = lerp(mCameraLag, target_lag, lag_interp);
  467. F32 lag_dist = mCameraLag.magVec();
  468. if (lag_dist > MAX_CAMERA_LAG)
  469. {
  470. mCameraLag = mCameraLag * MAX_CAMERA_LAG / lag_dist;
  471. }
  472. // clamp camera lag so that avatar is always in front
  473. F32 dot = (mCameraLag - (frame_at_axis * (MIN_CAMERA_LAG * u))) * frame_at_axis;
  474. if (dot < -(MIN_CAMERA_LAG * u))
  475. {
  476. mCameraLag -= (dot + (MIN_CAMERA_LAG * u)) * frame_at_axis;
  477. }
  478. }
  479. else
  480. {
  481. mCameraLag = lerp(mCameraLag, LLVector3::zero, LLCriticalDamp::getInterpolant(0.15f));
  482. }
  483. camera_lag_d.setVec(mCameraLag);
  484. camera_position_global = camera_position_global - camera_lag_d;
  485. }
  486. }
  487. }
  488. else
  489. {
  490. LLVector3d focusPosGlobal = calcFocusPositionTargetGlobal();
  491. // camera gets pushed out later wrt mCameraFOVZoomFactor...this is "raw" value
  492. camera_position_global = focusPosGlobal + mCameraFocusOffset;
  493. }
  494. if (!gSavedSettings.getBOOL("DisableCameraConstraints") && !gAgent.isGodlike())
  495. {
  496. LLViewerRegion* regionp = LLWorld::getInstance()->getRegionFromPosGlobal(
  497. camera_position_global);
  498. bool constrain = true;
  499. if(regionp && regionp->canManageEstate())
  500. {
  501. constrain = false;
  502. }
  503. if(constrain)
  504. {
  505. F32 max_dist = ( CAMERA_MODE_CUSTOMIZE_AVATAR == mCameraMode ) ?
  506. APPEARANCE_MAX_ZOOM : mDrawDistance;
  507. LLVector3d camera_offset = camera_position_global
  508. - gAgent.getPositionGlobal();
  509. F32 camera_distance = (F32)camera_offset.magVec();
  510. if(camera_distance > max_dist)
  511. {
  512. camera_position_global = gAgent.getPositionGlobal() + 
  513. (max_dist / camera_distance) * camera_offset;
  514. isConstrained = TRUE;
  515. }
  516. }
  517. // JC - Could constrain camera based on parcel stuff here.
  518. // LLViewerRegion *regionp = LLWorld::getInstance()->getRegionFromPosGlobal(camera_position_global);
  519. //
  520. // if (regionp && !regionp->mParcelOverlay->isBuildCameraAllowed(regionp->getPosRegionFromGlobal(camera_position_global)))
  521. // {
  522. // camera_position_global = last_position_global;
  523. //
  524. // isConstrained = TRUE;
  525. // }
  526. }
  527. // Don't let camera go underground
  528. F32 camera_min_off_ground = getCameraMinOffGround();
  529. camera_land_height = LLWorld::getInstance()->resolveLandHeightGlobal(camera_position_global);
  530. if (camera_position_global.mdV[VZ] < camera_land_height + camera_min_off_ground)
  531. {
  532. camera_position_global.mdV[VZ] = camera_land_height + camera_min_off_ground;
  533. isConstrained = TRUE;
  534. }
  535. if (hit_limit)
  536. {
  537. *hit_limit = isConstrained;
  538. }
  539. return camera_position_global;
  540. }
  541. LLVector3 LLAgent::getCameraOffsetInitial()
  542. {
  543. return mCameraOffsetInitial[mCameraPreset];
  544. }
  545. //-----------------------------------------------------------------------------
  546. // handleScrollWheel()
  547. //-----------------------------------------------------------------------------
  548. void LLAgent::handleScrollWheel(S32 clicks)
  549. {
  550. if ( mCameraMode == CAMERA_MODE_FOLLOW && gAgent.getFocusOnAvatar())
  551. {
  552. if ( ! mFollowCam.getPositionLocked() ) // not if the followCam position is locked in place
  553. {
  554. mFollowCam.zoom( clicks ); 
  555. if ( mFollowCam.isZoomedToMinimumDistance() )
  556. {
  557. changeCameraToMouselook(FALSE);
  558. }
  559. }
  560. }
  561. else
  562. {
  563. LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection();
  564. const F32 ROOT_ROOT_TWO = sqrt(F_SQRT2);
  565. // Block if camera is animating
  566. if (mCameraAnimating)
  567. {
  568. return;
  569. }
  570. if (selection->getObjectCount() && selection->getSelectType() == SELECT_TYPE_HUD)
  571. {
  572. F32 zoom_factor = (F32)pow(0.8, -clicks);
  573. cameraZoomIn(zoom_factor);
  574. }
  575. else if (mFocusOnAvatar && mCameraMode == CAMERA_MODE_THIRD_PERSON)
  576. {
  577. F32 camera_offset_initial_mag = getCameraOffsetInitial().magVec();
  578. F32 current_zoom_fraction = mTargetCameraDistance / (camera_offset_initial_mag * gSavedSettings.getF32("CameraOffsetScale"));
  579. current_zoom_fraction *= 1.f - pow(ROOT_ROOT_TWO, clicks);
  580. cameraOrbitIn(current_zoom_fraction * camera_offset_initial_mag * gSavedSettings.getF32("CameraOffsetScale"));
  581. }
  582. else
  583. {
  584. F32 current_zoom_fraction = (F32)mCameraFocusOffsetTarget.magVec();
  585. cameraOrbitIn(current_zoom_fraction * (1.f - pow(ROOT_ROOT_TWO, clicks)));
  586. }
  587. }
  588. }
  589. //-----------------------------------------------------------------------------
  590. // getCameraMinOffGround()
  591. //-----------------------------------------------------------------------------
  592. F32 LLAgent::getCameraMinOffGround()
  593. {
  594. if (mCameraMode == CAMERA_MODE_MOUSELOOK)
  595. {
  596. return 0.f;
  597. }
  598. else
  599. {
  600. if (gSavedSettings.getBOOL("DisableCameraConstraints"))
  601. {
  602. return -1000.f;
  603. }
  604. else
  605. {
  606. return 0.5f;
  607. }
  608. }
  609. }
  610. //-----------------------------------------------------------------------------
  611. // resetCamera()
  612. //-----------------------------------------------------------------------------
  613. void LLAgent::resetCamera()
  614. {
  615. // Remove any pitch from the avatar
  616. LLVector3 at = mFrameAgent.getAtAxis();
  617. at.mV[VZ] = 0.f;
  618. at.normalize();
  619. gAgent.resetAxes(at);
  620. // have to explicitly clear field of view zoom now
  621. mCameraFOVZoomFactor = 0.f;
  622. updateCamera();
  623. }
  624. //-----------------------------------------------------------------------------
  625. // changeCameraToMouselook()
  626. //-----------------------------------------------------------------------------
  627. void LLAgent::changeCameraToMouselook(BOOL animate)
  628. {
  629. if (LLViewerJoystick::getInstance()->getOverrideCamera())
  630. {
  631. return;
  632. }
  633. // visibility changes at end of animation
  634. gViewerWindow->getWindow()->resetBusyCount();
  635. // unpause avatar animation
  636. mPauseRequest = NULL;
  637. LLToolMgr::getInstance()->setCurrentToolset(gMouselookToolset);
  638. if (mAvatarObject.notNull())
  639. {
  640. mAvatarObject->stopMotion( ANIM_AGENT_BODY_NOISE );
  641. mAvatarObject->stopMotion( ANIM_AGENT_BREATHE_ROT );
  642. }
  643. //gViewerWindow->stopGrab();
  644. LLSelectMgr::getInstance()->deselectAll();
  645. gViewerWindow->hideCursor();
  646. gViewerWindow->moveCursorToCenter();
  647. if( mCameraMode != CAMERA_MODE_MOUSELOOK )
  648. {
  649. gFocusMgr.setKeyboardFocus( NULL );
  650. mLastCameraMode = mCameraMode;
  651. mCameraMode = CAMERA_MODE_MOUSELOOK;
  652. U32 old_flags = mControlFlags;
  653. setControlFlags(AGENT_CONTROL_MOUSELOOK);
  654. if (old_flags != mControlFlags)
  655. {
  656. mbFlagsDirty = TRUE;
  657. }
  658. if (animate)
  659. {
  660. startCameraAnimation();
  661. }
  662. else
  663. {
  664. mCameraAnimating = FALSE;
  665. endAnimationUpdateUI();
  666. }
  667. }
  668. }
  669. //-----------------------------------------------------------------------------
  670. // changeCameraToDefault()
  671. //-----------------------------------------------------------------------------
  672. void LLAgent::changeCameraToDefault()
  673. {
  674. if (LLViewerJoystick::getInstance()->getOverrideCamera())
  675. {
  676. return;
  677. }
  678. if (LLFollowCamMgr::getActiveFollowCamParams())
  679. {
  680. changeCameraToFollow();
  681. }
  682. else
  683. {
  684. changeCameraToThirdPerson();
  685. }
  686. }
  687. // Ventrella
  688. //-----------------------------------------------------------------------------
  689. // changeCameraToFollow()
  690. //-----------------------------------------------------------------------------
  691. void LLAgent::changeCameraToFollow(BOOL animate)
  692. {
  693. if (LLViewerJoystick::getInstance()->getOverrideCamera())
  694. {
  695. return;
  696. }
  697. if( mCameraMode != CAMERA_MODE_FOLLOW )
  698. {
  699. if (mCameraMode == CAMERA_MODE_MOUSELOOK)
  700. {
  701. animate = FALSE;
  702. }
  703. startCameraAnimation();
  704. mLastCameraMode = mCameraMode;
  705. mCameraMode = CAMERA_MODE_FOLLOW;
  706. // bang-in the current focus, position, and up vector of the follow cam
  707. mFollowCam.reset( mCameraPositionAgent, LLViewerCamera::getInstance()->getPointOfInterest(), LLVector3::z_axis );
  708. if (gBasicToolset)
  709. {
  710. LLToolMgr::getInstance()->setCurrentToolset(gBasicToolset);
  711. }
  712. if (mAvatarObject.notNull())
  713. {
  714. mAvatarObject->mPelvisp->setPosition(LLVector3::zero);
  715. mAvatarObject->startMotion( ANIM_AGENT_BODY_NOISE );
  716. mAvatarObject->startMotion( ANIM_AGENT_BREATHE_ROT );
  717. }
  718. // unpause avatar animation
  719. mPauseRequest = NULL;
  720. U32 old_flags = mControlFlags;
  721. clearControlFlags(AGENT_CONTROL_MOUSELOOK);
  722. if (old_flags != mControlFlags)
  723. {
  724. mbFlagsDirty = TRUE;
  725. }
  726. if (animate)
  727. {
  728. startCameraAnimation();
  729. }
  730. else
  731. {
  732. mCameraAnimating = FALSE;
  733. endAnimationUpdateUI();
  734. }
  735. }
  736. }
  737. //-----------------------------------------------------------------------------
  738. // changeCameraToThirdPerson()
  739. //-----------------------------------------------------------------------------
  740. void LLAgent::changeCameraToThirdPerson(BOOL animate)
  741. {
  742. if (LLViewerJoystick::getInstance()->getOverrideCamera())
  743. {
  744. return;
  745. }
  746. gViewerWindow->getWindow()->resetBusyCount();
  747. mCameraZoomFraction = INITIAL_ZOOM_FRACTION;
  748. if (mAvatarObject.notNull())
  749. {
  750. if (!mAvatarObject->isSitting())
  751. {
  752. mAvatarObject->mPelvisp->setPosition(LLVector3::zero);
  753. }
  754. mAvatarObject->startMotion( ANIM_AGENT_BODY_NOISE );
  755. mAvatarObject->startMotion( ANIM_AGENT_BREATHE_ROT );
  756. }
  757. LLVector3 at_axis;
  758. // unpause avatar animation
  759. mPauseRequest = NULL;
  760. if( mCameraMode != CAMERA_MODE_THIRD_PERSON )
  761. {
  762. if (gBasicToolset)
  763. {
  764. LLToolMgr::getInstance()->setCurrentToolset(gBasicToolset);
  765. }
  766. mCameraLag.clearVec();
  767. if (mCameraMode == CAMERA_MODE_MOUSELOOK)
  768. {
  769. mCurrentCameraDistance = MIN_CAMERA_DISTANCE;
  770. mTargetCameraDistance = MIN_CAMERA_DISTANCE;
  771. animate = FALSE;
  772. }
  773. mLastCameraMode = mCameraMode;
  774. mCameraMode = CAMERA_MODE_THIRD_PERSON;
  775. U32 old_flags = mControlFlags;
  776. clearControlFlags(AGENT_CONTROL_MOUSELOOK);
  777. if (old_flags != mControlFlags)
  778. {
  779. mbFlagsDirty = TRUE;
  780. }
  781. }
  782. // Remove any pitch from the avatar
  783. if (mAvatarObject.notNull() && mAvatarObject->getParent())
  784. {
  785. LLQuaternion obj_rot = ((LLViewerObject*)mAvatarObject->getParent())->getRenderRotation();
  786. at_axis = LLViewerCamera::getInstance()->getAtAxis();
  787. at_axis.mV[VZ] = 0.f;
  788. at_axis.normalize();
  789. resetAxes(at_axis * ~obj_rot);
  790. }
  791. else
  792. {
  793. at_axis = mFrameAgent.getAtAxis();
  794. at_axis.mV[VZ] = 0.f;
  795. at_axis.normalize();
  796. resetAxes(at_axis);
  797. }
  798. if (animate)
  799. {
  800. startCameraAnimation();
  801. }
  802. else
  803. {
  804. mCameraAnimating = FALSE;
  805. endAnimationUpdateUI();
  806. }
  807. }
  808. //-----------------------------------------------------------------------------
  809. // changeCameraToCustomizeAvatar()
  810. //-----------------------------------------------------------------------------
  811. void LLAgent::changeCameraToCustomizeAvatar(BOOL avatar_animate, BOOL camera_animate)
  812. {
  813. if (LLViewerJoystick::getInstance()->getOverrideCamera())
  814. {
  815. return;
  816. }
  817. standUp(); // force stand up
  818. gViewerWindow->getWindow()->resetBusyCount();
  819. if (gFaceEditToolset)
  820. {
  821. LLToolMgr::getInstance()->setCurrentToolset(gFaceEditToolset);
  822. }
  823. if (camera_animate)
  824. {
  825. startCameraAnimation();
  826. }
  827. // Remove any pitch from the avatar
  828. //LLVector3 at = mFrameAgent.getAtAxis();
  829. //at.mV[VZ] = 0.f;
  830. //at.normalize();
  831. //gAgent.resetAxes(at);
  832. if( mCameraMode != CAMERA_MODE_CUSTOMIZE_AVATAR )
  833. {
  834. mLastCameraMode = mCameraMode;
  835. mCameraMode = CAMERA_MODE_CUSTOMIZE_AVATAR;
  836. U32 old_flags = mControlFlags;
  837. clearControlFlags(AGENT_CONTROL_MOUSELOOK);
  838. if (old_flags != mControlFlags)
  839. {
  840. mbFlagsDirty = TRUE;
  841. }
  842. gFocusMgr.setKeyboardFocus( NULL );
  843. gFocusMgr.setMouseCapture( NULL );
  844. LLVOAvatarSelf::onCustomizeStart();
  845. }
  846. if (mAvatarObject.notNull())
  847. {
  848. if(avatar_animate)
  849. {
  850. // Remove any pitch from the avatar
  851. LLVector3 at = mFrameAgent.getAtAxis();
  852. at.mV[VZ] = 0.f;
  853. at.normalize();
  854. gAgent.resetAxes(at);
  855. sendAnimationRequest(ANIM_AGENT_CUSTOMIZE, ANIM_REQUEST_START);
  856. mCustomAnim = TRUE ;
  857. mAvatarObject->startMotion(ANIM_AGENT_CUSTOMIZE);
  858. LLMotion* turn_motion = mAvatarObject->findMotion(ANIM_AGENT_CUSTOMIZE);
  859. if (turn_motion)
  860. {
  861. mAnimationDuration = turn_motion->getDuration() + CUSTOMIZE_AVATAR_CAMERA_ANIM_SLOP;
  862. }
  863. else
  864. {
  865. mAnimationDuration = gSavedSettings.getF32("ZoomTime");
  866. }
  867. }
  868. gAgent.setFocusGlobal(LLVector3d::zero);
  869. }
  870. else
  871. {
  872. mCameraAnimating = FALSE;
  873. endAnimationUpdateUI();
  874. }
  875. }
  876. void LLAgent::switchCameraPreset(ECameraPreset preset)
  877. {
  878. //zoom is supposed to be reset for the front and group views
  879. mCameraZoomFraction = 1.f;
  880. //focusing on avatar in that case means following him on movements
  881. mFocusOnAvatar = TRUE;
  882. mCameraPreset = preset;
  883. gSavedSettings.setU32("CameraPreset", mCameraPreset);
  884. }
  885. //
  886. // Focus point management
  887. //
  888. //-----------------------------------------------------------------------------
  889. // startCameraAnimation()
  890. //-----------------------------------------------------------------------------
  891. void LLAgent::startCameraAnimation()
  892. {
  893. mAnimationCameraStartGlobal = getCameraPositionGlobal();
  894. mAnimationFocusStartGlobal = mFocusGlobal;
  895. mAnimationTimer.reset();
  896. mCameraAnimating = TRUE;
  897. mAnimationDuration = gSavedSettings.getF32("ZoomTime");
  898. }
  899. //-----------------------------------------------------------------------------
  900. // stopCameraAnimation()
  901. //-----------------------------------------------------------------------------
  902. void LLAgent::stopCameraAnimation()
  903. {
  904. mCameraAnimating = FALSE;
  905. }
  906. void LLAgent::clearFocusObject()
  907. {
  908. if (mFocusObject.notNull())
  909. {
  910. startCameraAnimation();
  911. setFocusObject(NULL);
  912. mFocusObjectOffset.clearVec();
  913. }
  914. }
  915. void LLAgent::setFocusObject(LLViewerObject* object)
  916. {
  917. mFocusObject = object;
  918. }
  919. // Focus on a point, but try to keep camera position stable.
  920. //-----------------------------------------------------------------------------
  921. // setFocusGlobal()
  922. //-----------------------------------------------------------------------------
  923. void LLAgent::setFocusGlobal(const LLPickInfo& pick)
  924. {
  925. LLViewerObject* objectp = gObjectList.findObject(pick.mObjectID);
  926. if (objectp)
  927. {
  928. // focus on object plus designated offset
  929. // which may or may not be same as pick.mPosGlobal
  930. setFocusGlobal(objectp->getPositionGlobal() + LLVector3d(pick.mObjectOffset), pick.mObjectID);
  931. }
  932. else
  933. {
  934. // focus directly on point where user clicked
  935. setFocusGlobal(pick.mPosGlobal, pick.mObjectID);
  936. }
  937. }
  938. void LLAgent::setFocusGlobal(const LLVector3d& focus, const LLUUID &object_id)
  939. {
  940. setFocusObject(gObjectList.findObject(object_id));
  941. LLVector3d old_focus = mFocusTargetGlobal;
  942. LLViewerObject *focus_obj = mFocusObject;
  943. // if focus has changed
  944. if (old_focus != focus)
  945. {
  946. if (focus.isExactlyZero())
  947. {
  948. if (mAvatarObject.notNull())
  949. {
  950. mFocusTargetGlobal = getPosGlobalFromAgent(mAvatarObject->mHeadp->getWorldPosition());
  951. }
  952. else
  953. {
  954. mFocusTargetGlobal = getPositionGlobal();
  955. }
  956. mCameraFocusOffsetTarget = getCameraPositionGlobal() - mFocusTargetGlobal;
  957. mCameraFocusOffset = mCameraFocusOffsetTarget;
  958. setLookAt(LOOKAT_TARGET_CLEAR);
  959. }
  960. else
  961. {
  962. mFocusTargetGlobal = focus;
  963. if (!focus_obj)
  964. {
  965. mCameraFOVZoomFactor = 0.f;
  966. }
  967. mCameraFocusOffsetTarget = gAgent.getPosGlobalFromAgent(mCameraVirtualPositionAgent) - mFocusTargetGlobal;
  968. startCameraAnimation();
  969. if (focus_obj)
  970. {
  971. if (focus_obj->isAvatar())
  972. {
  973. setLookAt(LOOKAT_TARGET_FOCUS, focus_obj);
  974. }
  975. else
  976. {
  977. setLookAt(LOOKAT_TARGET_FOCUS, focus_obj, (getPosAgentFromGlobal(focus) - focus_obj->getRenderPosition()) * ~focus_obj->getRenderRotation());
  978. }
  979. }
  980. else
  981. {
  982. setLookAt(LOOKAT_TARGET_FOCUS, NULL, getPosAgentFromGlobal(mFocusTargetGlobal));
  983. }
  984. }
  985. }
  986. else // focus == mFocusTargetGlobal
  987. {
  988. if (focus.isExactlyZero())
  989. {
  990. if (mAvatarObject.notNull())
  991. {
  992. mFocusTargetGlobal = getPosGlobalFromAgent(mAvatarObject->mHeadp->getWorldPosition());
  993. }
  994. else
  995. {
  996. mFocusTargetGlobal = getPositionGlobal();
  997. }
  998. }
  999. mCameraFocusOffsetTarget = (getCameraPositionGlobal() - mFocusTargetGlobal) / (1.f + mCameraFOVZoomFactor);;
  1000. mCameraFocusOffset = mCameraFocusOffsetTarget;
  1001. }
  1002. if (mFocusObject.notNull())
  1003. {
  1004. // for attachments, make offset relative to avatar, not the attachment
  1005. if (mFocusObject->isAttachment())
  1006. {
  1007. while (mFocusObject.notNull() // DEV-29123 - can crash with a messed-up attachment
  1008. && !mFocusObject->isAvatar())
  1009. {
  1010. mFocusObject = (LLViewerObject*) mFocusObject->getParent();
  1011. }
  1012. setFocusObject((LLViewerObject*)mFocusObject);
  1013. }
  1014. updateFocusOffset();
  1015. }
  1016. }
  1017. // Used for avatar customization
  1018. //-----------------------------------------------------------------------------
  1019. // setCameraPosAndFocusGlobal()
  1020. //-----------------------------------------------------------------------------
  1021. void LLAgent::setCameraPosAndFocusGlobal(const LLVector3d& camera_pos, const LLVector3d& focus, const LLUUID &object_id)
  1022. {
  1023. LLVector3d old_focus = mFocusTargetGlobal;
  1024. F64 focus_delta_squared = (old_focus - focus).magVecSquared();
  1025. const F64 ANIM_EPSILON_SQUARED = 0.0001;
  1026. if( focus_delta_squared > ANIM_EPSILON_SQUARED )
  1027. {
  1028. startCameraAnimation();
  1029. if( CAMERA_MODE_CUSTOMIZE_AVATAR == mCameraMode ) 
  1030. {
  1031. // Compensate for the fact that the camera has already been offset to make room for LLFloaterCustomize.
  1032. mAnimationCameraStartGlobal -= LLVector3d(LLViewerCamera::getInstance()->getLeftAxis() * calcCustomizeAvatarUIOffset( mAnimationCameraStartGlobal ));
  1033. }
  1034. }
  1035. //LLViewerCamera::getInstance()->setOrigin( gAgent.getPosAgentFromGlobal( camera_pos ) );
  1036. setFocusObject(gObjectList.findObject(object_id));
  1037. mFocusTargetGlobal = focus;
  1038. mCameraFocusOffsetTarget = camera_pos - focus;
  1039. mCameraFocusOffset = mCameraFocusOffsetTarget;
  1040. if (mFocusObject)
  1041. {
  1042. if (mFocusObject->isAvatar())
  1043. {
  1044. setLookAt(LOOKAT_TARGET_FOCUS, mFocusObject);
  1045. }
  1046. else
  1047. {
  1048. setLookAt(LOOKAT_TARGET_FOCUS, mFocusObject, (getPosAgentFromGlobal(focus) - mFocusObject->getRenderPosition()) * ~mFocusObject->getRenderRotation());
  1049. }
  1050. }
  1051. else
  1052. {
  1053. setLookAt(LOOKAT_TARGET_FOCUS, NULL, getPosAgentFromGlobal(mFocusTargetGlobal));
  1054. }
  1055. if( mCameraAnimating )
  1056. {
  1057. const F64 ANIM_METERS_PER_SECOND = 10.0;
  1058. const F64 MIN_ANIM_SECONDS = 0.5;
  1059. const F64 MAX_ANIM_SECONDS = 10.0;
  1060. F64 anim_duration = llmax( MIN_ANIM_SECONDS, sqrt(focus_delta_squared) / ANIM_METERS_PER_SECOND );
  1061. anim_duration = llmin( anim_duration, MAX_ANIM_SECONDS );
  1062. setAnimationDuration( (F32)anim_duration );
  1063. }
  1064. updateFocusOffset();
  1065. }
  1066. //-----------------------------------------------------------------------------
  1067. // setSitCamera()
  1068. //-----------------------------------------------------------------------------
  1069. void LLAgent::setSitCamera(const LLUUID &object_id, const LLVector3 &camera_pos, const LLVector3 &camera_focus)
  1070. {
  1071. BOOL camera_enabled = !object_id.isNull();
  1072. if (camera_enabled)
  1073. {
  1074. LLViewerObject *reference_object = gObjectList.findObject(object_id);
  1075. if (reference_object)
  1076. {
  1077. //convert to root object relative?
  1078. mSitCameraPos = camera_pos;
  1079. mSitCameraFocus = camera_focus;
  1080. mSitCameraReferenceObject = reference_object;
  1081. mSitCameraEnabled = TRUE;
  1082. }
  1083. }
  1084. else
  1085. {
  1086. mSitCameraPos.clearVec();
  1087. mSitCameraFocus.clearVec();
  1088. mSitCameraReferenceObject = NULL;
  1089. mSitCameraEnabled = FALSE;
  1090. }
  1091. }
  1092. //-----------------------------------------------------------------------------
  1093. // setFocusOnAvatar()
  1094. //-----------------------------------------------------------------------------
  1095. void LLAgent::setFocusOnAvatar(BOOL focus_on_avatar, BOOL animate)
  1096. {
  1097. if (focus_on_avatar != mFocusOnAvatar)
  1098. {
  1099. if (animate)
  1100. {
  1101. startCameraAnimation();
  1102. }
  1103. else
  1104. {
  1105. stopCameraAnimation();
  1106. }
  1107. }
  1108. //RN: when focused on the avatar, we're not "looking" at it
  1109. // looking implies intent while focusing on avatar means
  1110. // you're just walking around with a camera on you...eesh.
  1111. if (!mFocusOnAvatar && focus_on_avatar)
  1112. {
  1113. setFocusGlobal(LLVector3d::zero);
  1114. mCameraFOVZoomFactor = 0.f;
  1115. if (mCameraMode == CAMERA_MODE_THIRD_PERSON)
  1116. {
  1117. LLVector3 at_axis;
  1118. if (mAvatarObject.notNull() && mAvatarObject->getParent())
  1119. {
  1120. LLQuaternion obj_rot = ((LLViewerObject*)mAvatarObject->getParent())->getRenderRotation();
  1121. at_axis = LLViewerCamera::getInstance()->getAtAxis();
  1122. at_axis.mV[VZ] = 0.f;
  1123. at_axis.normalize();
  1124. resetAxes(at_axis * ~obj_rot);
  1125. }
  1126. else
  1127. {
  1128. at_axis = LLViewerCamera::getInstance()->getAtAxis();
  1129. at_axis.mV[VZ] = 0.f;
  1130. at_axis.normalize();
  1131. resetAxes(at_axis);
  1132. }
  1133. }
  1134. }
  1135. // unlocking camera from avatar
  1136. else if (mFocusOnAvatar && !focus_on_avatar)
  1137. {
  1138. // keep camera focus point consistent, even though it is now unlocked
  1139. setFocusGlobal(getPositionGlobal() + calcThirdPersonFocusOffset(), gAgent.getID());
  1140. }
  1141. mFocusOnAvatar = focus_on_avatar;
  1142. }
  1143. //-----------------------------------------------------------------------------
  1144. // heardChat()
  1145. //-----------------------------------------------------------------------------
  1146. void LLAgent::heardChat(const LLUUID& id)
  1147. {
  1148. // log text and voice chat to speaker mgr
  1149. // for keeping track of active speakers, etc.
  1150. LLLocalSpeakerMgr::getInstance()->speakerChatted(id);
  1151. // don't respond to your own voice
  1152. if (id == getID()) return;
  1153. if (ll_rand(2) == 0) 
  1154. {
  1155. LLViewerObject *chatter = gObjectList.findObject(mLastChatterID);
  1156. setLookAt(LOOKAT_TARGET_AUTO_LISTEN, chatter, LLVector3::zero);
  1157. }
  1158. mLastChatterID = id;
  1159. mChatTimer.reset();
  1160. }
  1161. //-----------------------------------------------------------------------------
  1162. // lookAtLastChat()
  1163. //-----------------------------------------------------------------------------
  1164. void LLAgent::lookAtLastChat()
  1165. {
  1166. // Block if camera is animating or not in normal third person camera mode
  1167. if (mCameraAnimating || !cameraThirdPerson())
  1168. {
  1169. return;
  1170. }
  1171. LLViewerObject *chatter = gObjectList.findObject(mLastChatterID);
  1172. if (chatter)
  1173. {
  1174. LLVector3 delta_pos;
  1175. if (chatter->isAvatar())
  1176. {
  1177. LLVOAvatar *chatter_av = (LLVOAvatar*)chatter;
  1178. if (mAvatarObject.notNull() && chatter_av->mHeadp)
  1179. {
  1180. delta_pos = chatter_av->mHeadp->getWorldPosition() - mAvatarObject->mHeadp->getWorldPosition();
  1181. }
  1182. else
  1183. {
  1184. delta_pos = chatter->getPositionAgent() - getPositionAgent();
  1185. }
  1186. delta_pos.normalize();
  1187. setControlFlags(AGENT_CONTROL_STOP);
  1188. changeCameraToThirdPerson();
  1189. LLVector3 new_camera_pos = mAvatarObject->mHeadp->getWorldPosition();
  1190. LLVector3 left = delta_pos % LLVector3::z_axis;
  1191. left.normalize();
  1192. LLVector3 up = left % delta_pos;
  1193. up.normalize();
  1194. new_camera_pos -= delta_pos * 0.4f;
  1195. new_camera_pos += left * 0.3f;
  1196. new_camera_pos += up * 0.2f;
  1197. if (chatter_av->mHeadp)
  1198. {
  1199. setFocusGlobal(getPosGlobalFromAgent(chatter_av->mHeadp->getWorldPosition()), mLastChatterID);
  1200. mCameraFocusOffsetTarget = getPosGlobalFromAgent(new_camera_pos) - gAgent.getPosGlobalFromAgent(chatter_av->mHeadp->getWorldPosition());
  1201. }
  1202. else
  1203. {
  1204. setFocusGlobal(chatter->getPositionGlobal(), mLastChatterID);
  1205. mCameraFocusOffsetTarget = getPosGlobalFromAgent(new_camera_pos) - chatter->getPositionGlobal();
  1206. }
  1207. setFocusOnAvatar(FALSE, TRUE);
  1208. }
  1209. else
  1210. {
  1211. delta_pos = chatter->getRenderPosition() - getPositionAgent();
  1212. delta_pos.normalize();
  1213. setControlFlags(AGENT_CONTROL_STOP);
  1214. changeCameraToThirdPerson();
  1215. LLVector3 new_camera_pos = mAvatarObject->mHeadp->getWorldPosition();
  1216. LLVector3 left = delta_pos % LLVector3::z_axis;
  1217. left.normalize();
  1218. LLVector3 up = left % delta_pos;
  1219. up.normalize();
  1220. new_camera_pos -= delta_pos * 0.4f;
  1221. new_camera_pos += left * 0.3f;
  1222. new_camera_pos += up * 0.2f;
  1223. setFocusGlobal(chatter->getPositionGlobal(), mLastChatterID);
  1224. mCameraFocusOffsetTarget = getPosGlobalFromAgent(new_camera_pos) - chatter->getPositionGlobal();
  1225. setFocusOnAvatar(FALSE, TRUE);
  1226. }
  1227. }
  1228. }
  1229. const F32 SIT_POINT_EXTENTS = 0.2f;
  1230. LLSD ll_sdmap_from_vector3(const LLVector3& vec)
  1231. {
  1232.     LLSD ret;
  1233.     ret["X"] = vec.mV[VX];
  1234.     ret["Y"] = vec.mV[VY];
  1235.     ret["Z"] = vec.mV[VZ];
  1236.     return ret;
  1237. }
  1238. LLVector3 ll_vector3_from_sdmap(const LLSD& sd)
  1239. {
  1240.     LLVector3 ret;
  1241.     ret.mV[VX] = F32(sd["X"].asReal());
  1242.     ret.mV[VY] = F32(sd["Y"].asReal());
  1243.     ret.mV[VZ] = F32(sd["Z"].asReal());
  1244.     return ret;
  1245. }
  1246. void LLAgent::setStartPosition( U32 location_id )
  1247. {
  1248.     LLViewerObject          *object;
  1249.     if (gAgentID == LLUUID::null)
  1250.     {
  1251.         return;
  1252.     }
  1253.     // we've got an ID for an agent viewerobject
  1254.     object = gObjectList.findObject(gAgentID);
  1255.     if (! object)
  1256.     {
  1257.         llinfos << "setStartPosition - Can't find agent viewerobject id " << gAgentID << llendl;
  1258.         return;
  1259.     }
  1260.     // we've got the viewer object
  1261.     // Sometimes the agent can be velocity interpolated off of
  1262.     // this simulator.  Clamp it to the region the agent is
  1263.     // in, a little bit in on each side.
  1264.     const F32 INSET = 0.5f; //meters
  1265.     const F32 REGION_WIDTH = LLWorld::getInstance()->getRegionWidthInMeters();
  1266.     LLVector3 agent_pos = getPositionAgent();
  1267.     if (mAvatarObject.notNull())
  1268.     {
  1269.         // the z height is at the agent's feet
  1270.         agent_pos.mV[VZ] -= 0.5f * mAvatarObject->mBodySize.mV[VZ];
  1271.     }
  1272.     agent_pos.mV[VX] = llclamp( agent_pos.mV[VX], INSET, REGION_WIDTH - INSET );
  1273.     agent_pos.mV[VY] = llclamp( agent_pos.mV[VY], INSET, REGION_WIDTH - INSET );
  1274.     // Don't let them go below ground, or too high.
  1275.     agent_pos.mV[VZ] = llclamp( agent_pos.mV[VZ],
  1276.                                 mRegionp->getLandHeightRegion( agent_pos ),
  1277.                                 LLWorld::getInstance()->getRegionMaxHeight() );
  1278.     // Send the CapReq
  1279.     LLSD request;
  1280.     LLSD body;
  1281.     LLSD homeLocation;
  1282.     homeLocation["LocationId"] = LLSD::Integer(location_id);
  1283.     homeLocation["LocationPos"] = ll_sdmap_from_vector3(agent_pos);
  1284.     homeLocation["LocationLookAt"] = ll_sdmap_from_vector3(mFrameAgent.getAtAxis());
  1285.     body["HomeLocation"] = homeLocation;
  1286.     // This awkward idiom warrants explanation.
  1287.     // For starters, LLSDMessage::ResponderAdapter is ONLY for testing the new
  1288.     // LLSDMessage functionality with a pre-existing LLHTTPClient::Responder.
  1289.     // In new code, define your reply/error methods on the same class as the
  1290.     // sending method, bind them to local LLEventPump objects and pass those
  1291.     // LLEventPump names in the request LLSD object.
  1292.     // When testing old code, the new LLHomeLocationResponder object
  1293.     // is referenced by an LLHTTPClient::ResponderPtr, so when the
  1294.     // ResponderAdapter is deleted, the LLHomeLocationResponder will be too.
  1295.     // We must trust that the underlying LLHTTPClient code will eventually
  1296.     // fire either the reply callback or the error callback; either will cause
  1297.     // the ResponderAdapter to delete itself.
  1298.     LLSDMessage::ResponderAdapter*
  1299.         adapter(new LLSDMessage::ResponderAdapter(new LLHomeLocationResponder()));
  1300.     request["message"] = "HomeLocation";
  1301.     request["payload"] = body;
  1302.     request["reply"]   = adapter->getReplyName();
  1303.     request["error"]   = adapter->getErrorName();
  1304.     gAgent.getRegion()->getCapAPI().post(request);
  1305.     const U32 HOME_INDEX = 1;
  1306.     if( HOME_INDEX == location_id )
  1307.     {
  1308.         setHomePosRegion( mRegionp->getHandle(), getPositionAgent() );
  1309.     }
  1310. }
  1311. struct HomeLocationMapper: public LLCapabilityListener::CapabilityMapper
  1312. {
  1313.     // No reply message expected
  1314.     HomeLocationMapper(): LLCapabilityListener::CapabilityMapper("HomeLocation") {}
  1315.     virtual void buildMessage(LLMessageSystem* msg,
  1316.                               const LLUUID& agentID,
  1317.                               const LLUUID& sessionID,
  1318.                               const std::string& capabilityName,
  1319.                               const LLSD& payload) const
  1320.     {
  1321.         msg->newMessageFast(_PREHASH_SetStartLocationRequest);
  1322.         msg->nextBlockFast( _PREHASH_AgentData);
  1323.         msg->addUUIDFast(_PREHASH_AgentID, agentID);
  1324.         msg->addUUIDFast(_PREHASH_SessionID, sessionID);
  1325.         msg->nextBlockFast( _PREHASH_StartLocationData);
  1326.         // corrected by sim
  1327.         msg->addStringFast(_PREHASH_SimName, "");
  1328.         msg->addU32Fast(_PREHASH_LocationID, payload["HomeLocation"]["LocationId"].asInteger());
  1329.         msg->addVector3Fast(_PREHASH_LocationPos,
  1330.                             ll_vector3_from_sdmap(payload["HomeLocation"]["LocationPos"]));
  1331.         msg->addVector3Fast(_PREHASH_LocationLookAt,
  1332.                             ll_vector3_from_sdmap(payload["HomeLocation"]["LocationLookAt"]));
  1333.     }
  1334. };
  1335. // Need an instance of this class so it will self-register
  1336. static HomeLocationMapper homeLocationMapper;
  1337. void LLAgent::requestStopMotion( LLMotion* motion )
  1338. {
  1339. // Notify all avatars that a motion has stopped.
  1340. // This is needed to clear the animation state bits
  1341. LLUUID anim_state = motion->getID();
  1342. onAnimStop(motion->getID());
  1343. // if motion is not looping, it could have stopped by running out of time
  1344. // so we need to tell the server this
  1345. // llinfos << "Sending stop for motion " << motion->getName() << llendl;
  1346. sendAnimationRequest( anim_state, ANIM_REQUEST_STOP );
  1347. }
  1348. void LLAgent::onAnimStop(const LLUUID& id)
  1349. {
  1350. // handle automatic state transitions (based on completion of animation playback)
  1351. if (id == ANIM_AGENT_STAND)
  1352. {
  1353. stopFidget();
  1354. }
  1355. else if (id == ANIM_AGENT_AWAY)
  1356. {
  1357. clearAFK();
  1358. }
  1359. else if (id == ANIM_AGENT_STANDUP)
  1360. {
  1361. // send stand up command
  1362. setControlFlags(AGENT_CONTROL_FINISH_ANIM);
  1363. // now trigger dusting self off animation
  1364. if (mAvatarObject.notNull() && !mAvatarObject->mBelowWater && rand() % 3 == 0)
  1365. sendAnimationRequest( ANIM_AGENT_BRUSH, ANIM_REQUEST_START );
  1366. }
  1367. else if (id == ANIM_AGENT_PRE_JUMP || id == ANIM_AGENT_LAND || id == ANIM_AGENT_MEDIUM_LAND)
  1368. {
  1369. setControlFlags(AGENT_CONTROL_FINISH_ANIM);
  1370. }
  1371. }
  1372. BOOL LLAgent::isGodlike() const
  1373. {
  1374. return mAgentAccess.isGodlike();
  1375. }
  1376. U8 LLAgent::getGodLevel() const
  1377. {
  1378. return mAgentAccess.getGodLevel();
  1379. }
  1380. bool LLAgent::wantsPGOnly() const
  1381. {
  1382. return mAgentAccess.wantsPGOnly();
  1383. }
  1384. bool LLAgent::canAccessMature() const
  1385. {
  1386. return mAgentAccess.canAccessMature();
  1387. }
  1388. bool LLAgent::canAccessAdult() const
  1389. {
  1390. return mAgentAccess.canAccessAdult();
  1391. }
  1392. bool LLAgent::canAccessMaturityInRegion( U64 region_handle ) const
  1393. {
  1394. LLViewerRegion *regionp = LLWorld::getInstance()->getRegionFromHandle( region_handle );
  1395. if( regionp )
  1396. {
  1397. switch( regionp->getSimAccess() )
  1398. {
  1399. case SIM_ACCESS_MATURE:
  1400. if( !canAccessMature() )
  1401. return false;
  1402. break;
  1403. case SIM_ACCESS_ADULT:
  1404. if( !canAccessAdult() )
  1405. return false;
  1406. break;
  1407. default:
  1408. // Oh, go on and hear the silly noises.
  1409. break;
  1410. }
  1411. }
  1412. return true;
  1413. }
  1414. bool LLAgent::canAccessMaturityAtGlobal( LLVector3d pos_global ) const
  1415. {
  1416. U64 region_handle = to_region_handle_global( pos_global.mdV[0], pos_global.mdV[1] );
  1417. return canAccessMaturityInRegion( region_handle );
  1418. }
  1419. bool LLAgent::prefersPG() const
  1420. {
  1421. return mAgentAccess.prefersPG();
  1422. }
  1423. bool LLAgent::prefersMature() const
  1424. {
  1425. return mAgentAccess.prefersMature();
  1426. }
  1427. bool LLAgent::prefersAdult() const
  1428. {
  1429. return mAgentAccess.prefersAdult();
  1430. }
  1431. bool LLAgent::isTeen() const
  1432. {
  1433. return mAgentAccess.isTeen();
  1434. }
  1435. bool LLAgent::isMature() const
  1436. {
  1437. return mAgentAccess.isMature();
  1438. }
  1439. bool LLAgent::isAdult() const
  1440. {
  1441. return mAgentAccess.isAdult();
  1442. }
  1443. void LLAgent::setTeen(bool teen)
  1444. {
  1445. mAgentAccess.setTeen(teen);
  1446. }
  1447. //static 
  1448. int LLAgent::convertTextToMaturity(char text)
  1449. {
  1450. return LLAgentAccess::convertTextToMaturity(text);
  1451. }
  1452. bool LLAgent::sendMaturityPreferenceToServer(int preferredMaturity)
  1453. {
  1454. if (!getRegion())
  1455. return false;
  1456. // Update agent access preference on the server
  1457. std::string url = getRegion()->getCapability("UpdateAgentInformation");
  1458. if (!url.empty())
  1459. {
  1460. // Set new access preference
  1461. LLSD access_prefs = LLSD::emptyMap();
  1462. if (preferredMaturity == SIM_ACCESS_PG)
  1463. {
  1464. access_prefs["max"] = "PG";
  1465. }
  1466. else if (preferredMaturity == SIM_ACCESS_MATURE)
  1467. {
  1468. access_prefs["max"] = "M";
  1469. }
  1470. if (preferredMaturity == SIM_ACCESS_ADULT)
  1471. {
  1472. access_prefs["max"] = "A";
  1473. }
  1474. LLSD body = LLSD::emptyMap();
  1475. body["access_prefs"] = access_prefs;
  1476. llinfos << "Sending access prefs update to " << (access_prefs["max"].asString()) << " via capability to: "
  1477. << url << llendl;
  1478. LLHTTPClient::post(url, body, new LLHTTPClient::Responder());    // Ignore response
  1479. return true;
  1480. }
  1481. return false;
  1482. }
  1483. BOOL LLAgent::getAdminOverride() const
  1484. return mAgentAccess.getAdminOverride(); 
  1485. }
  1486. void LLAgent::setMaturity(char text)
  1487. {
  1488. mAgentAccess.setMaturity(text);
  1489. }
  1490. void LLAgent::setAdminOverride(BOOL b)
  1491. mAgentAccess.setAdminOverride(b);
  1492. }
  1493. void LLAgent::setGodLevel(U8 god_level)
  1494. mAgentAccess.setGodLevel(god_level);
  1495. }
  1496. void LLAgent::setAOTransition()
  1497. {
  1498. mAgentAccess.setTransition();
  1499. }
  1500. const LLAgentAccess& LLAgent::getAgentAccess()
  1501. {
  1502. return mAgentAccess;
  1503. }
  1504. bool LLAgent::validateMaturity(const LLSD& newvalue)
  1505. {
  1506. return mAgentAccess.canSetMaturity(newvalue.asInteger());
  1507. }
  1508. void LLAgent::handleMaturity(const LLSD& newvalue)
  1509. {
  1510. sendMaturityPreferenceToServer(newvalue.asInteger());
  1511. }
  1512. //----------------------------------------------------------------------------
  1513. //*TODO remove, is not used anywhere as of August 20, 2009
  1514. void LLAgent::buildFullnameAndTitle(std::string& name) const
  1515. {
  1516. if (isGroupMember())
  1517. {
  1518. name = mGroupTitle;
  1519. name += ' ';
  1520. }
  1521. else
  1522. {
  1523. name.erase(0, name.length());
  1524. }
  1525. if (mAvatarObject.notNull())
  1526. {
  1527. name += mAvatarObject->getFullname();
  1528. }
  1529. }
  1530. BOOL LLAgent::isInGroup(const LLUUID& group_id, BOOL ignore_god_mode /* FALSE */) const
  1531. {
  1532. if (!ignore_god_mode && isGodlike())
  1533. return true;
  1534. S32 count = mGroups.count();
  1535. for(S32 i = 0; i < count; ++i)
  1536. {
  1537. if(mGroups.get(i).mID == group_id)
  1538. {
  1539. return TRUE;
  1540. }
  1541. }
  1542. return FALSE;
  1543. }
  1544. // This implementation should mirror LLAgentInfo::hasPowerInGroup
  1545. BOOL LLAgent::hasPowerInGroup(const LLUUID& group_id, U64 power) const
  1546. {
  1547. if (isGodlike())
  1548. return true;
  1549. // GP_NO_POWERS can also mean no power is enough to grant an ability.
  1550. if (GP_NO_POWERS == power) return FALSE;
  1551. S32 count = mGroups.count();
  1552. for(S32 i = 0; i < count; ++i)
  1553. {
  1554. if(mGroups.get(i).mID == group_id)
  1555. {
  1556. return (BOOL)((mGroups.get(i).mPowers & power) > 0);
  1557. }
  1558. }
  1559. return FALSE;
  1560. }
  1561. BOOL LLAgent::hasPowerInActiveGroup(U64 power) const
  1562. {
  1563. return (mGroupID.notNull() && (hasPowerInGroup(mGroupID, power)));
  1564. }
  1565. U64 LLAgent::getPowerInGroup(const LLUUID& group_id) const
  1566. {
  1567. if (isGodlike())
  1568. return GP_ALL_POWERS;
  1569. S32 count = mGroups.count();
  1570. for(S32 i = 0; i < count; ++i)
  1571. {
  1572. if(mGroups.get(i).mID == group_id)
  1573. {
  1574. return (mGroups.get(i).mPowers);
  1575. }
  1576. }
  1577. return GP_NO_POWERS;
  1578. }
  1579. BOOL LLAgent::getGroupData(const LLUUID& group_id, LLGroupData& data) const
  1580. {
  1581. S32 count = mGroups.count();
  1582. for(S32 i = 0; i < count; ++i)
  1583. {
  1584. if(mGroups.get(i).mID == group_id)
  1585. {
  1586. data = mGroups.get(i);
  1587. return TRUE;
  1588. }
  1589. }
  1590. return FALSE;
  1591. }
  1592. S32 LLAgent::getGroupContribution(const LLUUID& group_id) const
  1593. {
  1594. S32 count = mGroups.count();
  1595. for(S32 i = 0; i < count; ++i)
  1596. {
  1597. if(mGroups.get(i).mID == group_id)
  1598. {
  1599. S32 contribution = mGroups.get(i).mContribution;
  1600. return contribution;
  1601. }
  1602. }
  1603. return 0;
  1604. }
  1605. BOOL LLAgent::setGroupContribution(const LLUUID& group_id, S32 contribution)
  1606. {
  1607. S32 count = mGroups.count();
  1608. for(S32 i = 0; i < count; ++i)
  1609. {
  1610. if(mGroups.get(i).mID == group_id)
  1611. {
  1612. mGroups.get(i).mContribution = contribution;
  1613. LLMessageSystem* msg = gMessageSystem;
  1614. msg->newMessage("SetGroupContribution");
  1615. msg->nextBlock("AgentData");
  1616. msg->addUUID("AgentID", gAgentID);
  1617. msg->addUUID("SessionID", gAgentSessionID);
  1618. msg->nextBlock("Data");
  1619. msg->addUUID("GroupID", group_id);
  1620. msg->addS32("Contribution", contribution);
  1621. sendReliableMessage();
  1622. return TRUE;
  1623. }
  1624. }
  1625. return FALSE;
  1626. }
  1627. BOOL LLAgent::setUserGroupFlags(const LLUUID& group_id, BOOL accept_notices, BOOL list_in_profile)
  1628. {
  1629. S32 count = mGroups.count();
  1630. for(S32 i = 0; i < count; ++i)
  1631. {
  1632. if(mGroups.get(i).mID == group_id)
  1633. {
  1634. mGroups.get(i).mAcceptNotices = accept_notices;
  1635. mGroups.get(i).mListInProfile = list_in_profile;
  1636. LLMessageSystem* msg = gMessageSystem;
  1637. msg->newMessage("SetGroupAcceptNotices");
  1638. msg->nextBlock("AgentData");
  1639. msg->addUUID("AgentID", gAgentID);
  1640. msg->addUUID("SessionID", gAgentSessionID);
  1641. msg->nextBlock("Data");
  1642. msg->addUUID("GroupID", group_id);
  1643. msg->addBOOL("AcceptNotices", accept_notices);
  1644. msg->nextBlock("NewData");
  1645. msg->addBOOL("ListInProfile", list_in_profile);
  1646. sendReliableMessage();
  1647. return TRUE;
  1648. }
  1649. }
  1650. return FALSE;
  1651. }
  1652. BOOL LLAgent::canJoinGroups() const
  1653. {
  1654. return mGroups.count() < MAX_AGENT_GROUPS;
  1655. }
  1656. LLQuaternion LLAgent::getHeadRotation()
  1657. {
  1658. if (mAvatarObject.isNull() || !mAvatarObject->mPelvisp || !mAvatarObject->mHeadp)
  1659. {
  1660. return LLQuaternion::DEFAULT;
  1661. }
  1662. if (!gAgent.cameraMouselook())
  1663. {
  1664. return mAvatarObject->getRotation();
  1665. }
  1666. // We must be in mouselook
  1667. LLVector3 look_dir( LLViewerCamera::getInstance()->getAtAxis() );
  1668. LLVector3 up = look_dir % mFrameAgent.getLeftAxis();
  1669. LLVector3 left = up % look_dir;
  1670. LLQuaternion rot(look_dir, left, up);
  1671. if (mAvatarObject->getParent())
  1672. {
  1673. rot = rot * ~mAvatarObject->getParent()->getRotation();
  1674. }
  1675. return rot;
  1676. }
  1677. void LLAgent::sendAnimationRequests(LLDynamicArray<LLUUID> &anim_ids, EAnimRequest request)
  1678. {
  1679. if (gAgentID.isNull())
  1680. {
  1681. return;
  1682. }
  1683. S32 num_valid_anims = 0;
  1684. LLMessageSystem* msg = gMessageSystem;
  1685. msg->newMessageFast(_PREHASH_AgentAnimation);
  1686. msg->nextBlockFast(_PREHASH_AgentData);
  1687. msg->addUUIDFast(_PREHASH_AgentID, getID());
  1688. msg->addUUIDFast(_PREHASH_SessionID, getSessionID());
  1689. for (S32 i = 0; i < anim_ids.count(); i++)
  1690. {
  1691. if (anim_ids[i].isNull())
  1692. {
  1693. continue;
  1694. }
  1695. msg->nextBlockFast(_PREHASH_AnimationList);
  1696. msg->addUUIDFast(_PREHASH_AnimID, (anim_ids[i]) );
  1697. msg->addBOOLFast(_PREHASH_StartAnim, (request == ANIM_REQUEST_START) ? TRUE : FALSE);
  1698. num_valid_anims++;
  1699. }
  1700. msg->nextBlockFast(_PREHASH_PhysicalAvatarEventList);
  1701. msg->addBinaryDataFast(_PREHASH_TypeData, NULL, 0);
  1702. if (num_valid_anims)
  1703. {
  1704. sendReliableMessage();
  1705. }
  1706. }
  1707. void LLAgent::sendAnimationRequest(const LLUUID &anim_id, EAnimRequest request)
  1708. {
  1709. if (gAgentID.isNull() || anim_id.isNull() || !mRegionp)
  1710. {
  1711. return;
  1712. }
  1713. LLMessageSystem* msg = gMessageSystem;
  1714. msg->newMessageFast(_PREHASH_AgentAnimation);
  1715. msg->nextBlockFast(_PREHASH_AgentData);
  1716. msg->addUUIDFast(_PREHASH_AgentID, getID());
  1717. msg->addUUIDFast(_PREHASH_SessionID, getSessionID());
  1718. msg->nextBlockFast(_PREHASH_AnimationList);
  1719. msg->addUUIDFast(_PREHASH_AnimID, (anim_id) );
  1720. msg->addBOOLFast(_PREHASH_StartAnim, (request == ANIM_REQUEST_START) ? TRUE : FALSE);
  1721. msg->nextBlockFast(_PREHASH_PhysicalAvatarEventList);
  1722. msg->addBinaryDataFast(_PREHASH_TypeData, NULL, 0);
  1723. sendReliableMessage();
  1724. }
  1725. void LLAgent::sendWalkRun(bool running)
  1726. {
  1727. LLMessageSystem* msgsys = gMessageSystem;
  1728. if (msgsys)
  1729. {
  1730. msgsys->newMessageFast(_PREHASH_SetAlwaysRun);
  1731. msgsys->nextBlockFast(_PREHASH_AgentData);
  1732. msgsys->addUUIDFast(_PREHASH_AgentID, getID());
  1733. msgsys->addUUIDFast(_PREHASH_SessionID, getSessionID());
  1734. msgsys->addBOOLFast(_PREHASH_AlwaysRun, BOOL(running) );
  1735. sendReliableMessage();
  1736. }
  1737. }
  1738. void LLAgent::friendsChanged()
  1739. {
  1740. LLCollectProxyBuddies collector;
  1741. LLAvatarTracker::instance().applyFunctor(collector);
  1742. mProxyForAgents = collector.mProxy;
  1743. }
  1744. BOOL LLAgent::isGrantedProxy(const LLPermissions& perm)
  1745. {
  1746. return (mProxyForAgents.count(perm.getOwner()) > 0);
  1747. }
  1748. BOOL LLAgent::allowOperation(PermissionBit op,
  1749.  const LLPermissions& perm,
  1750.  U64 group_proxy_power,
  1751.  U8 god_minimum)
  1752. {
  1753. // Check god level.
  1754. if (getGodLevel() >= god_minimum) return TRUE;
  1755. if (!perm.isOwned()) return FALSE;
  1756. // A group member with group_proxy_power can act as owner.
  1757. BOOL is_group_owned;
  1758. LLUUID owner_id;
  1759. perm.getOwnership(owner_id, is_group_owned);
  1760. LLUUID group_id(perm.getGroup());
  1761. LLUUID agent_proxy(getID());
  1762. if (is_group_owned)
  1763. {
  1764. if (hasPowerInGroup(group_id, group_proxy_power))
  1765. {
  1766. // Let the member assume the group's id for permission requests.
  1767. agent_proxy = owner_id;
  1768. }
  1769. }
  1770. else
  1771. {
  1772. // Check for granted mod permissions.
  1773. if ((PERM_OWNER != op) && isGrantedProxy(perm))
  1774. {
  1775. agent_proxy = owner_id;
  1776. }
  1777. }
  1778. // This is the group id to use for permission requests.
  1779. // Only group members may use this field.
  1780. LLUUID group_proxy = LLUUID::null;
  1781. if (group_id.notNull() && isInGroup(group_id))
  1782. {
  1783. group_proxy = group_id;
  1784. }
  1785. // We now have max ownership information.
  1786. if (PERM_OWNER == op)
  1787. {
  1788. // This this was just a check for ownership, we can now return the answer.
  1789. return (agent_proxy == owner_id);
  1790. }
  1791. return perm.allowOperationBy(op, agent_proxy, group_proxy);
  1792. }
  1793. const LLColor4 &LLAgent::getEffectColor()
  1794. {
  1795. return mEffectColor;
  1796. }
  1797. void LLAgent::setEffectColor(const LLColor4 &color)
  1798. {
  1799. mEffectColor = color;
  1800. }
  1801. void LLAgent::initOriginGlobal(const LLVector3d &origin_global)
  1802. {
  1803. mAgentOriginGlobal = origin_global;
  1804. }
  1805. BOOL LLAgent::leftButtonGrabbed() const
  1806. return (!cameraMouselook() && mControlsTakenCount[CONTROL_LBUTTON_DOWN_INDEX] > 0) 
  1807. || (cameraMouselook() && mControlsTakenCount[CONTROL_ML_LBUTTON_DOWN_INDEX] > 0)
  1808. || (!cameraMouselook() && mControlsTakenPassedOnCount[CONTROL_LBUTTON_DOWN_INDEX] > 0)
  1809. || (cameraMouselook() && mControlsTakenPassedOnCount[CONTROL_ML_LBUTTON_DOWN_INDEX] > 0);
  1810. }
  1811. BOOL LLAgent::rotateGrabbed() const
  1812. return (mControlsTakenCount[CONTROL_YAW_POS_INDEX] > 0)
  1813. || (mControlsTakenCount[CONTROL_YAW_NEG_INDEX] > 0); 
  1814. }
  1815. BOOL LLAgent::forwardGrabbed() const
  1816. return (mControlsTakenCount[CONTROL_AT_POS_INDEX] > 0); 
  1817. }
  1818. BOOL LLAgent::backwardGrabbed() const
  1819. return (mControlsTakenCount[CONTROL_AT_NEG_INDEX] > 0); 
  1820. }
  1821. BOOL LLAgent::upGrabbed() const
  1822. return (mControlsTakenCount[CONTROL_UP_POS_INDEX] > 0); 
  1823. }
  1824. BOOL LLAgent::downGrabbed() const
  1825. return (mControlsTakenCount[CONTROL_UP_NEG_INDEX] > 0); 
  1826. }
  1827. void update_group_floaters(const LLUUID& group_id)
  1828. {
  1829. LLGroupActions::refresh(group_id);
  1830. //*TODO Implement group update for Profile View 
  1831. // still actual as of July 31, 2009 (DZ)
  1832. gAgent.fireEvent(new LLOldEvents::LLEvent(&gAgent, "new group"), "");
  1833. }
  1834. // static
  1835. void LLAgent::processAgentDropGroup(LLMessageSystem *msg, void **)
  1836. {
  1837. LLUUID agent_id;
  1838. msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id );
  1839. if (agent_id != gAgentID)
  1840. {
  1841. llwarns << "processAgentDropGroup for agent other than me" << llendl;
  1842. return;
  1843. }
  1844. LLUUID group_id;
  1845. msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_GroupID, group_id );
  1846. // Remove the group if it already exists remove it and add the new data to pick up changes.
  1847. LLGroupData gd;
  1848. gd.mID = group_id;
  1849. S32 index = gAgent.mGroups.find(gd);
  1850. if (index != -1)
  1851. {
  1852. gAgent.mGroups.remove(index);
  1853. if (gAgent.getGroupID() == group_id)
  1854. {
  1855. gAgent.mGroupID.setNull();
  1856. gAgent.mGroupPowers = 0;
  1857. gAgent.mGroupName.clear();
  1858. gAgent.mGroupTitle.clear();
  1859. }
  1860. // refresh all group information
  1861. gAgent.sendAgentDataUpdateRequest();
  1862. LLGroupMgr::getInstance()->clearGroupData(group_id);
  1863. // close the floater for this group, if any.
  1864. LLGroupActions::closeGroup(group_id);
  1865. }
  1866. else
  1867. {
  1868. llwarns << "processAgentDropGroup, agent is not part of group " << group_id << llendl;
  1869. }
  1870. }
  1871. class LLAgentDropGroupViewerNode : public LLHTTPNode
  1872. {
  1873. virtual void post(
  1874. LLHTTPNode::ResponsePtr response,
  1875. const LLSD& context,
  1876. const LLSD& input) const
  1877. {
  1878. if (
  1879. !input.isMap() ||
  1880. !input.has("body") )
  1881. {
  1882. //what to do with badly formed message?
  1883. response->statusUnknownError(400);
  1884. response->result(LLSD("Invalid message parameters"));
  1885. }
  1886. LLSD body = input["body"];
  1887. if ( body.has("body") ) 
  1888. {
  1889. //stupid message system doubles up the "body"s
  1890. body = body["body"];
  1891. }
  1892. if (
  1893. body.has("AgentData") &&
  1894. body["AgentData"].isArray() &&
  1895. body["AgentData"][0].isMap() )
  1896. {
  1897. llinfos << "VALID DROP GROUP" << llendl;
  1898. //there is only one set of data in the AgentData block
  1899. LLSD agent_data = body["AgentData"][0];
  1900. LLUUID agent_id;
  1901. LLUUID group_id;
  1902. agent_id = agent_data["AgentID"].asUUID();
  1903. group_id = agent_data["GroupID"].asUUID();
  1904. if (agent_id != gAgentID)
  1905. {
  1906. llwarns
  1907. << "AgentDropGroup for agent other than me" << llendl;
  1908. response->notFound();
  1909. return;
  1910. }
  1911. // Remove the group if it already exists remove it
  1912. // and add the new data to pick up changes.
  1913. LLGroupData gd;
  1914. gd.mID = group_id;
  1915. S32 index = gAgent.mGroups.find(gd);
  1916. if (index != -1)
  1917. {
  1918. gAgent.mGroups.remove(index);
  1919. if (gAgent.getGroupID() == group_id)
  1920. {
  1921. gAgent.mGroupID.setNull();
  1922. gAgent.mGroupPowers = 0;
  1923. gAgent.mGroupName.clear();
  1924. gAgent.mGroupTitle.clear();
  1925. }
  1926. // refresh all group information
  1927. gAgent.sendAgentDataUpdateRequest();
  1928. LLGroupMgr::getInstance()->clearGroupData(group_id);
  1929. // close the floater for this group, if any.
  1930. LLGroupActions::closeGroup(group_id);
  1931. }
  1932. else
  1933. {
  1934. llwarns
  1935. << "AgentDropGroup, agent is not part of group "
  1936. << group_id << llendl;
  1937. }
  1938. response->result(LLSD());
  1939. }
  1940. else
  1941. {
  1942. //what to do with badly formed message?
  1943. response->statusUnknownError(400);
  1944. response->result(LLSD("Invalid message parameters"));
  1945. }
  1946. }
  1947. };
  1948. LLHTTPRegistration<LLAgentDropGroupViewerNode>
  1949. gHTTPRegistrationAgentDropGroupViewerNode(
  1950. "/message/AgentDropGroup");
  1951. // static
  1952. void LLAgent::processAgentGroupDataUpdate(LLMessageSystem *msg, void **)
  1953. {
  1954. LLUUID agent_id;
  1955. msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id );
  1956. if (agent_id != gAgentID)
  1957. {
  1958. llwarns << "processAgentGroupDataUpdate for agent other than me" << llendl;
  1959. return;
  1960. }
  1961. S32 count = msg->getNumberOfBlocksFast(_PREHASH_GroupData);
  1962. LLGroupData group;
  1963. S32 index = -1;
  1964. bool need_floater_update = false;
  1965. for(S32 i = 0; i < count; ++i)
  1966. {
  1967. msg->getUUIDFast(_PREHASH_GroupData, _PREHASH_GroupID, group.mID, i);
  1968. msg->getUUIDFast(_PREHASH_GroupData, _PREHASH_GroupInsigniaID, group.mInsigniaID, i);
  1969. msg->getU64(_PREHASH_GroupData, "GroupPowers", group.mPowers, i);
  1970. msg->getBOOL(_PREHASH_GroupData, "AcceptNotices", group.mAcceptNotices, i);
  1971. msg->getS32(_PREHASH_GroupData, "Contribution", group.mContribution, i);
  1972. msg->getStringFast(_PREHASH_GroupData, _PREHASH_GroupName, group.mName, i);
  1973. if(group.mID.notNull())
  1974. {
  1975. need_floater_update = true;
  1976. // Remove the group if it already exists remove it and add the new data to pick up changes.
  1977. index = gAgent.mGroups.find(group);
  1978. if (index != -1)
  1979. {
  1980. gAgent.mGroups.remove(index);
  1981. }
  1982. gAgent.mGroups.put(group);
  1983. }
  1984. if (need_floater_update)
  1985. {
  1986. update_group_floaters(group.mID);
  1987. }
  1988. }
  1989. }
  1990. class LLAgentGroupDataUpdateViewerNode : public LLHTTPNode
  1991. {
  1992. virtual void post(
  1993. LLHTTPNode::ResponsePtr response,
  1994. const LLSD& context,
  1995. const LLSD& input) const
  1996. {
  1997. LLSD body = input["body"];
  1998. if(body.has("body"))
  1999. body = body["body"];
  2000. LLUUID agent_id = body["AgentData"][0]["AgentID"].asUUID();
  2001. if (agent_id != gAgentID)
  2002. {
  2003. llwarns << "processAgentGroupDataUpdate for agent other than me" << llendl;
  2004. return;
  2005. }
  2006. LLSD group_data = body["GroupData"];
  2007. LLSD::array_iterator iter_group =
  2008. group_data.beginArray();
  2009. LLSD::array_iterator end_group =
  2010. group_data.endArray();
  2011. int group_index = 0;
  2012. for(; iter_group != end_group; ++iter_group)
  2013. {
  2014. LLGroupData group;
  2015. S32 index = -1;
  2016. bool need_floater_update = false;
  2017. group.mID = (*iter_group)["GroupID"].asUUID();
  2018. group.mPowers = ll_U64_from_sd((*iter_group)["GroupPowers"]);
  2019. group.mAcceptNotices = (*iter_group)["AcceptNotices"].asBoolean();
  2020. group.mListInProfile = body["NewGroupData"][group_index]["ListInProfile"].asBoolean();
  2021. group.mInsigniaID = (*iter_group)["GroupInsigniaID"].asUUID();
  2022. group.mName = (*iter_group)["GroupName"].asString();
  2023. group.mContribution = (*iter_group)["Contribution"].asInteger();
  2024. group_index++;
  2025. if(group.mID.notNull())
  2026. {
  2027. need_floater_update = true;
  2028. // Remove the group if it already exists remove it and add the new data to pick up changes.
  2029. index = gAgent.mGroups.find(group);
  2030. if (index != -1)
  2031. {
  2032. gAgent.mGroups.remove(index);
  2033. }
  2034. gAgent.mGroups.put(group);
  2035. }
  2036. if (need_floater_update)
  2037. {
  2038. update_group_floaters(group.mID);
  2039. }
  2040. }
  2041. }
  2042. };
  2043. LLHTTPRegistration<LLAgentGroupDataUpdateViewerNode >
  2044. gHTTPRegistrationAgentGroupDataUpdateViewerNode ("/message/AgentGroupDataUpdate"); 
  2045. // static
  2046. void LLAgent::processAgentDataUpdate(LLMessageSystem *msg, void **)
  2047. {
  2048. LLUUID agent_id;
  2049. msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id );
  2050. if (agent_id != gAgentID)
  2051. {
  2052. llwarns << "processAgentDataUpdate for agent other than me" << llendl;
  2053. return;
  2054. }
  2055. msg->getStringFast(_PREHASH_AgentData, _PREHASH_GroupTitle, gAgent.mGroupTitle);
  2056. LLUUID active_id;
  2057. msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_ActiveGroupID, active_id);
  2058. if(active_id.notNull())
  2059. {
  2060. gAgent.mGroupID = active_id;
  2061. msg->getU64(_PREHASH_AgentData, "GroupPowers", gAgent.mGroupPowers);
  2062. msg->getString(_PREHASH_AgentData, _PREHASH_GroupName, gAgent.mGroupName);
  2063. }
  2064. else
  2065. {
  2066. gAgent.mGroupID.setNull();
  2067. gAgent.mGroupPowers = 0;
  2068. gAgent.mGroupName.clear();
  2069. }
  2070. update_group_floaters(active_id);
  2071. }
  2072. // static
  2073. void LLAgent::processScriptControlChange(LLMessageSystem *msg, void **)
  2074. {
  2075. S32 block_count = msg->getNumberOfBlocks("Data");
  2076. for (S32 block_index = 0; block_index < block_count; block_index++)
  2077. {
  2078. BOOL take_controls;
  2079. U32 controls;
  2080. BOOL passon;
  2081. U32 i;
  2082. msg->getBOOL("Data", "TakeControls", take_controls, block_index);
  2083. if (take_controls)
  2084. {
  2085. // take controls
  2086. msg->getU32("Data", "Controls", controls, block_index );
  2087. msg->getBOOL("Data", "PassToAgent", passon, block_index );
  2088. U32 total_count = 0;
  2089. for (i = 0; i < TOTAL_CONTROLS; i++)
  2090. {
  2091. if (controls & ( 1 << i))
  2092. {
  2093. if (passon)
  2094. {
  2095. gAgent.mControlsTakenPassedOnCount[i]++;
  2096. }
  2097. else
  2098. {
  2099. gAgent.mControlsTakenCount[i]++;
  2100. }
  2101. total_count++;
  2102. }
  2103. }
  2104. // Any control taken?  If so, might be first time.
  2105. //if (total_count > 0)
  2106. //{
  2107. //LLFirstUse::useOverrideKeys();
  2108. //}
  2109. }
  2110. else
  2111. {
  2112. // release controls
  2113. msg->getU32("Data", "Controls", controls, block_index );
  2114. msg->getBOOL("Data", "PassToAgent", passon, block_index );
  2115. for (i = 0; i < TOTAL_CONTROLS; i++)
  2116. {
  2117. if (controls & ( 1 << i))
  2118. {
  2119. if (passon)
  2120. {
  2121. gAgent.mControlsTakenPassedOnCount[i]--;
  2122. if (gAgent.mControlsTakenPassedOnCount[i] < 0)
  2123. {
  2124. gAgent.mControlsTakenPassedOnCount[i] = 0;
  2125. }
  2126. }
  2127. else
  2128. {
  2129. gAgent.mControlsTakenCount[i]--;
  2130. if (gAgent.mControlsTakenCount[i] < 0)
  2131. {
  2132. gAgent.mControlsTakenCount[i] = 0;
  2133. }
  2134. }
  2135. }
  2136. }
  2137. }
  2138. }
  2139. }
  2140. /*
  2141. // static
  2142. void LLAgent::processControlTake(LLMessageSystem *msg, void **)
  2143. {
  2144. U32 controls;
  2145. msg->getU32("Data", "Controls", controls );
  2146. U32 passon;
  2147. msg->getBOOL("Data", "PassToAgent", passon );
  2148. S32 i;
  2149. S32 total_count = 0;
  2150. for (i = 0; i < TOTAL_CONTROLS; i++)
  2151. {
  2152. if (controls & ( 1 << i))
  2153. {
  2154. if (passon)
  2155. {
  2156. gAgent.mControlsTakenPassedOnCount[i]++;
  2157. }
  2158. else
  2159. {
  2160. gAgent.mControlsTakenCount[i]++;
  2161. }
  2162. total_count++;
  2163. }
  2164. }
  2165. // Any control taken?  If so, might be first time.
  2166. if (total_count > 0)
  2167. {
  2168. LLFirstUse::useOverrideKeys();
  2169. }
  2170. }
  2171. // static
  2172. void LLAgent::processControlRelease(LLMessageSystem *msg, void **)
  2173. {
  2174. U32 controls;
  2175. msg->getU32("Data", "Controls", controls );
  2176. U32 passon;
  2177. msg->getBOOL("Data", "PassToAgent", passon );
  2178. S32 i;
  2179. for (i = 0; i < TOTAL_CONTROLS; i++)
  2180. {
  2181. if (controls & ( 1 << i))
  2182. {
  2183. if (passon)
  2184. {
  2185. gAgent.mControlsTakenPassedOnCount[i]--;
  2186. if (gAgent.mControlsTakenPassedOnCount[i] < 0)
  2187. {
  2188. gAgent.mControlsTakenPassedOnCount[i] = 0;
  2189. }
  2190. }
  2191. else
  2192. {
  2193. gAgent.mControlsTakenCount[i]--;
  2194. if (gAgent.mControlsTakenCount[i] < 0)
  2195. {
  2196. gAgent.mControlsTakenCount[i] = 0;
  2197. }
  2198. }
  2199. }
  2200. }
  2201. }
  2202. */
  2203. //static
  2204. void LLAgent::processAgentCachedTextureResponse(LLMessageSystem *mesgsys, void **user_data)
  2205. {
  2206. gAgentQueryManager.mNumPendingQueries--;
  2207. LLVOAvatarSelf* avatarp = gAgent.getAvatarObject();
  2208. if (!avatarp || avatarp->isDead())
  2209. {
  2210. llwarns << "No avatar for user in cached texture update!" << llendl;
  2211. return;
  2212. }
  2213. if (gAgent.cameraCustomizeAvatar())
  2214. {
  2215. // ignore baked textures when in customize mode
  2216. return;
  2217. }
  2218. S32 query_id;
  2219. mesgsys->getS32Fast(_PREHASH_AgentData, _PREHASH_SerialNum, query_id);
  2220. S32 num_texture_blocks = mesgsys->getNumberOfBlocksFast(_PREHASH_WearableData);
  2221. S32 num_results = 0;
  2222. for (S32 texture_block = 0; texture_block < num_texture_blocks; texture_block++)
  2223. {
  2224. LLUUID texture_id;
  2225. U8 texture_index;
  2226. mesgsys->getUUIDFast(_PREHASH_WearableData, _PREHASH_TextureID, texture_id, texture_block);
  2227. mesgsys->getU8Fast(_PREHASH_WearableData, _PREHASH_TextureIndex, texture_index, texture_block);
  2228. if (texture_id.notNull() 
  2229. && (S32)texture_index < BAKED_NUM_INDICES 
  2230. && gAgentQueryManager.mActiveCacheQueries[texture_index] == query_id)
  2231. {
  2232. //llinfos << "Received cached texture " << (U32)texture_index << ": " << texture_id << llendl;
  2233. avatarp->setCachedBakedTexture(LLVOAvatarDictionary::bakedToLocalTextureIndex((EBakedTextureIndex)texture_index), texture_id);
  2234. //avatarp->setTETexture( LLVOAvatar::sBakedTextureIndices[texture_index], texture_id );
  2235. gAgentQueryManager.mActiveCacheQueries[texture_index] = 0;
  2236. num_results++;
  2237. }
  2238. }
  2239. llinfos << "Received cached texture response for " << num_results << " textures." << llendl;
  2240. avatarp->updateMeshTextures();
  2241. if (gAgentQueryManager.mNumPendingQueries == 0)
  2242. {
  2243. // RN: not sure why composites are disabled at this point
  2244. avatarp->setCompositeUpdatesEnabled(TRUE);
  2245. gAgent.sendAgentSetAppearance();
  2246. }
  2247. }
  2248. BOOL LLAgent::anyControlGrabbed() const
  2249. {
  2250. for (U32 i = 0; i < TOTAL_CONTROLS; i++)
  2251. {
  2252. if (gAgent.mControlsTakenCount[i] > 0)
  2253. return TRUE;
  2254. if (gAgent.mControlsTakenPassedOnCount[i] > 0)
  2255. return TRUE;
  2256. }
  2257. return FALSE;
  2258. }
  2259. BOOL LLAgent::isControlGrabbed(S32 control_index) const
  2260. {
  2261. return mControlsTakenCount[control_index] > 0;
  2262. }
  2263. void LLAgent::forceReleaseControls()
  2264. {
  2265. gMessageSystem->newMessage("ForceScriptControlRelease");
  2266. gMessageSystem->nextBlock("AgentData");
  2267. gMessageSystem->addUUID("AgentID", getID());
  2268. gMessageSystem->addUUID("SessionID", getSessionID());
  2269. sendReliableMessage();
  2270. }
  2271. void LLAgent::setHomePosRegion( const U64& region_handle, const LLVector3& pos_region)
  2272. {
  2273. mHaveHomePosition = TRUE;
  2274. mHomeRegionHandle = region_handle;
  2275. mHomePosRegion = pos_region;
  2276. }
  2277. BOOL LLAgent::getHomePosGlobal( LLVector3d* pos_global )
  2278. {
  2279. if(!mHaveHomePosition)
  2280. {
  2281. return FALSE;
  2282. }
  2283. F32 x = 0;
  2284. F32 y = 0;
  2285. from_region_handle( mHomeRegionHandle, &x, &y);
  2286. pos_global->setVec( x + mHomePosRegion.mV[VX], y + mHomePosRegion.mV[VY], mHomePosRegion.mV[VZ] );
  2287. return TRUE;
  2288. }
  2289. void LLAgent::clearVisualParams(void *data)
  2290. {
  2291. LLVOAvatar* avatarp = gAgent.getAvatarObject();
  2292. if (avatarp)
  2293. {
  2294. avatarp->clearVisualParamWeights();
  2295. avatarp->updateVisualParams();
  2296. }
  2297. }
  2298. //---------------------------------------------------------------------------
  2299. // Teleport
  2300. //---------------------------------------------------------------------------
  2301. // teleportCore() - stuff to do on any teleport
  2302. // protected
  2303. bool LLAgent::teleportCore(bool is_local)
  2304. {
  2305. if(TELEPORT_NONE != mTeleportState)
  2306. {
  2307. llwarns << "Attempt to teleport when already teleporting." << llendl;
  2308. return false;
  2309. }
  2310. #if 0
  2311. // This should not exist. It has been added, removed, added, and now removed again.
  2312. // This change needs to come from the simulator. Otherwise, the agent ends up out of
  2313. // sync with other viewers. Discuss in DEV-14145/VWR-6744 before reenabling.
  2314. // Stop all animation before actual teleporting 
  2315. LLVOAvatar* avatarp = gAgent.getAvatarObject();
  2316.         if (avatarp)
  2317. {
  2318. for ( LLVOAvatar::AnimIterator anim_it= avatarp->mPlayingAnimations.begin();
  2319.       anim_it != avatarp->mPlayingAnimations.end();
  2320.       ++anim_it)
  2321.                {
  2322.                        avatarp->stopMotion(anim_it->first);
  2323.                }
  2324.                avatarp->processAnimationStateChanges();
  2325.        }
  2326. #endif
  2327. // Don't call LLFirstUse::useTeleport because we don't know
  2328. // yet if the teleport will succeed.  Look in 
  2329. // process_teleport_location_reply
  2330. // close the map and find panels so we can see our destination
  2331. LLFloaterReg::hideInstance("world_map");
  2332. LLFloaterReg::hideInstance("search");
  2333. // hide land floater too - it'll be out of date
  2334. LLFloaterReg::hideInstance("about_land");
  2335. LLViewerParcelMgr::getInstance()->deselectLand();
  2336. LLViewerMediaFocus::getInstance()->clearFocus();
  2337. // Close all pie menus, deselect land, etc.
  2338. // Don't change the camera until we know teleport succeeded. JC
  2339. resetView(FALSE);
  2340. // local logic
  2341. LLViewerStats::getInstance()->incStat(LLViewerStats::ST_TELEPORT_COUNT);
  2342. if (!is_local)
  2343. {
  2344. gTeleportDisplay = TRUE;
  2345. gAgent.setTeleportState( LLAgent::TELEPORT_START );
  2346. //release geometry from old location
  2347. gPipeline.resetVertexBuffers();
  2348. }
  2349. make_ui_sound("UISndTeleportOut");
  2350. // MBW -- Let the voice client know a teleport has begun so it can leave the existing channel.
  2351. // This was breaking the case of teleporting within a single sim.  Backing it out for now.
  2352. // gVoiceClient->leaveChannel();
  2353. return true;
  2354. }
  2355. void LLAgent::teleportRequest(
  2356. const U64& region_handle,
  2357. const LLVector3& pos_local)
  2358. {
  2359. LLViewerRegion* regionp = getRegion();
  2360. if(regionp && teleportCore())
  2361. {
  2362. llinfos << "TeleportRequest: '" << region_handle << "':" << pos_local
  2363. << llendl;
  2364. LLMessageSystem* msg = gMessageSystem;
  2365. msg->newMessage("TeleportLocationRequest");
  2366. msg->nextBlockFast(_PREHASH_AgentData);
  2367. msg->addUUIDFast(_PREHASH_AgentID, getID());
  2368. msg->addUUIDFast(_PREHASH_SessionID, getSessionID());
  2369. msg->nextBlockFast(_PREHASH_Info);
  2370. msg->addU64("RegionHandle", region_handle);
  2371. msg->addVector3("Position", pos_local);
  2372. LLVector3 look_at(0,1,0);
  2373. msg->addVector3("LookAt", look_at);
  2374. sendReliableMessage();
  2375. }
  2376. }
  2377. // Landmark ID = LLUUID::null means teleport home
  2378. void LLAgent::teleportViaLandmark(const LLUUID& landmark_asset_id)
  2379. {
  2380. LLViewerRegion *regionp = getRegion();
  2381. if(regionp && teleportCore())
  2382. {
  2383. LLMessageSystem* msg = gMessageSystem;
  2384. msg->newMessageFast(_PREHASH_TeleportLandmarkRequest);
  2385. msg->nextBlockFast(_PREHASH_Info);
  2386. msg->addUUIDFast(_PREHASH_AgentID, getID());
  2387. msg->addUUIDFast(_PREHASH_SessionID, getSessionID());
  2388. msg->addUUIDFast(_PREHASH_LandmarkID, landmark_asset_id);
  2389. sendReliableMessage();
  2390. }
  2391. }
  2392. void LLAgent::teleportViaLure(const LLUUID& lure_id, BOOL godlike)
  2393. {
  2394. LLViewerRegion* regionp = getRegion();
  2395. if(regionp && teleportCore())
  2396. {
  2397. U32 teleport_flags = 0x0;
  2398. if (godlike)
  2399. {
  2400. teleport_flags |= TELEPORT_FLAGS_VIA_GODLIKE_LURE;
  2401. teleport_flags |= TELEPORT_FLAGS_DISABLE_CANCEL;
  2402. }
  2403. else
  2404. {
  2405. teleport_flags |= TELEPORT_FLAGS_VIA_LURE;
  2406. }
  2407. // send the message
  2408. LLMessageSystem* msg = gMessageSystem;
  2409. msg->newMessageFast(_PREHASH_TeleportLureRequest);
  2410. msg->nextBlockFast(_PREHASH_Info);
  2411. msg->addUUIDFast(_PREHASH_AgentID, getID());
  2412. msg->addUUIDFast(_PREHASH_SessionID, getSessionID());
  2413. msg->addUUIDFast(_PREHASH_LureID, lure_id);
  2414. // teleport_flags is a legacy field, now derived sim-side:
  2415. msg->addU32("TeleportFlags", teleport_flags);
  2416. sendReliableMessage();
  2417. }
  2418. }
  2419. // James Cook, July 28, 2005
  2420. void LLAgent::teleportCancel()
  2421. {
  2422. LLViewerRegion* regionp = getRegion();
  2423. if(regionp)
  2424. {
  2425. // send the message
  2426. LLMessageSystem* msg = gMessageSystem;
  2427. msg->newMessage("TeleportCancel");
  2428. msg->nextBlockFast(_PREHASH_Info);
  2429. msg->addUUIDFast(_PREHASH_AgentID, getID());
  2430. msg->addUUIDFast(_PREHASH_SessionID, getSessionID());
  2431. sendReliableMessage();
  2432. }
  2433. gTeleportDisplay = FALSE;
  2434. gAgent.setTeleportState( LLAgent::TELEPORT_NONE );
  2435. }
  2436. void LLAgent::teleportViaLocation(const LLVector3d& pos_global)
  2437. {
  2438. LLViewerRegion* regionp = getRegion();
  2439. U64 handle = to_region_handle(pos_global);
  2440. LLSimInfo* info = LLWorldMap::getInstance()->simInfoFromHandle(handle);
  2441. if(regionp && info)
  2442. {
  2443. LLVector3d region_origin = info->getGlobalOrigin();
  2444. LLVector3 pos_local(
  2445. (F32)(pos_global.mdV[VX] - region_origin.mdV[VX]),
  2446. (F32)(pos_global.mdV[VY] - region_origin.mdV[VY]),
  2447. (F32)(pos_global.mdV[VZ]));
  2448. teleportRequest(handle, pos_local);
  2449. }
  2450. else if(regionp && 
  2451. teleportCore(regionp->getHandle() == to_region_handle_global((F32)pos_global.mdV[VX], (F32)pos_global.mdV[VY])))
  2452. {
  2453. llwarns << "Using deprecated teleportlocationrequest." << llendl; 
  2454. // send the message
  2455. LLMessageSystem* msg = gMessageSystem;
  2456. msg->newMessageFast(_PREHASH_TeleportLocationRequest);
  2457. msg->nextBlockFast(_PREHASH_AgentData);
  2458. msg->addUUIDFast(_PREHASH_AgentID, getID());
  2459. msg->addUUIDFast(_PREHASH_SessionID, getSessionID());
  2460. msg->nextBlockFast(_PREHASH_Info);
  2461. F32 width = regionp->getWidth();
  2462. LLVector3 pos(fmod((F32)pos_global.mdV[VX], width),
  2463.   fmod((F32)pos_global.mdV[VY], width),
  2464.   (F32)pos_global.mdV[VZ]);
  2465. F32 region_x = (F32)(pos_global.mdV[VX]);
  2466. F32 region_y = (F32)(pos_global.mdV[VY]);
  2467. U64 region_handle = to_region_handle_global(region_x, region_y);
  2468. msg->addU64Fast(_PREHASH_RegionHandle, region_handle);
  2469. msg->addVector3Fast(_PREHASH_Position, pos);
  2470. pos.mV[VX] += 1;
  2471. msg->addVector3Fast(_PREHASH_LookAt, pos);
  2472. sendReliableMessage();
  2473. }
  2474. }
  2475. void LLAgent::setTeleportState(ETeleportState state)
  2476. {
  2477. mTeleportState = state;
  2478. if (mTeleportState > TELEPORT_NONE && gSavedSettings.getBOOL("FreezeTime"))
  2479. {
  2480. LLFloaterReg::hideInstance("snapshot");
  2481. }
  2482. if (mTeleportState == TELEPORT_MOVING)
  2483. {
  2484. // We're outa here. Save "back" slurl.
  2485. mTeleportSourceSLURL = LLAgentUI::buildSLURL();
  2486. }
  2487. else if(mTeleportState == TELEPORT_ARRIVING)
  2488. {
  2489. // Let the interested parties know we've teleported.
  2490. LLViewerParcelMgr::getInstance()->onTeleportFinished(false, getPositionGlobal());
  2491. }
  2492. }
  2493. void LLAgent::stopCurrentAnimations()
  2494. {
  2495. // This function stops all current overriding animations on this
  2496. // avatar, propagating this change back to the server.
  2497. LLVOAvatar* avatarp = gAgent.getAvatarObject();
  2498. if (avatarp)
  2499. {
  2500. for ( LLVOAvatar::AnimIterator anim_it =
  2501.       avatarp->mPlayingAnimations.begin();
  2502.       anim_it != avatarp->mPlayingAnimations.end();
  2503.       anim_it++)
  2504. {
  2505. if (anim_it->first ==
  2506.     ANIM_AGENT_SIT_GROUND_CONSTRAINED)
  2507. {
  2508. // don't cancel a ground-sit anim, as viewers
  2509. // use this animation's status in
  2510. // determining whether we're sitting. ick.
  2511. }
  2512. else
  2513. {
  2514. // stop this animation locally
  2515. avatarp->stopMotion(anim_it->first, TRUE);
  2516. // ...and tell the server to tell everyone.
  2517. sendAnimationRequest(anim_it->first, ANIM_REQUEST_STOP);
  2518. }
  2519. }
  2520. // re-assert at least the default standing animation, because
  2521. // viewers get confused by avs with no associated anims.
  2522. sendAnimationRequest(ANIM_AGENT_STAND,
  2523.      ANIM_REQUEST_START);
  2524. }
  2525. }
  2526. void LLAgent::fidget()
  2527. {
  2528. if (!getAFK())
  2529. {
  2530. F32 curTime = mFidgetTimer.getElapsedTimeF32();
  2531. if (curTime > mNextFidgetTime)
  2532. {
  2533. // pick a random fidget anim here
  2534. S32 oldFidget = mCurrentFidget;
  2535. mCurrentFidget = ll_rand(NUM_AGENT_STAND_ANIMS);
  2536. if (mCurrentFidget != oldFidget)
  2537. {
  2538. LLAgent::stopFidget();
  2539. switch(mCurrentFidget)
  2540. {
  2541. case 0:
  2542. mCurrentFidget = 0;
  2543. break;
  2544. case 1:
  2545. sendAnimationRequest(ANIM_AGENT_STAND_1, ANIM_REQUEST_START);
  2546. mCurrentFidget = 1;
  2547. break;
  2548. case 2:
  2549. sendAnimationRequest(ANIM_AGENT_STAND_2, ANIM_REQUEST_START);
  2550. mCurrentFidget = 2;
  2551. break;
  2552. case 3:
  2553. sendAnimationRequest(ANIM_AGENT_STAND_3, ANIM_REQUEST_START);
  2554. mCurrentFidget = 3;
  2555. break;
  2556. case 4:
  2557. sendAnimationRequest(ANIM_AGENT_STAND_4, ANIM_REQUEST_START);
  2558. mCurrentFidget = 4;
  2559. break;
  2560. }
  2561. }
  2562. // calculate next fidget time
  2563. mNextFidgetTime = curTime + ll_frand(MAX_FIDGET_TIME - MIN_FIDGET_TIME) + MIN_FIDGET_TIME;
  2564. }
  2565. }
  2566. }
  2567. void LLAgent::stopFidget()
  2568. {
  2569. LLDynamicArray<LLUUID> anims;
  2570. anims.put(ANIM_AGENT_STAND_1);
  2571. anims.put(ANIM_AGENT_STAND_2);
  2572. anims.put(ANIM_AGENT_STAND_3);
  2573. anims.put(ANIM_AGENT_STAND_4);
  2574. gAgent.sendAnimationRequests(anims, ANIM_REQUEST_STOP);
  2575. }
  2576. void LLAgent::requestEnterGodMode()
  2577. {
  2578. LLMessageSystem* msg = gMessageSystem;
  2579. msg->newMessageFast(_PREHASH_RequestGodlikePowers);
  2580. msg->nextBlockFast(_PREHASH_AgentData);
  2581. msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
  2582. msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
  2583. msg->nextBlockFast(_PREHASH_RequestBlock);
  2584. msg->addBOOLFast(_PREHASH_Godlike, TRUE);
  2585. msg->addUUIDFast(_PREHASH_Token, LLUUID::null);
  2586. // simulators need to know about your request
  2587. sendReliableMessage();
  2588. }
  2589. void LLAgent::requestLeaveGodMode()
  2590. {
  2591. LLMessageSystem* msg = gMessageSystem;
  2592. msg->newMessageFast(_PREHASH_RequestGodlikePowers);
  2593. msg->nextBlockFast(_PREHASH_AgentData);
  2594. msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
  2595. msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
  2596. msg->nextBlockFast(_PREHASH_RequestBlock);
  2597. msg->addBOOLFast(_PREHASH_Godlike, FALSE);
  2598. msg->addUUIDFast(_PREHASH_Token, LLUUID::null);
  2599. // simulator needs to know about your request
  2600. sendReliableMessage();
  2601. }
  2602. //-----------------------------------------------------------------------------
  2603. // sendAgentSetAppearance()
  2604. //-----------------------------------------------------------------------------
  2605. void LLAgent::sendAgentSetAppearance()
  2606. {
  2607. if (mAvatarObject.isNull()) return;
  2608. if (gAgentQueryManager.mNumPendingQueries > 0 && !gAgent.cameraCustomizeAvatar()) 
  2609. {
  2610. return;
  2611. }
  2612. llinfos << "TAT: Sent AgentSetAppearance: " << mAvatarObject->getBakedStatusForPrintout() << llendl;
  2613. //dumpAvatarTEs( "sendAgentSetAppearance()" );
  2614. LLMessageSystem* msg = gMessageSystem;
  2615. msg->newMessageFast(_PREHASH_AgentSetAppearance);
  2616. msg->nextBlockFast(_PREHASH_AgentData);
  2617. msg->addUUIDFast(_PREHASH_AgentID, getID());
  2618. msg->addUUIDFast(_PREHASH_SessionID, getSessionID());
  2619. // correct for the collision tolerance (to make it look like the 
  2620. // agent is actually walking on the ground/object)
  2621. // NOTE -- when we start correcting all of the other Havok geometry 
  2622. // to compensate for the COLLISION_TOLERANCE ugliness we will have 
  2623. // to tweak this number again
  2624. const LLVector3 body_size = mAvatarObject->mBodySize;
  2625. msg->addVector3Fast(_PREHASH_Size, body_size);
  2626. // To guard against out of order packets
  2627. // Note: always start by sending 1.  This resets the server's count. 0 on the server means "uninitialized"
  2628. mAppearanceSerialNum++;
  2629. msg->addU32Fast(_PREHASH_SerialNum, mAppearanceSerialNum );
  2630. // is texture data current relative to wearables?
  2631. // KLW - TAT this will probably need to check the local queue.
  2632. BOOL textures_current = mAvatarObject->areTexturesCurrent();
  2633. for(U8 baked_index = 0; baked_index < BAKED_NUM_INDICES; baked_index++ )
  2634. {
  2635. const ETextureIndex texture_index = LLVOAvatarDictionary::bakedToLocalTextureIndex((EBakedTextureIndex)baked_index);
  2636. // if we're not wearing a skirt, we don't need the texture to be baked
  2637. if (texture_index == TEX_SKIRT_BAKED && !mAvatarObject->isWearingWearableType(WT_SKIRT))
  2638. {
  2639. continue;
  2640. }
  2641. // IMG_DEFAULT_AVATAR means not baked. 0 index should be ignored for baked textures
  2642. if (!mAvatarObject->isTextureDefined(texture_index, 0))
  2643. {
  2644. textures_current = FALSE;
  2645. break;
  2646. }
  2647. }
  2648. // only update cache entries if we have all our baked textures
  2649. if (textures_current)
  2650. {
  2651. llinfos << "TAT: Sending cached texture data" << llendl;
  2652. for (U8 baked_index = 0; baked_index < BAKED_NUM_INDICES; baked_index++)
  2653. {
  2654. const LLVOAvatarDictionary::BakedEntry *baked_dict = LLVOAvatarDictionary::getInstance()->getBakedTexture((EBakedTextureIndex)baked_index);
  2655. LLUUID hash;
  2656. for (U8 i=0; i < baked_dict->mWearables.size(); i++)
  2657. {
  2658. // EWearableType wearable_type = gBakedWearableMap[baked_index][wearable_num];
  2659. const EWearableType wearable_type = baked_dict->mWearables[i];
  2660. // MULTI-WEARABLE: fixed to 0th - extend to everything once messaging works.
  2661. const LLWearable* wearable = gAgentWearables.getWearable(wearable_type,0);
  2662. if (wearable)
  2663. {
  2664. hash ^= wearable->getAssetID();
  2665. }
  2666. }
  2667. if (hash.notNull())
  2668. {
  2669. hash ^= baked_dict->mWearablesHashID;
  2670. }
  2671. const ETextureIndex texture_index = LLVOAvatarDictionary::bakedToLocalTextureIndex((EBakedTextureIndex)baked_index);
  2672. msg->nextBlockFast(_PREHASH_WearableData);
  2673. msg->addUUIDFast(_PREHASH_CacheID, hash);
  2674. msg->addU8Fast(_PREHASH_TextureIndex, (U8)texture_index);
  2675. }
  2676. msg->nextBlockFast(_PREHASH_ObjectData);
  2677. mAvatarObject->sendAppearanceMessage( gMessageSystem );
  2678. }
  2679. else
  2680. {
  2681. // If the textures aren't baked, send NULL for texture IDs
  2682. // This means the baked texture IDs on the server will be untouched.
  2683. // Once all textures are baked, another AvatarAppearance message will be sent to update the TEs
  2684. msg->nextBlockFast(_PREHASH_ObjectData);
  2685. gMessageSystem->addBinaryDataFast(_PREHASH_TextureEntry, NULL, 0);
  2686. }
  2687. S32 transmitted_params = 0;
  2688. for (LLViewerVisualParam* param = (LLViewerVisualParam*)mAvatarObject->getFirstVisualParam();
  2689.  param;
  2690.  param = (LLViewerVisualParam*)mAvatarObject->getNextVisualParam())
  2691. {
  2692. if (param->getGroup() == VISUAL_PARAM_GROUP_TWEAKABLE)
  2693. {
  2694. msg->nextBlockFast(_PREHASH_VisualParam );
  2695. // We don't send the param ids.  Instead, we assume that the receiver has the same params in the same sequence.
  2696. const F32 param_value = param->getWeight();
  2697. const U8 new_weight = F32_to_U8(param_value, param->getMinWeight(), param->getMaxWeight());
  2698. msg->addU8Fast(_PREHASH_ParamValue, new_weight );
  2699. transmitted_params++;
  2700. }
  2701. }
  2702. // llinfos << "Avatar XML num VisualParams transmitted = " << transmitted_params << llendl;
  2703. sendReliableMessage();
  2704. }
  2705. void LLAgent::sendAgentDataUpdateRequest()
  2706. {
  2707. gMessageSystem->newMessageFast(_PREHASH_AgentDataUpdateRequest);
  2708. gMessageSystem->nextBlockFast(_PREHASH_AgentData);
  2709. gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
  2710. gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
  2711. sendReliableMessage();
  2712. }
  2713. void LLAgent::sendAgentUserInfoRequest()
  2714. {
  2715. if(getID().isNull())
  2716. return; // not logged in
  2717. gMessageSystem->newMessageFast(_PREHASH_UserInfoRequest);
  2718. gMessageSystem->nextBlockFast(_PREHASH_AgentData);
  2719. gMessageSystem->addUUIDFast(_PREHASH_AgentID, getID());
  2720. gMessageSystem->addUUIDFast(_PREHASH_SessionID, getSessionID());
  2721. sendReliableMessage();
  2722. }
  2723. void LLAgent::observeFriends()
  2724. {
  2725. if(!mFriendObserver)
  2726. {
  2727. mFriendObserver = new LLAgentFriendObserver;
  2728. LLAvatarTracker::instance().addObserver(mFriendObserver);
  2729. friendsChanged();
  2730. }
  2731. }
  2732. void LLAgent::parseTeleportMessages(const std::string& xml_filename)
  2733. {
  2734. LLXMLNodePtr root;
  2735. BOOL success = LLUICtrlFactory::getLayeredXMLNode(xml_filename, root);
  2736. if (!success || !root || !root->hasName( "teleport_messages" ))
  2737. {
  2738. llerrs << "Problem reading teleport string XML file: " 
  2739.    << xml_filename << llendl;
  2740. return;
  2741. }
  2742. for (LLXMLNode* message_set = root->getFirstChild();
  2743.  message_set != NULL;
  2744.  message_set = message_set->getNextSibling())
  2745. {
  2746. if ( !message_set->hasName("message_set") ) continue;
  2747. std::map<std::string, std::string> *teleport_msg_map = NULL;
  2748. std::string message_set_name;
  2749. if ( message_set->getAttributeString("name", message_set_name) )
  2750. {
  2751. //now we loop over all the string in the set and add them
  2752. //to the appropriate set
  2753. if ( message_set_name == "errors" )
  2754. {
  2755. teleport_msg_map = &sTeleportErrorMessages;
  2756. }
  2757. else if ( message_set_name == "progress" )
  2758. {
  2759. teleport_msg_map = &sTeleportProgressMessages;
  2760. }
  2761. }
  2762. if ( !teleport_msg_map ) continue;
  2763. std::string message_name;
  2764. for (LLXMLNode* message_node = message_set->getFirstChild();
  2765.  message_node != NULL;
  2766.  message_node = message_node->getNextSibling())
  2767. {
  2768. if ( message_node->hasName("message") && 
  2769.  message_node->getAttributeString("name", message_name) )
  2770. {
  2771. (*teleport_msg_map)[message_name] =
  2772. message_node->getTextContents();
  2773. } //end if ( message exists and has a name)
  2774. } //end for (all message in set)
  2775. }//end for (all message sets in xml file)
  2776. }
  2777. void LLAgent::sendAgentUpdateUserInfo(bool im_via_email, const std::string& directory_visibility )
  2778. {
  2779. gMessageSystem->newMessageFast(_PREHASH_UpdateUserInfo);
  2780. gMessageSystem->nextBlockFast(_PREHASH_AgentData);
  2781. gMessageSystem->addUUIDFast(_PREHASH_AgentID, getID());
  2782. gMessageSystem->addUUIDFast(_PREHASH_SessionID, getSessionID());
  2783. gMessageSystem->nextBlockFast(_PREHASH_UserData);
  2784. gMessageSystem->addBOOLFast(_PREHASH_IMViaEMail, im_via_email);
  2785. gMessageSystem->addString("DirectoryVisibility", directory_visibility);
  2786. gAgent.sendReliableMessage();
  2787. }
  2788. // static
  2789. void LLAgent::dumpGroupInfo()
  2790. {
  2791. llinfos << "group   " << gAgent.mGroupName << llendl;
  2792. llinfos << "ID      " << gAgent.mGroupID << llendl;
  2793. llinfos << "powers " << gAgent.mGroupPowers << llendl;
  2794. llinfos << "title   " << gAgent.mGroupTitle << llendl;
  2795. //llinfos << "insig   " << gAgent.mGroupInsigniaID << llendl;
  2796. }
  2797. /********************************************************************************/
  2798. LLAgentQueryManager gAgentQueryManager;
  2799. LLAgentQueryManager::LLAgentQueryManager() :
  2800. mWearablesCacheQueryID(0),
  2801. mNumPendingQueries(0),
  2802. mUpdateSerialNum(0)
  2803. {
  2804. for (U32 i = 0; i < BAKED_NUM_INDICES; i++)
  2805. {
  2806. mActiveCacheQueries[i] = 0;
  2807. }
  2808. }
  2809. LLAgentQueryManager::~LLAgentQueryManager()
  2810. {
  2811. }
  2812. // EOF