PageRenderTime 47ms CodeModel.GetById 21ms RepoModel.GetById 1ms app.codeStats 0ms

/indra/newview/llhudeffectbeam.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 348 lines | 256 code | 51 blank | 41 comment | 29 complexity | 8ebd476908fb2bfbd1af05e6b7908def MD5 | raw file
Possible License(s): LGPL-2.1
  1. /**
  2. * @file llhudeffectbeam.cpp
  3. * @brief LLHUDEffectBeam class implementation
  4. *
  5. * $LicenseInfo:firstyear=2002&license=viewerlgpl$
  6. * Second Life Viewer Source Code
  7. * Copyright (C) 2010, Linden Research, Inc.
  8. *
  9. * This library is free software; you can redistribute it and/or
  10. * modify it under the terms of the GNU Lesser General Public
  11. * License as published by the Free Software Foundation;
  12. * version 2.1 of the License only.
  13. *
  14. * This library is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  17. * Lesser General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU Lesser General Public
  20. * License along with this library; if not, write to the Free Software
  21. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  22. *
  23. * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
  24. * $/LicenseInfo$
  25. */
  26. #include "llviewerprecompiledheaders.h"
  27. #include "llhudeffectbeam.h"
  28. #include "message.h"
  29. #include "llviewerobjectlist.h"
  30. #include "llagent.h"
  31. #include "lldrawable.h"
  32. #include "llfontgl.h"
  33. #include "llgl.h"
  34. #include "llglheaders.h"
  35. #include "llhudrender.h"
  36. #include "llrendersphere.h"
  37. #include "llviewercamera.h"
  38. #include "llvoavatar.h"
  39. #include "llviewercontrol.h"
  40. const F32 BEAM_SPACING = 0.075f;
  41. LLHUDEffectBeam::LLHUDEffectBeam(const U8 type) : LLHUDEffect(type)
  42. {
  43. mKillTime = mDuration;
  44. // Initialize all of these to defaults
  45. S32 i;
  46. for (i = 0; i < NUM_POINTS; i++)
  47. {
  48. mInterp[i].setStartTime(BEAM_SPACING*i);
  49. mInterp[i].setEndTime(BEAM_SPACING*NUM_POINTS + BEAM_SPACING*i);
  50. mInterp[i].start();
  51. mInterpFade[i].setStartTime(BEAM_SPACING*NUM_POINTS + BEAM_SPACING*i - 0.5f*NUM_POINTS*BEAM_SPACING);
  52. mInterpFade[i].setEndTime(BEAM_SPACING*NUM_POINTS + BEAM_SPACING*i);
  53. mInterpFade[i].setStartVal(1.f);
  54. mInterpFade[i].setEndVal(0.f);
  55. }
  56. // Setup default timeouts and fade animations.
  57. F32 fade_length;
  58. fade_length = llmin(0.5f, mDuration);
  59. mFadeInterp.setStartTime(mKillTime - fade_length);
  60. mFadeInterp.setEndTime(mKillTime);
  61. mFadeInterp.setStartVal(1.f);
  62. mFadeInterp.setEndVal(0.f);
  63. }
  64. LLHUDEffectBeam::~LLHUDEffectBeam()
  65. {
  66. }
  67. void LLHUDEffectBeam::packData(LLMessageSystem *mesgsys)
  68. {
  69. if (!mSourceObject)
  70. {
  71. llwarns << "Missing source object!" << llendl;
  72. }
  73. // Pack the default data
  74. LLHUDEffect::packData(mesgsys);
  75. // Pack the type-specific data. Uses a fun packed binary format. Whee!
  76. // 16 + 24 + 1 = 41
  77. U8 packed_data[41];
  78. memset(packed_data, 0, 41);
  79. if (mSourceObject)
  80. {
  81. htonmemcpy(packed_data, mSourceObject->mID.mData, MVT_LLUUID, 16);
  82. }
  83. if (mTargetObject)
  84. {
  85. packed_data[16] = 1;
  86. }
  87. else
  88. {
  89. packed_data[16] = 0;
  90. }
  91. if (mTargetObject)
  92. {
  93. htonmemcpy(&(packed_data[17]), mTargetObject->mID.mData, MVT_LLUUID, 16);
  94. }
  95. else
  96. {
  97. htonmemcpy(&(packed_data[17]), mTargetPos.mdV, MVT_LLVector3d, 24);
  98. }
  99. mesgsys->addBinaryDataFast(_PREHASH_TypeData, packed_data, 41);
  100. }
  101. void LLHUDEffectBeam::unpackData(LLMessageSystem *mesgsys, S32 blocknum)
  102. {
  103. llerrs << "Got beam!" << llendl;
  104. BOOL use_target_object;
  105. LLVector3d new_target;
  106. U8 packed_data[41];
  107. LLHUDEffect::unpackData(mesgsys, blocknum);
  108. LLUUID source_id;
  109. LLUUID target_id;
  110. S32 size = mesgsys->getSizeFast(_PREHASH_Effect, blocknum, _PREHASH_TypeData);
  111. if (size != 41)
  112. {
  113. llwarns << "Beam effect with bad size " << size << llendl;
  114. return;
  115. }
  116. mesgsys->getBinaryDataFast(_PREHASH_Effect, _PREHASH_TypeData, packed_data, 41, blocknum);
  117. htonmemcpy(source_id.mData, packed_data, MVT_LLUUID, 16);
  118. LLViewerObject *objp = gObjectList.findObject(source_id);
  119. if (objp)
  120. {
  121. setSourceObject(objp);
  122. }
  123. use_target_object = packed_data[16];
  124. if (use_target_object)
  125. {
  126. htonmemcpy(target_id.mData, &packed_data[17], MVT_LLUUID, 16);
  127. LLViewerObject *objp = gObjectList.findObject(target_id);
  128. if (objp)
  129. {
  130. setTargetObject(objp);
  131. }
  132. }
  133. else
  134. {
  135. htonmemcpy(new_target.mdV, &(packed_data[17]), MVT_LLVector3d, 24);
  136. setTargetPos(new_target);
  137. }
  138. // We've received an update for the effect, update the various timeouts
  139. // and fade animations.
  140. mKillTime = mTimer.getElapsedTimeF32() + mDuration;
  141. F32 fade_length;
  142. fade_length = llmin(0.5f, mDuration);
  143. mFadeInterp.setStartTime(mKillTime - fade_length);
  144. mFadeInterp.setEndTime(mKillTime);
  145. mFadeInterp.setStartVal(1.f);
  146. mFadeInterp.setEndVal(0.f);
  147. }
  148. void LLHUDEffectBeam::setSourceObject(LLViewerObject *objp)
  149. {
  150. if (objp->isDead())
  151. {
  152. llwarns << "HUDEffectBeam: Source object is dead!" << llendl;
  153. mSourceObject = NULL;
  154. return;
  155. }
  156. if (mSourceObject == objp)
  157. {
  158. return;
  159. }
  160. mSourceObject = objp;
  161. if (mSourceObject)
  162. {
  163. S32 i;
  164. for (i = 0; i < NUM_POINTS; i++)
  165. {
  166. if (mSourceObject->isAvatar())
  167. {
  168. LLViewerObject *objp = mSourceObject;
  169. LLVOAvatar *avatarp = (LLVOAvatar *)objp;
  170. LLVector3d hand_pos_global = gAgent.getPosGlobalFromAgent(avatarp->mWristLeftp->getWorldPosition());
  171. mInterp[i].setStartVal(hand_pos_global);
  172. mInterp[i].start();
  173. }
  174. else
  175. {
  176. mInterp[i].setStartVal(mSourceObject->getPositionGlobal());
  177. mInterp[i].start();
  178. }
  179. }
  180. }
  181. }
  182. void LLHUDEffectBeam::setTargetObject(LLViewerObject *objp)
  183. {
  184. if (mTargetObject->isDead())
  185. {
  186. llwarns << "HUDEffectBeam: Target object is dead!" << llendl;
  187. }
  188. mTargetObject = objp;
  189. }
  190. void LLHUDEffectBeam::setTargetPos(const LLVector3d &pos_global)
  191. {
  192. mTargetPos = pos_global;
  193. mTargetObject = NULL;
  194. }
  195. void LLHUDEffectBeam::render()
  196. {
  197. if (!mSourceObject)
  198. {
  199. markDead();
  200. return;
  201. }
  202. if (mSourceObject->isDead())
  203. {
  204. markDead();
  205. return;
  206. }
  207. F32 time = mTimer.getElapsedTimeF32();
  208. // Kill us if our time is over...
  209. if (mKillTime < time)
  210. {
  211. markDead();
  212. return;
  213. }
  214. LLGLSPipelineAlpha gls_pipeline_alpha;
  215. gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
  216. // Interpolate the global fade alpha
  217. mFadeInterp.update(time);
  218. if (mTargetObject.notNull() && mTargetObject->mDrawable.notNull())
  219. {
  220. // use viewer object position on freshly created objects
  221. if (mTargetObject->mDrawable->getGeneration() == -1)
  222. {
  223. mTargetPos = mTargetObject->getPositionGlobal();
  224. }
  225. // otherwise use drawable
  226. else
  227. {
  228. mTargetPos = gAgent.getPosGlobalFromAgent(mTargetObject->mDrawable->getPositionAgent());
  229. }
  230. }
  231. // Init the color of the particles
  232. LLColor4U coloru = mColor;
  233. // Draw the particles
  234. S32 i;
  235. for (i = 0; i < NUM_POINTS; i++)
  236. {
  237. mInterp[i].update(time);
  238. if (!mInterp[i].isActive())
  239. {
  240. continue;
  241. }
  242. mInterpFade[i].update(time);
  243. if (mInterp[i].isDone())
  244. {
  245. // Reinitialize the particle when the particle has finished its animation.
  246. setupParticle(i);
  247. }
  248. F32 frac = mInterp[i].getCurFrac();
  249. F32 scale = 0.025f + fabs(0.05f*sin(2.f*F_PI*(frac - time)));
  250. scale *= mInterpFade[i].getCurVal();
  251. LLVector3 pos_agent = gAgent.getPosAgentFromGlobal(mInterp[i].getCurVal());
  252. F32 alpha = mFadeInterp.getCurVal()*mColor.mV[3];
  253. alpha *= mInterpFade[i].getCurVal();
  254. coloru.mV[3] = (U8)alpha;
  255. gGL.color4ubv(coloru.mV);
  256. gGL.pushMatrix();
  257. gGL.translatef(pos_agent.mV[0], pos_agent.mV[1], pos_agent.mV[2]);
  258. gGL.scalef(scale, scale, scale);
  259. gSphere.render();
  260. gGL.popMatrix();
  261. }
  262. }
  263. void LLHUDEffectBeam::renderForTimer()
  264. {
  265. render();
  266. }
  267. void LLHUDEffectBeam::setupParticle(const S32 i)
  268. {
  269. LLVector3d start_pos_global;
  270. if (mSourceObject->getPCode() == LL_PCODE_LEGACY_AVATAR)
  271. {
  272. LLViewerObject *objp = mSourceObject;
  273. LLVOAvatar *avatarp = (LLVOAvatar *)objp;
  274. start_pos_global = gAgent.getPosGlobalFromAgent(avatarp->mWristLeftp->getWorldPosition());
  275. }
  276. else
  277. {
  278. start_pos_global = mSourceObject->getPositionGlobal();
  279. }
  280. // Generate a random offset for the target point.
  281. const F32 SCALE = 0.5f;
  282. F32 x, y, z;
  283. x = ll_frand(SCALE) - 0.5f*SCALE;
  284. y = ll_frand(SCALE) - 0.5f*SCALE;
  285. z = ll_frand(SCALE) - 0.5f*SCALE;
  286. LLVector3d target_pos_global(mTargetPos);
  287. target_pos_global += LLVector3d(x, y, z);
  288. mInterp[i].setStartTime(mInterp[i].getEndTime());
  289. mInterp[i].setEndTime(mInterp[i].getStartTime() + BEAM_SPACING*NUM_POINTS);
  290. mInterp[i].setStartVal(start_pos_global);
  291. mInterp[i].setEndVal(target_pos_global);
  292. mInterp[i].start();
  293. // Setup the interpolator that fades out the alpha.
  294. mInterpFade[i].setStartTime(mInterp[i].getStartTime() + BEAM_SPACING*NUM_POINTS - 0.5f*NUM_POINTS*BEAM_SPACING);
  295. mInterpFade[i].setEndTime(mInterp[i].getStartTime() + BEAM_SPACING*NUM_POINTS - 0.05f);
  296. mInterpFade[i].start();
  297. }