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

游戏引擎

开发平台:

C++ Builder

  1. /** 
  2.  * @file llhudicon.cpp
  3.  * @brief LLHUDIcon class implementation
  4.  *
  5.  * $LicenseInfo:firstyear=2006&license=viewergpl$
  6.  * 
  7.  * Copyright (c) 2006-2010, Linden Research, Inc.
  8.  * 
  9.  * Second Life Viewer Source Code
  10.  * The source code in this file ("Source Code") is provided by Linden Lab
  11.  * to you under the terms of the GNU General Public License, version 2.0
  12.  * ("GPL"), unless you have obtained a separate licensing agreement
  13.  * ("Other License"), formally executed by you and Linden Lab.  Terms of
  14.  * the GPL can be found in doc/GPL-license.txt in this distribution, or
  15.  * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
  16.  * 
  17.  * There are special exceptions to the terms and conditions of the GPL as
  18.  * it is applied to this Source Code. View the full text of the exception
  19.  * in the file doc/FLOSS-exception.txt in this software distribution, or
  20.  * online at
  21.  * http://secondlifegrid.net/programs/open_source/licensing/flossexception
  22.  * 
  23.  * By copying, modifying or distributing this software, you acknowledge
  24.  * that you have read and understood your obligations described above,
  25.  * and agree to abide by those obligations.
  26.  * 
  27.  * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
  28.  * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
  29.  * COMPLETENESS OR PERFORMANCE.
  30.  * $/LicenseInfo$
  31.  */
  32. #include "llviewerprecompiledheaders.h"
  33. #include "llhudicon.h"
  34. #include "llgl.h"
  35. #include "llrender.h"
  36. #include "llviewerobject.h"
  37. #include "lldrawable.h"
  38. #include "llviewercamera.h"
  39. #include "llviewertexture.h"
  40. #include "llviewerwindow.h"
  41. //-----------------------------------------------------------------------------
  42. // Local consts
  43. //-----------------------------------------------------------------------------
  44. const F32 ANIM_TIME = 0.4f;
  45. const F32 DIST_START_FADE = 15.f;
  46. const F32 DIST_END_FADE = 30.f;
  47. const F32 MAX_VISIBLE_TIME = 15.f;
  48. const F32 FADE_OUT_TIME = 1.f;
  49. //-----------------------------------------------------------------------------
  50. // Utility functions
  51. //-----------------------------------------------------------------------------
  52. static F32 calc_bouncy_animation(F32 x)
  53. {
  54. return -(cosf(x * F_PI * 2.5f - F_PI_BY_TWO))*(0.4f + x * -0.1f) + x * 1.3f;
  55. }
  56. //-----------------------------------------------------------------------------
  57. // static declarations
  58. //-----------------------------------------------------------------------------
  59. LLHUDIcon::icon_instance_t LLHUDIcon::sIconInstances;
  60. LLHUDIcon::LLHUDIcon(const U8 type) :
  61. LLHUDObject(type),
  62. mImagep(NULL),
  63. mPickID(0),
  64. mScale(0.1f),
  65. mHidden(FALSE)
  66. {
  67. sIconInstances.push_back(this);
  68. }
  69. LLHUDIcon::~LLHUDIcon()
  70. {
  71. mImagep = NULL;
  72. }
  73. void LLHUDIcon::renderIcon(BOOL for_select)
  74. {
  75. LLGLSUIDefault texture_state;
  76. LLGLDepthTest gls_depth(GL_TRUE);
  77. if (for_select)
  78. {
  79. gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
  80. }
  81. if (mHidden)
  82. return;
  83. if (mSourceObject.isNull() || mImagep.isNull())
  84. {
  85. markDead();
  86. return;
  87. }
  88. LLVector3 obj_position = mSourceObject->getRenderPosition();
  89. // put icon above object, and in front
  90. // RN: don't use drawable radius, it's fricking HUGE
  91. LLViewerCamera* camera = LLViewerCamera::getInstance();
  92. LLVector3 icon_relative_pos = (camera->getUpAxis() * ~mSourceObject->getRenderRotation());
  93. icon_relative_pos.abs();
  94. F32 distance_scale = llmin(mSourceObject->getScale().mV[VX] / icon_relative_pos.mV[VX], 
  95. mSourceObject->getScale().mV[VY] / icon_relative_pos.mV[VY], 
  96. mSourceObject->getScale().mV[VZ] / icon_relative_pos.mV[VZ]);
  97. F32 up_distance = 0.5f * distance_scale;
  98. LLVector3 icon_position = obj_position + (up_distance * camera->getUpAxis()) * 1.2f;
  99. LLVector3 icon_to_cam = LLViewerCamera::getInstance()->getOrigin() - icon_position;
  100. icon_to_cam.normVec();
  101. icon_position += icon_to_cam * mSourceObject->mDrawable->getRadius() * 1.1f;
  102. mDistance = dist_vec(icon_position, camera->getOrigin());
  103. F32 alpha_factor = for_select ? 1.f : clamp_rescale(mDistance, DIST_START_FADE, DIST_END_FADE, 1.f, 0.f);
  104. LLVector3 x_pixel_vec;
  105. LLVector3 y_pixel_vec;
  106. camera->getPixelVectors(icon_position, y_pixel_vec, x_pixel_vec);
  107. F32 scale_factor = 1.f;
  108. if (mAnimTimer.getElapsedTimeF32() < ANIM_TIME)
  109. {
  110. scale_factor = llmax(0.f, calc_bouncy_animation(mAnimTimer.getElapsedTimeF32() / ANIM_TIME));
  111. }
  112. F32 time_elapsed = mLifeTimer.getElapsedTimeF32();
  113. if (time_elapsed > MAX_VISIBLE_TIME)
  114. {
  115. markDead();
  116. return;
  117. }
  118. if (time_elapsed > MAX_VISIBLE_TIME - FADE_OUT_TIME)
  119. {
  120. alpha_factor *= clamp_rescale(time_elapsed, MAX_VISIBLE_TIME - FADE_OUT_TIME, MAX_VISIBLE_TIME, 1.f, 0.f);
  121. }
  122. F32 image_aspect = (F32)mImagep->getFullWidth() / (F32)mImagep->getFullHeight() ;
  123. LLVector3 x_scale = image_aspect * (F32)gViewerWindow->getWindowHeightScaled() * mScale * scale_factor * x_pixel_vec;
  124. LLVector3 y_scale = (F32)gViewerWindow->getWindowHeightScaled() * mScale * scale_factor * y_pixel_vec;
  125. LLVector3 lower_left = icon_position - (x_scale * 0.5f);
  126. LLVector3 lower_right = icon_position + (x_scale * 0.5f);
  127. LLVector3 upper_left = icon_position - (x_scale * 0.5f) + y_scale;
  128. LLVector3 upper_right = icon_position + (x_scale * 0.5f) + y_scale;
  129. if (for_select)
  130. {
  131. // set color to unique color id for picking
  132. LLColor4U coloru((U8)(mPickID >> 16), (U8)(mPickID >> 8), (U8)mPickID);
  133. gGL.color4ubv(coloru.mV);
  134. }
  135. else
  136. {
  137. LLColor4 icon_color = LLColor4::white;
  138. icon_color.mV[VALPHA] = alpha_factor;
  139. gGL.color4fv(icon_color.mV);
  140. gGL.getTexUnit(0)->bind(mImagep);
  141. }
  142. gGL.begin(LLRender::QUADS);
  143. {
  144. gGL.texCoord2f(0.f, 1.f);
  145. gGL.vertex3fv(upper_left.mV);
  146. gGL.texCoord2f(0.f, 0.f);
  147. gGL.vertex3fv(lower_left.mV);
  148. gGL.texCoord2f(1.f, 0.f);
  149. gGL.vertex3fv(lower_right.mV);
  150. gGL.texCoord2f(1.f, 1.f);
  151. gGL.vertex3fv(upper_right.mV);
  152. }
  153. gGL.end();
  154. }
  155. void LLHUDIcon::setImage(LLViewerTexture* imagep)
  156. {
  157. mImagep = imagep;
  158. mImagep->setAddressMode(LLTexUnit::TAM_CLAMP);
  159. }
  160. void LLHUDIcon::setScale(F32 fraction_of_fov)
  161. {
  162. mScale = fraction_of_fov;
  163. }
  164. void LLHUDIcon::markDead()
  165. {
  166. if (mSourceObject)
  167. {
  168. mSourceObject->clearIcon();
  169. }
  170. LLHUDObject::markDead();
  171. }
  172. void LLHUDIcon::render()
  173. {
  174. renderIcon(FALSE);
  175. }
  176. void LLHUDIcon::renderForSelect()
  177. {
  178. renderIcon(TRUE);
  179. }
  180. BOOL LLHUDIcon::lineSegmentIntersect(const LLVector3& start, const LLVector3& end, LLVector3* intersection)
  181. {
  182. if (mHidden)
  183. return FALSE;
  184. if (mSourceObject.isNull() || mImagep.isNull())
  185. {
  186. markDead();
  187. return FALSE;
  188. }
  189. LLVector3 obj_position = mSourceObject->getRenderPosition();
  190. // put icon above object, and in front
  191. // RN: don't use drawable radius, it's fricking HUGE
  192. LLViewerCamera* camera = LLViewerCamera::getInstance();
  193. LLVector3 icon_relative_pos = (camera->getUpAxis() * ~mSourceObject->getRenderRotation());
  194. icon_relative_pos.abs();
  195. F32 distance_scale = llmin(mSourceObject->getScale().mV[VX] / icon_relative_pos.mV[VX], 
  196. mSourceObject->getScale().mV[VY] / icon_relative_pos.mV[VY], 
  197. mSourceObject->getScale().mV[VZ] / icon_relative_pos.mV[VZ]);
  198. F32 up_distance = 0.5f * distance_scale;
  199. LLVector3 icon_position = obj_position + (up_distance * camera->getUpAxis()) * 1.2f;
  200. LLVector3 icon_to_cam = LLViewerCamera::getInstance()->getOrigin() - icon_position;
  201. icon_to_cam.normVec();
  202. icon_position += icon_to_cam * mSourceObject->mDrawable->getRadius() * 1.1f;
  203. mDistance = dist_vec(icon_position, camera->getOrigin());
  204. LLVector3 x_pixel_vec;
  205. LLVector3 y_pixel_vec;
  206. camera->getPixelVectors(icon_position, y_pixel_vec, x_pixel_vec);
  207. F32 scale_factor = 1.f;
  208. if (mAnimTimer.getElapsedTimeF32() < ANIM_TIME)
  209. {
  210. scale_factor = llmax(0.f, calc_bouncy_animation(mAnimTimer.getElapsedTimeF32() / ANIM_TIME));
  211. }
  212. F32 time_elapsed = mLifeTimer.getElapsedTimeF32();
  213. if (time_elapsed > MAX_VISIBLE_TIME)
  214. {
  215. markDead();
  216. return FALSE;
  217. }
  218. F32 image_aspect = (F32)mImagep->getFullWidth() / (F32)mImagep->getFullHeight() ;
  219. LLVector3 x_scale = image_aspect * (F32)gViewerWindow->getWindowHeightScaled() * mScale * scale_factor * x_pixel_vec;
  220. LLVector3 y_scale = (F32)gViewerWindow->getWindowHeightScaled() * mScale * scale_factor * y_pixel_vec;
  221. LLVector3 lower_left = icon_position - (x_scale * 0.5f);
  222. LLVector3 lower_right = icon_position + (x_scale * 0.5f);
  223. LLVector3 upper_left = icon_position - (x_scale * 0.5f) + y_scale;
  224. LLVector3 upper_right = icon_position + (x_scale * 0.5f) + y_scale;
  225. F32 t = 0.f;
  226. LLVector3 dir = end-start;
  227. if (LLTriangleRayIntersect(upper_right, upper_left, lower_right, start, dir, NULL, NULL, &t, FALSE) ||
  228. LLTriangleRayIntersect(upper_left, lower_left, lower_right, start, dir, NULL, NULL, &t, FALSE))
  229. {
  230. if (intersection)
  231. {
  232. *intersection = start + dir*t;
  233. }
  234. return TRUE;
  235. }
  236. return FALSE;
  237. }
  238. //static
  239. S32 LLHUDIcon::generatePickIDs(S32 start_id, S32 step_size)
  240. {
  241. S32 cur_id = start_id;
  242. icon_instance_t::iterator icon_it;
  243. for(icon_it = sIconInstances.begin(); icon_it != sIconInstances.end(); ++icon_it)
  244. {
  245. (*icon_it)->mPickID = cur_id;
  246. cur_id += step_size;
  247. }
  248. return cur_id;
  249. }
  250. //static
  251. LLHUDIcon* LLHUDIcon::handlePick(S32 pick_id)
  252. {
  253. icon_instance_t::iterator icon_it;
  254. for(icon_it = sIconInstances.begin(); icon_it != sIconInstances.end(); ++icon_it)
  255. {
  256. if (pick_id == (*icon_it)->mPickID)
  257. {
  258. return *icon_it;
  259. }
  260. }
  261. return NULL;
  262. }
  263. //static
  264. LLHUDIcon* LLHUDIcon::lineSegmentIntersectAll(const LLVector3& start, const LLVector3& end, LLVector3* intersection)
  265. {
  266. icon_instance_t::iterator icon_it;
  267. LLVector3 local_end = end;
  268. LLVector3 position;
  269. LLHUDIcon* ret = NULL;
  270. for(icon_it = sIconInstances.begin(); icon_it != sIconInstances.end(); ++icon_it)
  271. {
  272. LLHUDIcon* icon = *icon_it;
  273. if (icon->lineSegmentIntersect(start, local_end, &position))
  274. {
  275. ret = icon;
  276. if (intersection)
  277. {
  278. *intersection = position;
  279. }
  280. local_end = position;
  281. }
  282. }
  283. return ret;
  284. }
  285.  //static
  286. void LLHUDIcon::updateAll()
  287. {
  288. cleanupDeadIcons();
  289. }
  290. //static
  291. BOOL LLHUDIcon::iconsNearby()
  292. {
  293. return !sIconInstances.empty();
  294. }
  295. //static
  296. void LLHUDIcon::cleanupDeadIcons()
  297. {
  298. icon_instance_t::iterator icon_it;
  299. icon_instance_t icons_to_erase;
  300. for(icon_it = sIconInstances.begin(); icon_it != sIconInstances.end(); ++icon_it)
  301. {
  302. if ((*icon_it)->mDead)
  303. {
  304. icons_to_erase.push_back(*icon_it);
  305. }
  306. }
  307. for(icon_it = icons_to_erase.begin(); icon_it != icons_to_erase.end(); ++icon_it)
  308. {
  309. icon_instance_t::iterator found_it = std::find(sIconInstances.begin(), sIconInstances.end(), *icon_it);
  310. if (found_it != sIconInstances.end())
  311. {
  312. sIconInstances.erase(found_it);
  313. }
  314. }
  315. }
  316. //static
  317. S32 LLHUDIcon::getNumInstances()
  318. {
  319. return (S32)sIconInstances.size();
  320. }