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

游戏引擎

开发平台:

C++ Builder

  1. /** 
  2.  * @file llhudeffectpointat.cpp
  3.  * @brief LLHUDEffectPointAt 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 "llhudeffectpointat.h"
  34. #include "llgl.h"
  35. #include "llrender.h"
  36. #include "llagent.h"
  37. #include "lldrawable.h"
  38. #include "llviewerobjectlist.h"
  39. #include "llvoavatar.h"
  40. #include "message.h"
  41. // packet layout
  42. const S32 SOURCE_AVATAR = 0;
  43. const S32 TARGET_OBJECT = 16;
  44. const S32 TARGET_POS = 32;
  45. const S32 POINTAT_TYPE = 56;
  46. const S32 PKT_SIZE = 57;
  47. // throttle
  48. const F32 MAX_SENDS_PER_SEC = 4.f;
  49. const F32 MIN_DELTAPOS_FOR_UPDATE = 0.05f;
  50. // timeouts
  51. // can't use actual F32_MAX, because we add this to the current frametime
  52. const F32 MAX_TIMEOUT = F32_MAX / 4.f;
  53. const F32 POINTAT_TIMEOUTS[POINTAT_NUM_TARGETS] = 
  54. {
  55. MAX_TIMEOUT, //POINTAT_TARGET_NONE
  56. MAX_TIMEOUT, //POINTAT_TARGET_SELECT
  57. MAX_TIMEOUT, //POINTAT_TARGET_GRAB
  58. 0.f, //POINTAT_TARGET_CLEAR
  59. };
  60. const S32 POINTAT_PRIORITIES[POINTAT_NUM_TARGETS] = 
  61. {
  62. 0, //POINTAT_TARGET_NONE
  63. 1, //POINTAT_TARGET_SELECT
  64. 2, //POINTAT_TARGET_GRAB
  65. 3, //POINTAT_TARGET_CLEAR
  66. };
  67. // statics
  68. BOOL LLHUDEffectPointAt::sDebugPointAt;
  69. //-----------------------------------------------------------------------------
  70. // LLHUDEffectPointAt()
  71. //-----------------------------------------------------------------------------
  72. LLHUDEffectPointAt::LLHUDEffectPointAt(const U8 type) : 
  73. LLHUDEffect(type), 
  74. mKillTime(0.f),
  75. mLastSendTime(0.f)
  76. {
  77. clearPointAtTarget();
  78. }
  79. //-----------------------------------------------------------------------------
  80. // ~LLHUDEffectPointAt()
  81. //-----------------------------------------------------------------------------
  82. LLHUDEffectPointAt::~LLHUDEffectPointAt()
  83. {
  84. }
  85. //-----------------------------------------------------------------------------
  86. // packData()
  87. //-----------------------------------------------------------------------------
  88. void LLHUDEffectPointAt::packData(LLMessageSystem *mesgsys)
  89. {
  90. // Pack the default data
  91. LLHUDEffect::packData(mesgsys);
  92. // Pack the type-specific data.  Uses a fun packed binary format.  Whee!
  93. U8 packed_data[PKT_SIZE];
  94. memset(packed_data, 0, PKT_SIZE);
  95. if (mSourceObject)
  96. {
  97. htonmemcpy(&(packed_data[SOURCE_AVATAR]), mSourceObject->mID.mData, MVT_LLUUID, 16);
  98. }
  99. else
  100. {
  101. htonmemcpy(&(packed_data[SOURCE_AVATAR]), LLUUID::null.mData, MVT_LLUUID, 16);
  102. }
  103. // pack both target object and position
  104. // position interpreted as offset if target object is non-null
  105. if (mTargetObject)
  106. {
  107. htonmemcpy(&(packed_data[TARGET_OBJECT]), mTargetObject->mID.mData, MVT_LLUUID, 16);
  108. }
  109. else
  110. {
  111. htonmemcpy(&(packed_data[TARGET_OBJECT]), LLUUID::null.mData, MVT_LLUUID, 16);
  112. }
  113. htonmemcpy(&(packed_data[TARGET_POS]), mTargetOffsetGlobal.mdV, MVT_LLVector3d, 24);
  114. U8 pointAtTypePacked = (U8)mTargetType;
  115. htonmemcpy(&(packed_data[POINTAT_TYPE]), &pointAtTypePacked, MVT_U8, 1);
  116. mesgsys->addBinaryDataFast(_PREHASH_TypeData, packed_data, PKT_SIZE);
  117. mLastSendTime = mTimer.getElapsedTimeF32();
  118. }
  119. //-----------------------------------------------------------------------------
  120. // unpackData()
  121. //-----------------------------------------------------------------------------
  122. void LLHUDEffectPointAt::unpackData(LLMessageSystem *mesgsys, S32 blocknum)
  123. {
  124. LLVector3d new_target;
  125. U8 packed_data[PKT_SIZE];
  126. LLUUID dataId;
  127. mesgsys->getUUIDFast(_PREHASH_Effect, _PREHASH_ID, dataId, blocknum);
  128. // ignore messages from ourselves
  129. if (!gAgent.mPointAt.isNull() && dataId == gAgent.mPointAt->getID())
  130. {
  131. return;
  132. }
  133. LLHUDEffect::unpackData(mesgsys, blocknum);
  134. LLUUID source_id;
  135. LLUUID target_id;
  136. U8 pointAtTypeUnpacked = 0;
  137. S32 size = mesgsys->getSizeFast(_PREHASH_Effect, blocknum, _PREHASH_TypeData);
  138. if (size != PKT_SIZE)
  139. {
  140. llwarns << "PointAt effect with bad size " << size << llendl;
  141. return;
  142. }
  143. mesgsys->getBinaryDataFast(_PREHASH_Effect, _PREHASH_TypeData, packed_data, PKT_SIZE, blocknum);
  144. htonmemcpy(source_id.mData, &(packed_data[SOURCE_AVATAR]), MVT_LLUUID, 16);
  145. htonmemcpy(target_id.mData, &(packed_data[TARGET_OBJECT]), MVT_LLUUID, 16);
  146. htonmemcpy(new_target.mdV, &(packed_data[TARGET_POS]), MVT_LLVector3d, 24);
  147. htonmemcpy(&pointAtTypeUnpacked, &(packed_data[POINTAT_TYPE]), MVT_U8, 1);
  148. LLViewerObject *objp = gObjectList.findObject(source_id);
  149. if (objp && objp->isAvatar())
  150. {
  151. setSourceObject(objp);
  152. }
  153. else
  154. {
  155. //llwarns << "Could not find source avatar for pointat effect" << llendl;
  156. return;
  157. }
  158. objp = gObjectList.findObject(target_id);
  159. if (objp)
  160. {
  161. setTargetObjectAndOffset(objp, new_target);
  162. }
  163. else if (target_id.isNull())
  164. {
  165. setTargetPosGlobal(new_target);
  166. }
  167. mTargetType = (EPointAtType)pointAtTypeUnpacked;
  168. // mKillTime = mTimer.getElapsedTimeF32() + mDuration;
  169. update();
  170. }
  171. //-----------------------------------------------------------------------------
  172. // setTargetObjectAndOffset()
  173. //-----------------------------------------------------------------------------
  174. void LLHUDEffectPointAt::setTargetObjectAndOffset(LLViewerObject *objp, LLVector3d offset)
  175. {
  176. mTargetObject = objp;
  177. mTargetOffsetGlobal = offset;
  178. }
  179. //-----------------------------------------------------------------------------
  180. // setTargetPosGlobal()
  181. //-----------------------------------------------------------------------------
  182. void LLHUDEffectPointAt::setTargetPosGlobal(const LLVector3d &target_pos_global)
  183. {
  184. mTargetObject = NULL;
  185. mTargetOffsetGlobal = target_pos_global;
  186. }
  187. //-----------------------------------------------------------------------------
  188. // setPointAt()
  189. // called by agent logic to set look at behavior locally, and propagate to sim
  190. //-----------------------------------------------------------------------------
  191. BOOL LLHUDEffectPointAt::setPointAt(EPointAtType target_type, LLViewerObject *object, LLVector3 position)
  192. {
  193. if (!mSourceObject)
  194. {
  195. return FALSE;
  196. }
  197. if (target_type >= POINTAT_NUM_TARGETS)
  198. {
  199. llwarns << "Bad target_type " << (int)target_type << " - ignoring." << llendl;
  200. return FALSE;
  201. }
  202. // must be same or higher priority than existing effect
  203. if (POINTAT_PRIORITIES[target_type] < POINTAT_PRIORITIES[mTargetType])
  204. {
  205. return FALSE;
  206. }
  207. F32 current_time  = mTimer.getElapsedTimeF32();
  208. // type of pointat behavior or target object has changed
  209. BOOL targetTypeChanged = (target_type != mTargetType) ||
  210. (object != mTargetObject);
  211. BOOL targetPosChanged = (dist_vec(position, mLastSentOffsetGlobal) > MIN_DELTAPOS_FOR_UPDATE) && 
  212. ((current_time - mLastSendTime) > (1.f / MAX_SENDS_PER_SEC));
  213. if (targetTypeChanged || targetPosChanged)
  214. {
  215. mLastSentOffsetGlobal = position;
  216. setDuration(POINTAT_TIMEOUTS[target_type]);
  217. setNeedsSendToSim(TRUE);
  218. // llinfos << "Sending pointat data" << llendl;
  219. }
  220. if (target_type == POINTAT_TARGET_CLEAR)
  221. {
  222. clearPointAtTarget();
  223. }
  224. else
  225. {
  226. mTargetType = target_type;
  227. mTargetObject = object;
  228. if (object)
  229. {
  230. mTargetOffsetGlobal.setVec(position);
  231. }
  232. else
  233. {
  234. mTargetOffsetGlobal = gAgent.getPosGlobalFromAgent(position);
  235. }
  236. mKillTime = mTimer.getElapsedTimeF32() + mDuration;
  237. //set up requisite animation data
  238. update();
  239. }
  240. return TRUE;
  241. }
  242. //-----------------------------------------------------------------------------
  243. // clearPointAtTarget()
  244. //-----------------------------------------------------------------------------
  245. void LLHUDEffectPointAt::clearPointAtTarget()
  246. {
  247. mTargetObject = NULL;
  248. mTargetOffsetGlobal.clearVec();
  249. mTargetType = POINTAT_TARGET_NONE;
  250. }
  251. //-----------------------------------------------------------------------------
  252. // markDead()
  253. //-----------------------------------------------------------------------------
  254. void LLHUDEffectPointAt::markDead()
  255. {
  256. if (!mSourceObject.isNull() && mSourceObject->isAvatar())
  257. {
  258. ((LLVOAvatar*)(LLViewerObject*)mSourceObject)->removeAnimationData("PointAtPoint");
  259. }
  260. clearPointAtTarget();
  261. LLHUDEffect::markDead();
  262. }
  263. void LLHUDEffectPointAt::setSourceObject(LLViewerObject* objectp)
  264. {
  265. // restrict source objects to avatars
  266. if (objectp && objectp->isAvatar())
  267. {
  268. LLHUDEffect::setSourceObject(objectp);
  269. }
  270. }
  271. //-----------------------------------------------------------------------------
  272. // render()
  273. //-----------------------------------------------------------------------------
  274. void LLHUDEffectPointAt::render()
  275. {
  276. update();
  277. if (sDebugPointAt && mTargetType != POINTAT_TARGET_NONE)
  278. {
  279. gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
  280. LLVector3 target = mTargetPos + mSourceObject->getRenderPosition();
  281. gGL.pushMatrix();
  282. gGL.translatef(target.mV[VX], target.mV[VY], target.mV[VZ]);
  283. glScalef(0.3f, 0.3f, 0.3f);
  284. gGL.begin(LLRender::LINES);
  285. {
  286. gGL.color3f(1.f, 0.f, 0.f);
  287. gGL.vertex3f(-1.f, 0.f, 0.f);
  288. gGL.vertex3f(1.f, 0.f, 0.f);
  289. gGL.vertex3f(0.f, -1.f, 0.f);
  290. gGL.vertex3f(0.f, 1.f, 0.f);
  291. gGL.vertex3f(0.f, 0.f, -1.f);
  292. gGL.vertex3f(0.f, 0.f, 1.f);
  293. } gGL.end();
  294. gGL.popMatrix();
  295. }
  296. }
  297. //-----------------------------------------------------------------------------
  298. // update()
  299. //-----------------------------------------------------------------------------
  300. void LLHUDEffectPointAt::update()
  301. {
  302. // If the target object is dead, set the target object to NULL
  303. if (!mTargetObject.isNull() && mTargetObject->isDead())
  304. {
  305. clearPointAtTarget();
  306. }
  307. if (mSourceObject.isNull() || mSourceObject->isDead())
  308. {
  309. markDead();
  310. return;
  311. }
  312. F32 time = mTimer.getElapsedTimeF32();
  313. // clear out the effect if time is up
  314. if (mKillTime != 0.f && time > mKillTime)
  315. {
  316. mTargetType = POINTAT_TARGET_NONE;
  317. }
  318. if (mSourceObject->isAvatar())
  319. {
  320. if (mTargetType == POINTAT_TARGET_NONE)
  321. {
  322. ((LLVOAvatar*)(LLViewerObject*)mSourceObject)->removeAnimationData("PointAtPoint");
  323. }
  324. else
  325. {
  326. if (calcTargetPosition())
  327. {
  328. ((LLVOAvatar*)(LLViewerObject*)mSourceObject)->startMotion(ANIM_AGENT_EDITING);
  329. }
  330. }
  331. }
  332. }
  333. //-----------------------------------------------------------------------------
  334. // calcTargetPosition()
  335. // returns whether we successfully calculated a finite target position.
  336. //-----------------------------------------------------------------------------
  337. bool LLHUDEffectPointAt::calcTargetPosition()
  338. {
  339. LLViewerObject *targetObject = (LLViewerObject *)mTargetObject;
  340. LLVector3 local_offset;
  341. if (targetObject)
  342. {
  343. local_offset.setVec(mTargetOffsetGlobal);
  344. }
  345. else
  346. {
  347. local_offset = gAgent.getPosAgentFromGlobal(mTargetOffsetGlobal);
  348. }
  349. if (targetObject && targetObject->mDrawable.notNull())
  350. {
  351. LLQuaternion objRot;
  352. if (targetObject->isAvatar())
  353. {
  354. LLVOAvatar *avatarp = (LLVOAvatar *)targetObject;
  355. mTargetPos = avatarp->mHeadp->getWorldPosition();
  356. objRot = avatarp->mPelvisp->getWorldRotation();
  357. }
  358. else
  359. {
  360. if (targetObject->mDrawable->getGeneration() == -1)
  361. {
  362. mTargetPos = targetObject->getPositionAgent();
  363. objRot = targetObject->getWorldRotation();
  364. }
  365. else
  366. {
  367. mTargetPos = targetObject->getRenderPosition();
  368. objRot = targetObject->getRenderRotation();
  369. }
  370. }
  371. mTargetPos += (local_offset * objRot);
  372. }
  373. else
  374. {
  375. mTargetPos = local_offset;
  376. }
  377. mTargetPos -= mSourceObject->getRenderPosition();
  378. if (!llfinite(mTargetPos.lengthSquared()))
  379. {
  380. return false;
  381. }
  382. if (mSourceObject->isAvatar())
  383. {
  384. ((LLVOAvatar*)(LLViewerObject*)mSourceObject)->setAnimationData("PointAtPoint", (void *)&mTargetPos);
  385. }
  386. return true;
  387. }
  388. const LLVector3d LLHUDEffectPointAt::getPointAtPosGlobal()
  389. {
  390. LLVector3d global_pos;
  391. global_pos.setVec(mTargetPos);
  392. if (mSourceObject.notNull())
  393. {
  394. global_pos += mSourceObject->getPositionGlobal();
  395. }
  396. return global_pos;
  397. }