diff options
author | Jacek Antonelli | 2008-08-15 23:44:46 -0500 |
---|---|---|
committer | Jacek Antonelli | 2008-08-15 23:44:46 -0500 |
commit | 38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4 (patch) | |
tree | adca584755d22ca041a2dbfc35d4eca01f70b32c /linden/indra/newview/llhudeffectbeam.cpp | |
parent | README.txt (diff) | |
download | meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.zip meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.gz meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.bz2 meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.xz |
Second Life viewer sources 1.13.2.12
Diffstat (limited to 'linden/indra/newview/llhudeffectbeam.cpp')
-rw-r--r-- | linden/indra/newview/llhudeffectbeam.cpp | 390 |
1 files changed, 390 insertions, 0 deletions
diff --git a/linden/indra/newview/llhudeffectbeam.cpp b/linden/indra/newview/llhudeffectbeam.cpp new file mode 100644 index 0000000..a7e7a5e --- /dev/null +++ b/linden/indra/newview/llhudeffectbeam.cpp | |||
@@ -0,0 +1,390 @@ | |||
1 | /** | ||
2 | * @file llhudeffectbeam.cpp | ||
3 | * @brief LLHUDEffectBeam class implementation | ||
4 | * | ||
5 | * Copyright (c) 2002-2007, Linden Research, Inc. | ||
6 | * | ||
7 | * The source code in this file ("Source Code") is provided by Linden Lab | ||
8 | * to you under the terms of the GNU General Public License, version 2.0 | ||
9 | * ("GPL"), unless you have obtained a separate licensing agreement | ||
10 | * ("Other License"), formally executed by you and Linden Lab. Terms of | ||
11 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | ||
12 | * online at http://secondlife.com/developers/opensource/gplv2 | ||
13 | * | ||
14 | * There are special exceptions to the terms and conditions of the GPL as | ||
15 | * it is applied to this Source Code. View the full text of the exception | ||
16 | * in the file doc/FLOSS-exception.txt in this software distribution, or | ||
17 | * online at http://secondlife.com/developers/opensource/flossexception | ||
18 | * | ||
19 | * By copying, modifying or distributing this software, you acknowledge | ||
20 | * that you have read and understood your obligations described above, | ||
21 | * and agree to abide by those obligations. | ||
22 | * | ||
23 | * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO | ||
24 | * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, | ||
25 | * COMPLETENESS OR PERFORMANCE. | ||
26 | */ | ||
27 | |||
28 | #include "llviewerprecompiledheaders.h" | ||
29 | |||
30 | #include "llhudeffectbeam.h" | ||
31 | #include "message.h" | ||
32 | |||
33 | #include "llviewerobjectlist.h" | ||
34 | |||
35 | #include "llagent.h" | ||
36 | #include "lldrawable.h" | ||
37 | #include "llfontgl.h" | ||
38 | #include "llgl.h" | ||
39 | #include "llglheaders.h" | ||
40 | #include "llhudrender.h" | ||
41 | #include "llimagegl.h" | ||
42 | #include "llsphere.h" | ||
43 | #include "llviewercamera.h" | ||
44 | #include "llvoavatar.h" | ||
45 | #include "llviewercontrol.h" | ||
46 | |||
47 | const F32 BEAM_SPACING = 0.075f; | ||
48 | |||
49 | LLHUDEffectBeam::LLHUDEffectBeam(const U8 type) : LLHUDEffect(type) | ||
50 | { | ||
51 | mKillTime = mDuration; | ||
52 | |||
53 | // Initialize all of these to defaults | ||
54 | S32 i; | ||
55 | for (i = 0; i < NUM_POINTS; i++) | ||
56 | { | ||
57 | mInterp[i].setStartTime(BEAM_SPACING*i); | ||
58 | mInterp[i].setEndTime(BEAM_SPACING*NUM_POINTS + BEAM_SPACING*i); | ||
59 | mInterp[i].start(); | ||
60 | mInterpFade[i].setStartTime(BEAM_SPACING*NUM_POINTS + BEAM_SPACING*i - 0.5f*NUM_POINTS*BEAM_SPACING); | ||
61 | mInterpFade[i].setEndTime(BEAM_SPACING*NUM_POINTS + BEAM_SPACING*i); | ||
62 | mInterpFade[i].setStartVal(1.f); | ||
63 | mInterpFade[i].setEndVal(0.f); | ||
64 | } | ||
65 | |||
66 | // Setup default timeouts and fade animations. | ||
67 | F32 fade_length; | ||
68 | fade_length = llmin(0.5f, mDuration); | ||
69 | mFadeInterp.setStartTime(mKillTime - fade_length); | ||
70 | mFadeInterp.setEndTime(mKillTime); | ||
71 | mFadeInterp.setStartVal(1.f); | ||
72 | mFadeInterp.setEndVal(0.f); | ||
73 | } | ||
74 | |||
75 | LLHUDEffectBeam::~LLHUDEffectBeam() | ||
76 | { | ||
77 | } | ||
78 | |||
79 | void LLHUDEffectBeam::packData(LLMessageSystem *mesgsys) | ||
80 | { | ||
81 | if (!mSourceObject) | ||
82 | { | ||
83 | llwarns << "Missing source object!" << llendl; | ||
84 | } | ||
85 | |||
86 | // Pack the default data | ||
87 | LLHUDEffect::packData(mesgsys); | ||
88 | |||
89 | // Pack the type-specific data. Uses a fun packed binary format. Whee! | ||
90 | // 16 + 24 + 1 = 41 | ||
91 | U8 packed_data[41]; | ||
92 | memset(packed_data, 0, 41); | ||
93 | if (mSourceObject) | ||
94 | { | ||
95 | htonmemcpy(packed_data, mSourceObject->mID.mData, MVT_LLUUID, 16); | ||
96 | } | ||
97 | |||
98 | if (mTargetObject) | ||
99 | { | ||
100 | packed_data[16] = 1; | ||
101 | } | ||
102 | else | ||
103 | { | ||
104 | packed_data[16] = 0; | ||
105 | } | ||
106 | |||
107 | if (mTargetObject) | ||
108 | { | ||
109 | htonmemcpy(&(packed_data[17]), mTargetObject->mID.mData, MVT_LLUUID, 16); | ||
110 | } | ||
111 | else | ||
112 | { | ||
113 | htonmemcpy(&(packed_data[17]), mTargetPos.mdV, MVT_LLVector3d, 24); | ||
114 | } | ||
115 | mesgsys->addBinaryDataFast(_PREHASH_TypeData, packed_data, 41); | ||
116 | } | ||
117 | |||
118 | void LLHUDEffectBeam::unpackData(LLMessageSystem *mesgsys, S32 blocknum) | ||
119 | { | ||
120 | llerrs << "Got beam!" << llendl; | ||
121 | BOOL use_target_object; | ||
122 | LLVector3d new_target; | ||
123 | U8 packed_data[41]; | ||
124 | |||
125 | LLHUDEffect::unpackData(mesgsys, blocknum); | ||
126 | LLUUID source_id; | ||
127 | LLUUID target_id; | ||
128 | S32 size = mesgsys->getSizeFast(_PREHASH_Effect, blocknum, _PREHASH_TypeData); | ||
129 | if (size != 41) | ||
130 | { | ||
131 | llwarns << "Beam effect with bad size " << size << llendl; | ||
132 | return; | ||
133 | } | ||
134 | mesgsys->getBinaryDataFast(_PREHASH_Effect, _PREHASH_TypeData, packed_data, 41, blocknum); | ||
135 | |||
136 | htonmemcpy(source_id.mData, packed_data, MVT_LLUUID, 16); | ||
137 | |||
138 | LLViewerObject *objp = gObjectList.findObject(source_id); | ||
139 | if (objp) | ||
140 | { | ||
141 | setSourceObject(objp); | ||
142 | } | ||
143 | |||
144 | use_target_object = packed_data[16]; | ||
145 | |||
146 | if (use_target_object) | ||
147 | { | ||
148 | htonmemcpy(target_id.mData, &packed_data[17], MVT_LLUUID, 16); | ||
149 | |||
150 | LLViewerObject *objp = gObjectList.findObject(target_id); | ||
151 | if (objp) | ||
152 | { | ||
153 | setTargetObject(objp); | ||
154 | } | ||
155 | } | ||
156 | else | ||
157 | { | ||
158 | htonmemcpy(new_target.mdV, &(packed_data[17]), MVT_LLVector3d, 24); | ||
159 | setTargetPos(new_target); | ||
160 | } | ||
161 | |||
162 | // We've received an update for the effect, update the various timeouts | ||
163 | // and fade animations. | ||
164 | mKillTime = mTimer.getElapsedTimeF32() + mDuration; | ||
165 | F32 fade_length; | ||
166 | fade_length = llmin(0.5f, mDuration); | ||
167 | mFadeInterp.setStartTime(mKillTime - fade_length); | ||
168 | mFadeInterp.setEndTime(mKillTime); | ||
169 | mFadeInterp.setStartVal(1.f); | ||
170 | mFadeInterp.setEndVal(0.f); | ||
171 | } | ||
172 | |||
173 | void LLHUDEffectBeam::setSourceObject(LLViewerObject *objp) | ||
174 | { | ||
175 | if (objp->isDead()) | ||
176 | { | ||
177 | llwarns << "HUDEffectBeam: Source object is dead!" << llendl; | ||
178 | mSourceObject = NULL; | ||
179 | return; | ||
180 | } | ||
181 | |||
182 | if (mSourceObject == objp) | ||
183 | { | ||
184 | return; | ||
185 | } | ||
186 | |||
187 | mSourceObject = objp; | ||
188 | if (mSourceObject) | ||
189 | { | ||
190 | S32 i; | ||
191 | for (i = 0; i < NUM_POINTS; i++) | ||
192 | { | ||
193 | if (mSourceObject->isAvatar()) | ||
194 | { | ||
195 | LLViewerObject *objp = mSourceObject; | ||
196 | LLVOAvatar *avatarp = (LLVOAvatar *)objp; | ||
197 | LLVector3d hand_pos_global = gAgent.getPosGlobalFromAgent(avatarp->mWristLeftp->getWorldPosition()); | ||
198 | mInterp[i].setStartVal(hand_pos_global); | ||
199 | mInterp[i].start(); | ||
200 | } | ||
201 | else | ||
202 | { | ||
203 | mInterp[i].setStartVal(mSourceObject->getPositionGlobal()); | ||
204 | mInterp[i].start(); | ||
205 | } | ||
206 | } | ||
207 | } | ||
208 | } | ||
209 | |||
210 | |||
211 | void LLHUDEffectBeam::setTargetObject(LLViewerObject *objp) | ||
212 | { | ||
213 | if (mTargetObject->isDead()) | ||
214 | { | ||
215 | llwarns << "HUDEffectBeam: Target object is dead!" << llendl; | ||
216 | } | ||
217 | |||
218 | mTargetObject = objp; | ||
219 | } | ||
220 | |||
221 | void LLHUDEffectBeam::setTargetPos(const LLVector3d &pos_global) | ||
222 | { | ||
223 | mTargetPos = pos_global; | ||
224 | mTargetObject = NULL; | ||
225 | } | ||
226 | |||
227 | void LLHUDEffectBeam::render() | ||
228 | { | ||
229 | if (!mSourceObject) | ||
230 | { | ||
231 | markDead(); | ||
232 | return; | ||
233 | } | ||
234 | if (mSourceObject->isDead()) | ||
235 | { | ||
236 | markDead(); | ||
237 | return; | ||
238 | } | ||
239 | |||
240 | F32 time = mTimer.getElapsedTimeF32(); | ||
241 | |||
242 | // Kill us if our time is over... | ||
243 | if (mKillTime < time) | ||
244 | { | ||
245 | markDead(); | ||
246 | return; | ||
247 | } | ||
248 | |||
249 | LLGLSPipelineAlpha gls_pipeline_alpha; | ||
250 | LLImageGL::unbindTexture(0, GL_TEXTURE_2D); | ||
251 | |||
252 | |||
253 | // Interpolate the global fade alpha | ||
254 | mFadeInterp.update(time); | ||
255 | |||
256 | if (mTargetObject.notNull() && mTargetObject->mDrawable.notNull()) | ||
257 | { | ||
258 | // use viewer object position on freshly created objects | ||
259 | if (mTargetObject->mDrawable->getGeneration() == -1) | ||
260 | { | ||
261 | mTargetPos = mTargetObject->getPositionGlobal(); | ||
262 | } | ||
263 | // otherwise use drawable | ||
264 | else | ||
265 | { | ||
266 | mTargetPos = gAgent.getPosGlobalFromAgent(mTargetObject->mDrawable->getPositionAgent()); | ||
267 | } | ||
268 | } | ||
269 | |||
270 | |||
271 | // Init the color of the particles | ||
272 | LLColor4U coloru = mColor; | ||
273 | |||
274 | /* | ||
275 | // This is disabled for now - DJS | ||
276 | |||
277 | // Fade the alpha | ||
278 | coloru.mV[3] = mFadeInterp.getCurVal()*mColor.mV[3]; | ||
279 | |||
280 | // Draw a regular "beam" that connects the source and target | ||
281 | |||
282 | // First, figure out start and end positions relative to the camera | ||
283 | LLVector3 start_pos_agent; | ||
284 | if (mSourceObject->getPCode() == LL_PCODE_LEGACY_AVATAR) | ||
285 | { | ||
286 | LLViewerObject *objp = mSourceObject; | ||
287 | LLVOAvatar *avatarp = (LLVOAvatar *)objp; | ||
288 | LLVector3d hand_pos_global = gAgent.getPosGlobalFromAgent(avatarp->mWristLeftp->getWorldPosition()); | ||
289 | start_pos_agent = gAgent.getPosAgentFromGlobal(hand_pos_global); | ||
290 | } | ||
291 | else | ||
292 | { | ||
293 | start_pos_agent = mSourceObject->getPositionAgent(); | ||
294 | } | ||
295 | LLVector3 start_pos_camera = (start_pos_agent - gAgent.getCameraPositionAgent()); | ||
296 | LLVector3 target_pos_agent = gAgent.getPosAgentFromGlobal(mTargetPos); | ||
297 | LLVector3 target_pos_camera = target_pos_agent - gAgent.getCameraPositionAgent(); | ||
298 | |||
299 | // Generate the right "up" vector which is perpendicular to the beam, make it 1/10 meter wide, going to a point. | ||
300 | LLVector3 camera_up = gCamera->getUpAxis(); | ||
301 | LLVector3 camera_at = gCamera->getAtAxis(); | ||
302 | LLVector3 up = target_pos_camera % start_pos_camera; | ||
303 | up.normVec(); | ||
304 | up *= 0.1f; | ||
305 | |||
306 | // Draw the triangle for the beam. | ||
307 | LLVector3 vertex; | ||
308 | glColor4ubv(coloru.mV); | ||
309 | glBegin(GL_TRIANGLE_STRIP); | ||
310 | vertex = start_pos_agent + up; | ||
311 | glVertex3fv(vertex.mV); | ||
312 | vertex = start_pos_agent - up; | ||
313 | glVertex3fv(vertex.mV); | ||
314 | vertex = target_pos_agent; | ||
315 | glVertex3fv(vertex.mV); | ||
316 | glEnd(); | ||
317 | */ | ||
318 | |||
319 | // Draw the particles | ||
320 | S32 i; | ||
321 | for (i = 0; i < NUM_POINTS; i++) | ||
322 | { | ||
323 | mInterp[i].update(time); | ||
324 | if (!mInterp[i].isActive()) | ||
325 | { | ||
326 | continue; | ||
327 | } | ||
328 | mInterpFade[i].update(time); | ||
329 | |||
330 | if (mInterp[i].isDone()) | ||
331 | { | ||
332 | // Reinitialize the particle when the particle has finished its animation. | ||
333 | setupParticle(i); | ||
334 | } | ||
335 | |||
336 | F32 frac = mInterp[i].getCurFrac(); | ||
337 | F32 scale = 0.025f + fabs(0.05f*sin(2.f*F_PI*(frac - time))); | ||
338 | scale *= mInterpFade[i].getCurVal(); | ||
339 | |||
340 | LLVector3 pos_agent = gAgent.getPosAgentFromGlobal(mInterp[i].getCurVal()); | ||
341 | |||
342 | F32 alpha = mFadeInterp.getCurVal()*mColor.mV[3]; | ||
343 | alpha *= mInterpFade[i].getCurVal(); | ||
344 | coloru.mV[3] = (U8)alpha; | ||
345 | glColor4ubv(coloru.mV); | ||
346 | |||
347 | glPushMatrix(); | ||
348 | glTranslatef(pos_agent.mV[0], pos_agent.mV[1], pos_agent.mV[2]); | ||
349 | glScalef(scale, scale, scale); | ||
350 | gSphere.render(0); | ||
351 | glPopMatrix(); | ||
352 | } | ||
353 | } | ||
354 | |||
355 | void LLHUDEffectBeam::setupParticle(const S32 i) | ||
356 | { | ||
357 | LLVector3d start_pos_global; | ||
358 | if (mSourceObject->getPCode() == LL_PCODE_LEGACY_AVATAR) | ||
359 | { | ||
360 | LLViewerObject *objp = mSourceObject; | ||
361 | LLVOAvatar *avatarp = (LLVOAvatar *)objp; | ||
362 | start_pos_global = gAgent.getPosGlobalFromAgent(avatarp->mWristLeftp->getWorldPosition()); | ||
363 | } | ||
364 | else | ||
365 | { | ||
366 | start_pos_global = mSourceObject->getPositionGlobal(); | ||
367 | } | ||
368 | |||
369 | // Generate a random offset for the target point. | ||
370 | const F32 SCALE = 0.5f; | ||
371 | F32 x, y, z; | ||
372 | x = frand(SCALE) - 0.5f*SCALE; | ||
373 | y = frand(SCALE) - 0.5f*SCALE; | ||
374 | z = frand(SCALE) - 0.5f*SCALE; | ||
375 | |||
376 | LLVector3d target_pos_global(mTargetPos); | ||
377 | target_pos_global += LLVector3d(x, y, z); | ||
378 | |||
379 | mInterp[i].setStartTime(mInterp[i].getEndTime()); | ||
380 | mInterp[i].setEndTime(mInterp[i].getStartTime() + BEAM_SPACING*NUM_POINTS); | ||
381 | mInterp[i].setStartVal(start_pos_global); | ||
382 | mInterp[i].setEndVal(target_pos_global); | ||
383 | mInterp[i].start(); | ||
384 | |||
385 | |||
386 | // Setup the interpolator that fades out the alpha. | ||
387 | mInterpFade[i].setStartTime(mInterp[i].getStartTime() + BEAM_SPACING*NUM_POINTS - 0.5f*NUM_POINTS*BEAM_SPACING); | ||
388 | mInterpFade[i].setEndTime(mInterp[i].getStartTime() + BEAM_SPACING*NUM_POINTS - 0.05f); | ||
389 | mInterpFade[i].start(); | ||
390 | } | ||