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

游戏引擎

开发平台:

C++ Builder

  1. /** 
  2.  * @file llhudeffectbeam.cpp
  3.  * @brief LLHUDEffectBeam class implementation
  4.  *
  5.  * $LicenseInfo:firstyear=2002&license=viewergpl$
  6.  * 
  7.  * Copyright (c) 2002-2010, Linden Research, Inc.
  8.  * 
  9.  * Second Life Viewer Source Code
  10.  * The source code in this file ("Source Code") is provided by Linden Lab
  11.  * to you under the terms of the GNU General Public License, version 2.0
  12.  * ("GPL"), unless you have obtained a separate licensing agreement
  13.  * ("Other License"), formally executed by you and Linden Lab.  Terms of
  14.  * the GPL can be found in doc/GPL-license.txt in this distribution, or
  15.  * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
  16.  * 
  17.  * There are special exceptions to the terms and conditions of the GPL as
  18.  * it is applied to this Source Code. View the full text of the exception
  19.  * in the file doc/FLOSS-exception.txt in this software distribution, or
  20.  * online at
  21.  * http://secondlifegrid.net/programs/open_source/licensing/flossexception
  22.  * 
  23.  * By copying, modifying or distributing this software, you acknowledge
  24.  * that you have read and understood your obligations described above,
  25.  * and agree to abide by those obligations.
  26.  * 
  27.  * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
  28.  * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
  29.  * COMPLETENESS OR PERFORMANCE.
  30.  * $/LicenseInfo$
  31.  */
  32. #include "llviewerprecompiledheaders.h"
  33. #include "llhudeffectbeam.h"
  34. #include "message.h"
  35. #include "llviewerobjectlist.h"
  36. #include "llagent.h"
  37. #include "lldrawable.h"
  38. #include "llfontgl.h"
  39. #include "llgl.h"
  40. #include "llglheaders.h"
  41. #include "llhudrender.h"
  42. #include "llrendersphere.h"
  43. #include "llviewercamera.h"
  44. #include "llvoavatar.h"
  45. #include "llviewercontrol.h"
  46. const F32 BEAM_SPACING = 0.075f;
  47. LLHUDEffectBeam::LLHUDEffectBeam(const U8 type) : LLHUDEffect(type)
  48. {
  49. mKillTime = mDuration;
  50. // Initialize all of these to defaults
  51. S32 i;
  52. for (i = 0; i < NUM_POINTS; i++)
  53. {
  54. mInterp[i].setStartTime(BEAM_SPACING*i);
  55. mInterp[i].setEndTime(BEAM_SPACING*NUM_POINTS + BEAM_SPACING*i);
  56. mInterp[i].start();
  57. mInterpFade[i].setStartTime(BEAM_SPACING*NUM_POINTS + BEAM_SPACING*i - 0.5f*NUM_POINTS*BEAM_SPACING);
  58. mInterpFade[i].setEndTime(BEAM_SPACING*NUM_POINTS + BEAM_SPACING*i);
  59. mInterpFade[i].setStartVal(1.f);
  60. mInterpFade[i].setEndVal(0.f);
  61. }
  62. // Setup default timeouts and fade animations.
  63. F32 fade_length;
  64. fade_length = llmin(0.5f, mDuration);
  65. mFadeInterp.setStartTime(mKillTime - fade_length);
  66. mFadeInterp.setEndTime(mKillTime);
  67. mFadeInterp.setStartVal(1.f);
  68. mFadeInterp.setEndVal(0.f);
  69. }
  70. LLHUDEffectBeam::~LLHUDEffectBeam()
  71. {
  72. }
  73. void LLHUDEffectBeam::packData(LLMessageSystem *mesgsys)
  74. {
  75. if (!mSourceObject)
  76. {
  77. llwarns << "Missing source object!" << llendl;
  78. }
  79. // Pack the default data
  80. LLHUDEffect::packData(mesgsys);
  81. // Pack the type-specific data.  Uses a fun packed binary format.  Whee!
  82. // 16 + 24 + 1 = 41
  83. U8 packed_data[41];
  84. memset(packed_data, 0, 41);
  85. if (mSourceObject)
  86. {
  87. htonmemcpy(packed_data, mSourceObject->mID.mData, MVT_LLUUID, 16);
  88. }
  89. if (mTargetObject)
  90. {
  91. packed_data[16] = 1;
  92. }
  93. else
  94. {
  95. packed_data[16] = 0;
  96. }
  97. if (mTargetObject)
  98. {
  99. htonmemcpy(&(packed_data[17]), mTargetObject->mID.mData, MVT_LLUUID, 16);
  100. }
  101. else
  102. {
  103. htonmemcpy(&(packed_data[17]), mTargetPos.mdV, MVT_LLVector3d, 24);
  104. }
  105. mesgsys->addBinaryDataFast(_PREHASH_TypeData, packed_data, 41);
  106. }
  107. void LLHUDEffectBeam::unpackData(LLMessageSystem *mesgsys, S32 blocknum)
  108. {
  109. llerrs << "Got beam!" << llendl;
  110. BOOL use_target_object;
  111. LLVector3d new_target;
  112. U8 packed_data[41];
  113. LLHUDEffect::unpackData(mesgsys, blocknum);
  114. LLUUID source_id;
  115. LLUUID target_id;
  116. S32 size = mesgsys->getSizeFast(_PREHASH_Effect, blocknum, _PREHASH_TypeData);
  117. if (size != 41)
  118. {
  119. llwarns << "Beam effect with bad size " << size << llendl;
  120. return;
  121. }
  122. mesgsys->getBinaryDataFast(_PREHASH_Effect, _PREHASH_TypeData, packed_data, 41, blocknum);
  123. htonmemcpy(source_id.mData, packed_data, MVT_LLUUID, 16);
  124. LLViewerObject *objp = gObjectList.findObject(source_id);
  125. if (objp)
  126. {
  127. setSourceObject(objp);
  128. }
  129. use_target_object = packed_data[16];
  130. if (use_target_object)
  131. {
  132. htonmemcpy(target_id.mData, &packed_data[17], MVT_LLUUID, 16);
  133. LLViewerObject *objp = gObjectList.findObject(target_id);
  134. if (objp)
  135. {
  136. setTargetObject(objp);
  137. }
  138. }
  139. else
  140. {
  141. htonmemcpy(new_target.mdV, &(packed_data[17]), MVT_LLVector3d, 24);
  142. setTargetPos(new_target);
  143. }
  144. // We've received an update for the effect, update the various timeouts
  145. // and fade animations.
  146. mKillTime = mTimer.getElapsedTimeF32() + mDuration;
  147. F32 fade_length;
  148. fade_length = llmin(0.5f, mDuration);
  149. mFadeInterp.setStartTime(mKillTime - fade_length);
  150. mFadeInterp.setEndTime(mKillTime);
  151. mFadeInterp.setStartVal(1.f);
  152. mFadeInterp.setEndVal(0.f);
  153. }
  154. void LLHUDEffectBeam::setSourceObject(LLViewerObject *objp)
  155. {
  156. if (objp->isDead())
  157. {
  158. llwarns << "HUDEffectBeam: Source object is dead!" << llendl;
  159. mSourceObject = NULL;
  160. return;
  161. }
  162. if (mSourceObject == objp)
  163. {
  164. return;
  165. }
  166. mSourceObject = objp;
  167. if (mSourceObject)
  168. {
  169. S32 i;
  170. for (i = 0; i < NUM_POINTS; i++)
  171. {
  172. if (mSourceObject->isAvatar())
  173. {
  174. LLViewerObject *objp = mSourceObject;
  175. LLVOAvatar *avatarp = (LLVOAvatar *)objp;
  176. LLVector3d hand_pos_global = gAgent.getPosGlobalFromAgent(avatarp->mWristLeftp->getWorldPosition());
  177. mInterp[i].setStartVal(hand_pos_global);
  178. mInterp[i].start();
  179. }
  180. else
  181. {
  182. mInterp[i].setStartVal(mSourceObject->getPositionGlobal());
  183. mInterp[i].start();
  184. }
  185. }
  186. }
  187. }
  188. void LLHUDEffectBeam::setTargetObject(LLViewerObject *objp)
  189. {
  190. if (mTargetObject->isDead())
  191. {
  192. llwarns << "HUDEffectBeam: Target object is dead!" << llendl;
  193. }
  194. mTargetObject = objp;
  195. }
  196. void LLHUDEffectBeam::setTargetPos(const LLVector3d &pos_global)
  197. {
  198. mTargetPos = pos_global;
  199. mTargetObject = NULL;
  200. }
  201. void LLHUDEffectBeam::render()
  202. {
  203. if (!mSourceObject)
  204. {
  205. markDead();
  206. return;
  207. }
  208. if (mSourceObject->isDead())
  209. {
  210. markDead();
  211. return;
  212. }
  213. F32 time = mTimer.getElapsedTimeF32();
  214. // Kill us if our time is over...
  215. if (mKillTime < time)
  216. {
  217. markDead();
  218. return;
  219. }
  220. LLGLSPipelineAlpha gls_pipeline_alpha;
  221. gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
  222. // Interpolate the global fade alpha
  223. mFadeInterp.update(time);
  224. if (mTargetObject.notNull() && mTargetObject->mDrawable.notNull())
  225. {
  226. // use viewer object position on freshly created objects
  227. if (mTargetObject->mDrawable->getGeneration() == -1)
  228. {
  229. mTargetPos = mTargetObject->getPositionGlobal();
  230. }
  231. // otherwise use drawable
  232. else
  233. {
  234. mTargetPos = gAgent.getPosGlobalFromAgent(mTargetObject->mDrawable->getPositionAgent());
  235. }
  236. }
  237. // Init the color of the particles
  238. LLColor4U coloru = mColor;
  239. // Draw the particles
  240. S32 i;
  241. for (i = 0; i < NUM_POINTS; i++)
  242. {
  243. mInterp[i].update(time);
  244. if (!mInterp[i].isActive())
  245. {
  246. continue;
  247. }
  248. mInterpFade[i].update(time);
  249. if (mInterp[i].isDone())
  250. {
  251. // Reinitialize the particle when the particle has finished its animation.
  252. setupParticle(i);
  253. }
  254. F32 frac = mInterp[i].getCurFrac();
  255. F32 scale = 0.025f + fabs(0.05f*sin(2.f*F_PI*(frac - time)));
  256. scale *= mInterpFade[i].getCurVal();
  257. LLVector3 pos_agent = gAgent.getPosAgentFromGlobal(mInterp[i].getCurVal());
  258. F32 alpha = mFadeInterp.getCurVal()*mColor.mV[3];
  259. alpha *= mInterpFade[i].getCurVal();
  260. coloru.mV[3] = (U8)alpha;
  261. glColor4ubv(coloru.mV);
  262. glPushMatrix();
  263. glTranslatef(pos_agent.mV[0], pos_agent.mV[1], pos_agent.mV[2]);
  264. glScalef(scale, scale, scale);
  265. gSphere.render(0);
  266. glPopMatrix();
  267. }
  268. }
  269. void LLHUDEffectBeam::setupParticle(const S32 i)
  270. {
  271. LLVector3d start_pos_global;
  272. if (mSourceObject->getPCode() == LL_PCODE_LEGACY_AVATAR)
  273. {
  274. LLViewerObject *objp = mSourceObject;
  275. LLVOAvatar *avatarp = (LLVOAvatar *)objp;
  276. start_pos_global = gAgent.getPosGlobalFromAgent(avatarp->mWristLeftp->getWorldPosition());
  277. }
  278. else
  279. {
  280. start_pos_global = mSourceObject->getPositionGlobal();
  281. }
  282. // Generate a random offset for the target point.
  283. const F32 SCALE = 0.5f;
  284. F32 x, y, z;
  285. x = ll_frand(SCALE) - 0.5f*SCALE;
  286. y = ll_frand(SCALE) - 0.5f*SCALE;
  287. z = ll_frand(SCALE) - 0.5f*SCALE;
  288. LLVector3d target_pos_global(mTargetPos);
  289. target_pos_global += LLVector3d(x, y, z);
  290. mInterp[i].setStartTime(mInterp[i].getEndTime());
  291. mInterp[i].setEndTime(mInterp[i].getStartTime() + BEAM_SPACING*NUM_POINTS);
  292. mInterp[i].setStartVal(start_pos_global);
  293. mInterp[i].setEndVal(target_pos_global);
  294. mInterp[i].start();
  295. // Setup the interpolator that fades out the alpha.
  296. mInterpFade[i].setStartTime(mInterp[i].getStartTime() + BEAM_SPACING*NUM_POINTS - 0.5f*NUM_POINTS*BEAM_SPACING);
  297. mInterpFade[i].setEndTime(mInterp[i].getStartTime() + BEAM_SPACING*NUM_POINTS - 0.05f);
  298. mInterpFade[i].start();
  299. }