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/lltoolfocus.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/lltoolfocus.cpp')
-rw-r--r-- | linden/indra/newview/lltoolfocus.cpp | 461 |
1 files changed, 461 insertions, 0 deletions
diff --git a/linden/indra/newview/lltoolfocus.cpp b/linden/indra/newview/lltoolfocus.cpp new file mode 100644 index 0000000..e57f5fb --- /dev/null +++ b/linden/indra/newview/lltoolfocus.cpp | |||
@@ -0,0 +1,461 @@ | |||
1 | /** | ||
2 | * @file lltoolfocus.cpp | ||
3 | * @brief A tool to set the build focus point. | ||
4 | * | ||
5 | * Copyright (c) 2001-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 | // File includes | ||
31 | #include "lltoolfocus.h" | ||
32 | |||
33 | // Library includes | ||
34 | #include "v3math.h" | ||
35 | #include "llfontgl.h" | ||
36 | #include "llui.h" | ||
37 | |||
38 | // Viewer includes | ||
39 | #include "llagent.h" | ||
40 | #include "llbutton.h" | ||
41 | #include "llviewercontrol.h" | ||
42 | #include "lldrawable.h" | ||
43 | #include "llhoverview.h" | ||
44 | #include "llhudmanager.h" | ||
45 | #include "llfloatertools.h" | ||
46 | #include "llselectmgr.h" | ||
47 | #include "llstatusbar.h" | ||
48 | #include "lltoolmgr.h" | ||
49 | #include "lltoolselect.h" | ||
50 | #include "llviewborder.h" | ||
51 | #include "llviewercamera.h" | ||
52 | #include "llviewerobject.h" | ||
53 | #include "llviewerwindow.h" | ||
54 | #include "viewer.h" | ||
55 | #include "llvoavatar.h" | ||
56 | #include "llmorphview.h" | ||
57 | |||
58 | // Globals | ||
59 | LLToolCamera *gToolCamera = NULL; | ||
60 | BOOL gCameraBtnOrbit = FALSE; | ||
61 | BOOL gCameraBtnPan = FALSE; | ||
62 | const S32 SLOP_RANGE = 4; | ||
63 | const F32 FOCUS_OFFSET_FACTOR = 1.f; | ||
64 | |||
65 | extern void handle_first_tool(void*); | ||
66 | |||
67 | |||
68 | // | ||
69 | // Camera - shared functionality | ||
70 | // | ||
71 | |||
72 | LLToolCamera::LLToolCamera() | ||
73 | : LLTool("Camera"), | ||
74 | mAccumX(0), | ||
75 | mAccumY(0), | ||
76 | mMouseDownX(0), | ||
77 | mMouseDownY(0), | ||
78 | mOutsideSlopX(FALSE), | ||
79 | mOutsideSlopY(FALSE), | ||
80 | mValidClickPoint(FALSE), | ||
81 | mMouseSteering(FALSE), | ||
82 | mMouseUpX(0), | ||
83 | mMouseUpY(0), | ||
84 | mMouseUpMask(MASK_NONE) | ||
85 | { } | ||
86 | |||
87 | |||
88 | LLToolCamera::~LLToolCamera() | ||
89 | { } | ||
90 | |||
91 | // virtual | ||
92 | void LLToolCamera::handleSelect() | ||
93 | { | ||
94 | gFloaterTools->setStatusText("Click and drag to change view"); | ||
95 | } | ||
96 | |||
97 | // virtual | ||
98 | void LLToolCamera::handleDeselect() | ||
99 | { | ||
100 | gFloaterTools->setStatusText(""); | ||
101 | // gAgent.setLookingAtAvatar(FALSE); | ||
102 | } | ||
103 | |||
104 | BOOL LLToolCamera::handleMouseDown(S32 x, S32 y, MASK mask) | ||
105 | { | ||
106 | // Ensure a mouseup | ||
107 | setMouseCapture(TRUE); | ||
108 | |||
109 | // call the base class to propogate info to sim | ||
110 | LLTool::handleMouseDown(x, y, mask); | ||
111 | |||
112 | mAccumX = 0; | ||
113 | mAccumY = 0; | ||
114 | |||
115 | mOutsideSlopX = FALSE; | ||
116 | mOutsideSlopY = FALSE; | ||
117 | |||
118 | mValidClickPoint = FALSE; | ||
119 | |||
120 | // If mouse capture gets ripped away, claim we moused up | ||
121 | // at the point we moused down. JC | ||
122 | mMouseUpX = x; | ||
123 | mMouseUpY = y; | ||
124 | mMouseUpMask = mask; | ||
125 | |||
126 | gViewerWindow->hideCursor(); | ||
127 | |||
128 | gViewerWindow->hitObjectOrLandGlobalAsync(x, y, mask, pickCallback); | ||
129 | // don't steal focus from UI | ||
130 | return FALSE; | ||
131 | } | ||
132 | |||
133 | void LLToolCamera::pickCallback(S32 x, S32 y, MASK mask) | ||
134 | { | ||
135 | if (!gToolCamera->hasMouseCapture()) | ||
136 | { | ||
137 | return; | ||
138 | } | ||
139 | |||
140 | gToolCamera->mMouseDownX = x; | ||
141 | gToolCamera->mMouseDownY = y; | ||
142 | |||
143 | gViewerWindow->moveCursorToCenter(); | ||
144 | |||
145 | // Potentially recenter if click outside rectangle | ||
146 | LLViewerObject* hit_obj = gViewerWindow->lastObjectHit(); | ||
147 | |||
148 | // Check for hit the sky, or some other invalid point | ||
149 | if (!hit_obj && gLastHitPosGlobal.isExactlyZero()) | ||
150 | { | ||
151 | gToolCamera->mValidClickPoint = FALSE; | ||
152 | return; | ||
153 | } | ||
154 | |||
155 | // check for hud attachments | ||
156 | if (hit_obj && hit_obj->isHUDAttachment()) | ||
157 | { | ||
158 | if (!gSelectMgr->getObjectCount() || gSelectMgr->getSelectType() != SELECT_TYPE_HUD) | ||
159 | { | ||
160 | gToolCamera->mValidClickPoint = FALSE; | ||
161 | return; | ||
162 | } | ||
163 | } | ||
164 | |||
165 | if( CAMERA_MODE_CUSTOMIZE_AVATAR == gAgent.getCameraMode() ) | ||
166 | { | ||
167 | BOOL good_customize_avatar_hit = FALSE; | ||
168 | if( hit_obj ) | ||
169 | { | ||
170 | LLVOAvatar* avatar = gAgent.getAvatarObject(); | ||
171 | if( hit_obj == avatar) | ||
172 | { | ||
173 | // It's you | ||
174 | good_customize_avatar_hit = TRUE; | ||
175 | } | ||
176 | else | ||
177 | if( hit_obj->isAttachment() && hit_obj->permYouOwner() ) | ||
178 | { | ||
179 | // It's an attachment that you're wearing | ||
180 | good_customize_avatar_hit = TRUE; | ||
181 | } | ||
182 | } | ||
183 | |||
184 | if( !good_customize_avatar_hit ) | ||
185 | { | ||
186 | gToolCamera->mValidClickPoint = FALSE; | ||
187 | return; | ||
188 | } | ||
189 | |||
190 | if( gMorphView ) | ||
191 | { | ||
192 | gMorphView->setCameraDrivenByKeys( FALSE ); | ||
193 | } | ||
194 | } | ||
195 | //RN: check to see if this is mouse-driving as opposed to ALT-zoom or Focus tool | ||
196 | else if (mask & MASK_ALT || | ||
197 | (gToolMgr->getCurrentTool(mask)->getName() == "Camera")) | ||
198 | { | ||
199 | LLViewerObject* hit_obj = gViewerWindow->lastObjectHit(); | ||
200 | if (hit_obj) | ||
201 | { | ||
202 | // ...clicked on a world object, so focus at its position | ||
203 | // Use "gLastHitPosGlobal" because it's correct for avatar heads, | ||
204 | // not pelvis. | ||
205 | if (!hit_obj->isHUDAttachment()) | ||
206 | { | ||
207 | gAgent.setFocusOnAvatar(FALSE, ANIMATE); | ||
208 | gAgent.setFocusGlobal( gLastHitObjectOffset + gLastHitPosGlobal, gLastHitObjectID); | ||
209 | } | ||
210 | } | ||
211 | else if (!gLastHitPosGlobal.isExactlyZero()) | ||
212 | { | ||
213 | // Hit the ground | ||
214 | gAgent.setFocusOnAvatar(FALSE, ANIMATE); | ||
215 | gAgent.setFocusGlobal( gLastHitPosGlobal, gLastHitObjectID); | ||
216 | } | ||
217 | |||
218 | if (!(mask & MASK_ALT) && | ||
219 | gAgent.cameraThirdPerson() && | ||
220 | gViewerWindow->getLeftMouseDown() && | ||
221 | !gSavedSettings.getBOOL("FreezeTime") && | ||
222 | (hit_obj == gAgent.getAvatarObject() || | ||
223 | (hit_obj && hit_obj->isAttachment() && LLVOAvatar::findAvatarFromAttachment(hit_obj)->mIsSelf))) | ||
224 | { | ||
225 | gToolCamera->mMouseSteering = TRUE; | ||
226 | } | ||
227 | |||
228 | } | ||
229 | |||
230 | gToolCamera->mValidClickPoint = TRUE; | ||
231 | |||
232 | if( CAMERA_MODE_CUSTOMIZE_AVATAR == gAgent.getCameraMode() ) | ||
233 | { | ||
234 | gAgent.setFocusOnAvatar(FALSE, FALSE); | ||
235 | |||
236 | LLVector3d cam_pos = gAgent.getCameraPositionGlobal(); | ||
237 | cam_pos -= LLVector3d(gCamera->getLeftAxis() * gAgent.calcCustomizeAvatarUIOffset( cam_pos )); | ||
238 | |||
239 | gAgent.setCameraPosAndFocusGlobal( cam_pos, gLastHitObjectOffset + gLastHitPosGlobal, gLastHitObjectID); | ||
240 | } | ||
241 | } | ||
242 | |||
243 | |||
244 | // "Let go" of the mouse, for example on mouse up or when | ||
245 | // we lose mouse capture. This ensures that cursor becomes visible | ||
246 | // if a modal dialog pops up during Alt-Zoom. JC | ||
247 | void LLToolCamera::releaseMouse() | ||
248 | { | ||
249 | // Need to tell the sim that the mouse button is up, since this | ||
250 | // tool is no longer working and cursor is visible (despite actual | ||
251 | // mouse button status). | ||
252 | LLTool::handleMouseUp(mMouseUpX, mMouseUpY, mMouseUpMask); | ||
253 | |||
254 | gViewerWindow->showCursor(); | ||
255 | |||
256 | gToolMgr->clearTransientTool(); | ||
257 | |||
258 | mMouseSteering = FALSE; | ||
259 | mValidClickPoint = FALSE; | ||
260 | mOutsideSlopX = FALSE; | ||
261 | mOutsideSlopY = FALSE; | ||
262 | } | ||
263 | |||
264 | |||
265 | BOOL LLToolCamera::handleMouseUp(S32 x, S32 y, MASK mask) | ||
266 | { | ||
267 | // Claim that we're mousing up somewhere | ||
268 | mMouseUpX = x; | ||
269 | mMouseUpY = y; | ||
270 | mMouseUpMask = mask; | ||
271 | |||
272 | if (hasMouseCapture()) | ||
273 | { | ||
274 | if (mValidClickPoint) | ||
275 | { | ||
276 | if( CAMERA_MODE_CUSTOMIZE_AVATAR == gAgent.getCameraMode() ) | ||
277 | { | ||
278 | LLCoordGL mouse_pos; | ||
279 | LLVector3 focus_pos = gAgent.getPosAgentFromGlobal(gAgent.getFocusGlobal()); | ||
280 | gCamera->projectPosAgentToScreen(focus_pos, mouse_pos); | ||
281 | |||
282 | LLUI::setCursorPositionScreen(mouse_pos.mX, mouse_pos.mY); | ||
283 | } | ||
284 | else if (mMouseSteering) | ||
285 | { | ||
286 | LLUI::setCursorPositionScreen(mMouseDownX, mMouseDownY); | ||
287 | } | ||
288 | else | ||
289 | { | ||
290 | gViewerWindow->moveCursorToCenter(); | ||
291 | } | ||
292 | } | ||
293 | else | ||
294 | { | ||
295 | // not a valid zoomable object | ||
296 | LLUI::setCursorPositionScreen(mMouseDownX, mMouseDownY); | ||
297 | } | ||
298 | |||
299 | // calls releaseMouse() internally | ||
300 | setMouseCapture(FALSE); | ||
301 | } | ||
302 | else | ||
303 | { | ||
304 | releaseMouse(); | ||
305 | } | ||
306 | |||
307 | return TRUE; | ||
308 | } | ||
309 | |||
310 | |||
311 | BOOL LLToolCamera::handleHover(S32 x, S32 y, MASK mask) | ||
312 | { | ||
313 | S32 dx = gViewerWindow->getCurrentMouseDX(); | ||
314 | S32 dy = gViewerWindow->getCurrentMouseDY(); | ||
315 | |||
316 | BOOL moved_outside_slop = FALSE; | ||
317 | |||
318 | if (hasMouseCapture() && mValidClickPoint) | ||
319 | { | ||
320 | mAccumX += llabs(dx); | ||
321 | mAccumY += llabs(dy); | ||
322 | |||
323 | if (mAccumX >= SLOP_RANGE) | ||
324 | { | ||
325 | if (!mOutsideSlopX) | ||
326 | { | ||
327 | moved_outside_slop = TRUE; | ||
328 | } | ||
329 | mOutsideSlopX = TRUE; | ||
330 | } | ||
331 | |||
332 | if (mAccumY >= SLOP_RANGE) | ||
333 | { | ||
334 | if (!mOutsideSlopY) | ||
335 | { | ||
336 | moved_outside_slop = TRUE; | ||
337 | } | ||
338 | mOutsideSlopY = TRUE; | ||
339 | } | ||
340 | } | ||
341 | |||
342 | if (mOutsideSlopX || mOutsideSlopY) | ||
343 | { | ||
344 | if (!mValidClickPoint) | ||
345 | { | ||
346 | lldebugst(LLERR_USER_INPUT) << "hover handled by LLToolFocus [invalid point]" << llendl; | ||
347 | gViewerWindow->setCursor(UI_CURSOR_NO); | ||
348 | gViewerWindow->showCursor(); | ||
349 | return TRUE; | ||
350 | } | ||
351 | |||
352 | if (gCameraBtnOrbit || | ||
353 | mask == MASK_ORBIT || | ||
354 | mask == (MASK_ALT | MASK_ORBIT)) | ||
355 | { | ||
356 | // Orbit tool | ||
357 | if (hasMouseCapture()) | ||
358 | { | ||
359 | const F32 RADIANS_PER_PIXEL = 360.f * DEG_TO_RAD / gViewerWindow->getWindowWidth(); | ||
360 | |||
361 | if (dx != 0) | ||
362 | { | ||
363 | gAgent.cameraOrbitAround( -dx * RADIANS_PER_PIXEL ); | ||
364 | } | ||
365 | |||
366 | if (dy != 0) | ||
367 | { | ||
368 | gAgent.cameraOrbitOver( -dy * RADIANS_PER_PIXEL ); | ||
369 | } | ||
370 | |||
371 | gViewerWindow->moveCursorToCenter(); | ||
372 | } | ||
373 | lldebugst(LLERR_USER_INPUT) << "hover handled by LLToolFocus [active]" << llendl; | ||
374 | } | ||
375 | else if ( gCameraBtnPan || | ||
376 | mask == MASK_PAN || | ||
377 | mask == (MASK_PAN | MASK_ALT) ) | ||
378 | { | ||
379 | // Pan tool | ||
380 | if (hasMouseCapture()) | ||
381 | { | ||
382 | LLVector3d camera_to_focus = gAgent.getCameraPositionGlobal(); | ||
383 | camera_to_focus -= gAgent.getFocusGlobal(); | ||
384 | F32 dist = (F32) camera_to_focus.normVec(); | ||
385 | |||
386 | // Fudge factor for pan | ||
387 | F32 meters_per_pixel = 3.f * dist / gViewerWindow->getWindowWidth(); | ||
388 | |||
389 | if (dx != 0) | ||
390 | { | ||
391 | gAgent.cameraPanLeft( dx * meters_per_pixel ); | ||
392 | } | ||
393 | |||
394 | if (dy != 0) | ||
395 | { | ||
396 | gAgent.cameraPanUp( -dy * meters_per_pixel ); | ||
397 | } | ||
398 | |||
399 | gViewerWindow->moveCursorToCenter(); | ||
400 | } | ||
401 | lldebugst(LLERR_USER_INPUT) << "hover handled by LLToolPan" << llendl; | ||
402 | } | ||
403 | else | ||
404 | { | ||
405 | // Zoom tool | ||
406 | if (hasMouseCapture()) | ||
407 | { | ||
408 | |||
409 | const F32 RADIANS_PER_PIXEL = 360.f * DEG_TO_RAD / gViewerWindow->getWindowWidth(); | ||
410 | |||
411 | if (dx != 0) | ||
412 | { | ||
413 | gAgent.cameraOrbitAround( -dx * RADIANS_PER_PIXEL ); | ||
414 | } | ||
415 | |||
416 | const F32 IN_FACTOR = 0.99f; | ||
417 | |||
418 | if (dy != 0 && mOutsideSlopY ) | ||
419 | { | ||
420 | if (mMouseSteering) | ||
421 | { | ||
422 | gAgent.cameraOrbitOver( -dy * RADIANS_PER_PIXEL ); | ||
423 | } | ||
424 | else | ||
425 | { | ||
426 | gAgent.cameraZoomIn( pow( IN_FACTOR, dy ) ); | ||
427 | } | ||
428 | } | ||
429 | |||
430 | gViewerWindow->moveCursorToCenter(); | ||
431 | } | ||
432 | |||
433 | lldebugst(LLERR_USER_INPUT) << "hover handled by LLToolZoom" << llendl; | ||
434 | } | ||
435 | } | ||
436 | |||
437 | if (gCameraBtnOrbit || | ||
438 | mask == MASK_ORBIT || | ||
439 | mask == (MASK_ALT | MASK_ORBIT)) | ||
440 | { | ||
441 | gViewerWindow->setCursor(UI_CURSOR_TOOLCAMERA); | ||
442 | } | ||
443 | else if ( gCameraBtnPan || | ||
444 | mask == MASK_PAN || | ||
445 | mask == (MASK_PAN | MASK_ALT) ) | ||
446 | { | ||
447 | gViewerWindow->setCursor(UI_CURSOR_TOOLPAN); | ||
448 | } | ||
449 | else | ||
450 | { | ||
451 | gViewerWindow->setCursor(UI_CURSOR_TOOLZOOMIN); | ||
452 | } | ||
453 | |||
454 | return TRUE; | ||
455 | } | ||
456 | |||
457 | |||
458 | void LLToolCamera::onMouseCaptureLost() | ||
459 | { | ||
460 | releaseMouse(); | ||
461 | } | ||