summaryrefslogtreecommitdiff
path: root/indra/newview/llagentcamera.h
blob: d27cdb0c5ca03e54c163f69f0dc1de15da6de763 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
/** 
 * @file llagent.h
 * @brief LLAgent class header file
 *
 * $LicenseInfo:firstyear=2000&license=viewerlgpl$
 * Second Life Viewer Source Code
 * Copyright (C) 2010, Linden Research, Inc.
 * 
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation;
 * version 2.1 of the License only.
 * 
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 * 
 * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 * $/LicenseInfo$
 */

#ifndef LL_LLAGENTCAMERA_H
#define LL_LLAGENTCAMERA_H

#include "llfollowcam.h" 			// Ventrella
#include "llhudeffectlookat.h" 		// EPointAtType
#include "llhudeffectpointat.h" 	// ELookAtType

class LLPickInfo;
class LLVOAvatarSelf;
class LLControlVariable;

//--------------------------------------------------------------------
// Types
//--------------------------------------------------------------------
enum ECameraMode
{
	CAMERA_MODE_THIRD_PERSON,
	CAMERA_MODE_MOUSELOOK,
	CAMERA_MODE_CUSTOMIZE_AVATAR,
	CAMERA_MODE_FOLLOW
};

/** Camera Presets for CAMERA_MODE_THIRD_PERSON */
enum ECameraPreset 
{
	/** Default preset, what the Third Person Mode actually was */
	CAMERA_PRESET_REAR_VIEW,
	
	/** "Looking at the Avatar from the front" */
	CAMERA_PRESET_FRONT_VIEW, 

	/** "Above and to the left, over the shoulder, pulled back a little on the zoom" */
	CAMERA_PRESET_GROUP_VIEW,

	/** Current view when a preset is saved */
	CAMERA_PRESET_CUSTOM
};

//------------------------------------------------------------------------
// LLAgentCamera
//------------------------------------------------------------------------
class LLAgentCamera
{
	LOG_CLASS(LLAgentCamera);

public:
	//--------------------------------------------------------------------
	// Constructors / Destructors
	//--------------------------------------------------------------------
public:
	LLAgentCamera();
	virtual 		~LLAgentCamera();
	void			init();
	void			cleanup();
	void		    setAvatarObject(LLVOAvatarSelf* avatar);
	bool			isInitialized() { return mInitialized; }
private:
	bool			mInitialized;


	//--------------------------------------------------------------------
	// Mode
	//--------------------------------------------------------------------
public:
	void			changeCameraToDefault();
	void			changeCameraToMouselook(BOOL animate = TRUE);
	void			changeCameraToThirdPerson(BOOL animate = TRUE);
	void			changeCameraToCustomizeAvatar(); // Trigger transition animation
	void			changeCameraToFollow(BOOL animate = TRUE); 	// Ventrella
	BOOL			cameraThirdPerson() const		{ return (mCameraMode == CAMERA_MODE_THIRD_PERSON && mLastCameraMode == CAMERA_MODE_THIRD_PERSON); }
	BOOL			cameraMouselook() const			{ return (mCameraMode == CAMERA_MODE_MOUSELOOK && mLastCameraMode == CAMERA_MODE_MOUSELOOK); }
	BOOL			cameraCustomizeAvatar() const	{ return (mCameraMode == CAMERA_MODE_CUSTOMIZE_AVATAR /*&& !mCameraAnimating*/); }
	BOOL			cameraFollow() const			{ return (mCameraMode == CAMERA_MODE_FOLLOW && mLastCameraMode == CAMERA_MODE_FOLLOW); }
	ECameraMode		getCameraMode() const 			{ return mCameraMode; }
	ECameraMode		getLastCameraMode() const 		{ return mLastCameraMode; }
	void			updateCamera();					// Call once per frame to update camera location/orientation
	void			resetCamera(); 					// Slam camera into its default position
	void			updateLastCamera();				// Set last camera to current camera

private:
	ECameraMode		mCameraMode;					// Target mode after transition animation is done
	ECameraMode		mLastCameraMode;

	//--------------------------------------------------------------------
	// Preset
	//--------------------------------------------------------------------
public:
	void switchCameraPreset(ECameraPreset preset);
	/** Determines default camera offset depending on the current camera preset */
	LLVector3 getCameraOffsetInitial();
	/** Determines default focus offset depending on the current camera preset */
	LLVector3d getFocusOffsetInitial();

	LLVector3 getCurrentCameraOffset();
	LLVector3d getCurrentFocusOffset();
	LLQuaternion getCurrentAvatarRotation();
	bool isJoystickCameraUsed();
	void setInitSitRot(LLQuaternion sit_rot) { mInitSitRot = sit_rot; };
	void rotateToInitSitRot();

private:
	/** Determines maximum camera distance from target for mouselook, opposite to LAND_MIN_ZOOM */
	F32 getCameraMaxZoomDistance();

	/** Camera preset in Third Person Mode */
	ECameraPreset mCameraPreset; 

	LLQuaternion mInitSitRot;

	//--------------------------------------------------------------------
	// Position
	//--------------------------------------------------------------------
public:
	LLVector3d		getCameraPositionGlobal() const;
	const LLVector3 &getCameraPositionAgent() const;
	LLVector3d		calcCameraPositionTargetGlobal(BOOL *hit_limit = NULL); // Calculate the camera position target
	F32				getCameraMinOffGround(); 		// Minimum height off ground for this mode, meters
	void			setCameraCollidePlane(const LLVector4 &plane) { mCameraCollidePlane = plane; }
	BOOL			calcCameraMinDistance(F32 &obj_min_distance);
	F32				getCurrentCameraBuildOffset() 	{ return (F32)mCameraFocusOffset.length(); }
	void			clearCameraLag() { mCameraLag.clearVec(); }
private:
	LLVector3		getAvatarRootPosition();

	F32				mCurrentCameraDistance;	 		// Current camera offset from avatar
	F32				mTargetCameraDistance;			// Target camera offset from avatar
	F32				mCameraFOVZoomFactor;			// Amount of fov zoom applied to camera when zeroing in on an object
	F32				mCameraCurrentFOVZoomFactor;	// Interpolated fov zoom
	LLVector4		mCameraCollidePlane;			// Colliding plane for camera
	F32				mCameraZoomFraction;			// Mousewheel driven fraction of zoom
	LLVector3		mCameraPositionAgent;			// Camera position in agent coordinates
	LLVector3		mCameraVirtualPositionAgent;	// Camera virtual position (target) before performing FOV zoom
	LLVector3d      mCameraSmoothingLastPositionGlobal;    
	LLVector3d      mCameraSmoothingLastPositionAgent;
	bool            mCameraSmoothingStop;
	LLVector3		mCameraLag;						// Third person camera lag
	LLVector3		mCameraUpVector;				// Camera's up direction in world coordinates (determines the 'roll' of the view)

	//--------------------------------------------------------------------
	// Follow
	//--------------------------------------------------------------------
public:
	bool 			isfollowCamLocked();
private:
	LLFollowCam 	mFollowCam; 			// Ventrella

	//--------------------------------------------------------------------
	// Sit
	//--------------------------------------------------------------------
public:
	void			setupSitCamera();
	BOOL			sitCameraEnabled() 		{ return mSitCameraEnabled; }
	void			setSitCamera(const LLUUID &object_id, 
								 const LLVector3 &camera_pos = LLVector3::zero, const LLVector3 &camera_focus = LLVector3::zero);
private:
	LLPointer<LLViewerObject> mSitCameraReferenceObject; // Object to which camera is related when sitting
	BOOL			mSitCameraEnabled;		// Use provided camera information when sitting?
	LLVector3		mSitCameraPos;			// Root relative camera pos when sitting
	LLVector3		mSitCameraFocus;		// Root relative camera target when sitting

	//--------------------------------------------------------------------
	// Animation
	//--------------------------------------------------------------------
public:
	void			setCameraAnimating(BOOL b)			{ mCameraAnimating = b; }
	BOOL			getCameraAnimating()				{ return mCameraAnimating; }
	void			setAnimationDuration(F32 seconds);
	void			startCameraAnimation();
	void			stopCameraAnimation();
private:
	LLFrameTimer	mAnimationTimer; 	// Seconds that transition animation has been active
	F32				mAnimationDuration;	// In seconds
	BOOL			mCameraAnimating;					// Camera is transitioning from one mode to another
	LLVector3d		mAnimationCameraStartGlobal;		// Camera start position, global coords
	LLVector3d		mAnimationFocusStartGlobal;			// Camera focus point, global coords

	//--------------------------------------------------------------------
	// Focus
	//--------------------------------------------------------------------
public:
	LLVector3d		calcFocusPositionTargetGlobal();
	LLVector3		calcFocusOffset(LLViewerObject *object, LLVector3 pos_agent, S32 x, S32 y);
	BOOL			getFocusOnAvatar() const		{ return mFocusOnAvatar; }
	LLPointer<LLViewerObject>&	getFocusObject() 	{ return mFocusObject; }
	F32				getFocusObjectDist() const		{ return mFocusObjectDist; }
	void			updateFocusOffset();
	void			validateFocusObject();
	void			setFocusGlobal(const LLPickInfo& pick);
	void			setFocusGlobal(const LLVector3d &focus, const LLUUID &object_id = LLUUID::null);
	void			setFocusOnAvatar(BOOL focus, BOOL animate, BOOL reset_axes = TRUE);
	void			setCameraPosAndFocusGlobal(const LLVector3d& pos, const LLVector3d& focus, const LLUUID &object_id);
	void			clearFocusObject();
	void			setFocusObject(LLViewerObject* object);
	void			setAllowChangeToFollow(BOOL focus) 	{ mAllowChangeToFollow = focus; }
	void			setObjectTracking(BOOL track) 	{ mTrackFocusObject = track; }
	const LLVector3d &getFocusGlobal() const		{ return mFocusGlobal; }
	const LLVector3d &getFocusTargetGlobal() const	{ return mFocusTargetGlobal; }
private:
	LLVector3d		mCameraFocusOffset;				// Offset from focus point in build mode
	LLVector3d		mCameraFocusOffsetTarget;		// Target towards which we are lerping the camera's focus offset
	BOOL			mFocusOnAvatar;
	BOOL			mAllowChangeToFollow;
	LLVector3d		mFocusGlobal;
	LLVector3d		mFocusTargetGlobal;
	LLPointer<LLViewerObject> mFocusObject;
	F32				mFocusObjectDist;
	LLVector3		mFocusObjectOffset;
	BOOL			mTrackFocusObject;
	
	//--------------------------------------------------------------------
	// Lookat / Pointat
	//--------------------------------------------------------------------
public:
	void			updateLookAt(const S32 mouse_x, const S32 mouse_y);
	BOOL			setLookAt(ELookAtType target_type, LLViewerObject *object = NULL, LLVector3 position = LLVector3::zero);
	ELookAtType		getLookAtType();
	void			lookAtLastChat();
	void 			slamLookAt(const LLVector3 &look_at); // Set the physics data
	BOOL			setPointAt(EPointAtType target_type, LLViewerObject *object = NULL, LLVector3 position = LLVector3::zero);
	EPointAtType	getPointAtType();
public:
	LLPointer<LLHUDEffectLookAt> mLookAt;
	LLPointer<LLHUDEffectPointAt> mPointAt;

	//--------------------------------------------------------------------
	// Third person
	//--------------------------------------------------------------------
public:
	LLVector3d		calcThirdPersonFocusOffset();
	void			setThirdPersonHeadOffset(LLVector3 offset) 	{ mThirdPersonHeadOffset = offset; }	
private:
	LLVector3		mThirdPersonHeadOffset;						// Head offset for third person camera position

	//--------------------------------------------------------------------
	// Orbit
	//--------------------------------------------------------------------
public:
	void			cameraOrbitAround(const F32 radians);	// Rotate camera CCW radians about build focus point
	void			cameraOrbitOver(const F32 radians);		// Rotate camera forward radians over build focus point
	void			cameraOrbitIn(const F32 meters);		// Move camera in toward build focus point
	void			resetCameraOrbit();
	void			resetOrbitDiff();
	//--------------------------------------------------------------------
	// Zoom
	//--------------------------------------------------------------------
public:
	void			handleScrollWheel(S32 clicks); 							// Mousewheel driven zoom
	void			cameraZoomIn(const F32 factor);							// Zoom in by fraction of current distance
	F32				getCameraZoomFraction(bool get_third_person = false);	// Get camera zoom as fraction of minimum and maximum zoom
	void			setCameraZoomFraction(F32 fraction);					// Set camera zoom as fraction of minimum and maximum zoom
	F32				calcCameraFOVZoomFactor();
	F32				getAgentHUDTargetZoom();

	void			resetCameraZoomFraction();
	F32				getCurrentCameraZoomFraction() { return mCameraZoomFraction; }

	//--------------------------------------------------------------------
	// Pan
	//--------------------------------------------------------------------
public:
	void			cameraPanIn(const F32 meters);
	void			cameraPanLeft(const F32 meters);
	void			cameraPanUp(const F32 meters);	
	void			resetCameraPan();
	void			resetPanDiff();
	//--------------------------------------------------------------------
	// View
	//--------------------------------------------------------------------
public:
	// Called whenever the agent moves.  Puts camera back in default position, deselects items, etc.
	void			resetView(BOOL reset_camera = TRUE, BOOL change_camera = FALSE);
	// Called on camera movement.  Unlocks camera from the default position behind the avatar.
	void			unlockView();
public:
	F32				mDrawDistance;

	//--------------------------------------------------------------------
	// Mouselook
	//--------------------------------------------------------------------
public:
	BOOL			getForceMouselook() const 			{ return mForceMouselook; }
	void			setForceMouselook(BOOL mouselook) 	{ mForceMouselook = mouselook; }
private:
	BOOL			mForceMouselook;
	
	//--------------------------------------------------------------------
	// HUD
	//--------------------------------------------------------------------
public:
	F32				mHUDTargetZoom;	// Target zoom level for HUD objects (used when editing)
	F32				mHUDCurZoom; 	// Current animated zoom level for HUD objects


/********************************************************************************
 **                                                                            **
 **                    KEYS
 **/

public:
	S32				getAtKey() const		{ return mAtKey; }
	S32				getWalkKey() const		{ return mWalkKey; }
	S32				getLeftKey() const		{ return mLeftKey; }
	S32				getUpKey() const		{ return mUpKey; }
	F32				getYawKey() const		{ return mYawKey; }
	F32				getPitchKey() const		{ return mPitchKey; }

	void			setAtKey(S32 mag)		{ mAtKey = mag; }
	void			setWalkKey(S32 mag)		{ mWalkKey = mag; }
	void			setLeftKey(S32 mag)		{ mLeftKey = mag; }
	void			setUpKey(S32 mag)		{ mUpKey = mag; }
	void			setYawKey(F32 mag)		{ mYawKey = mag; }
	void			setPitchKey(F32 mag)	{ mPitchKey = mag; }

	void			clearGeneralKeys();
	static S32		directionToKey(S32 direction); // Changes direction to -1/0/1

private:
	S32 			mAtKey;				// Either 1, 0, or -1. Indicates that movement key is pressed
	S32				mWalkKey; 			// Like AtKey, but causes less forward thrust
	S32 			mLeftKey;
	S32				mUpKey;
	F32				mYawKey;
	F32				mPitchKey;

	//--------------------------------------------------------------------
	// Orbit
	//--------------------------------------------------------------------
public:
	F32				getOrbitLeftKey() const		{ return mOrbitLeftKey; }
	F32				getOrbitRightKey() const	{ return mOrbitRightKey; }
	F32				getOrbitUpKey() const		{ return mOrbitUpKey; }
	F32				getOrbitDownKey() const		{ return mOrbitDownKey; }
	F32				getOrbitInKey() const		{ return mOrbitInKey; }
	F32				getOrbitOutKey() const		{ return mOrbitOutKey; }

	void			setOrbitLeftKey(F32 mag)	{ mOrbitLeftKey = mag; }
	void			setOrbitRightKey(F32 mag)	{ mOrbitRightKey = mag; }
	void			setOrbitUpKey(F32 mag)		{ mOrbitUpKey = mag; }
	void			setOrbitDownKey(F32 mag)	{ mOrbitDownKey = mag; }
	void			setOrbitInKey(F32 mag)		{ mOrbitInKey = mag; }
	void			setOrbitOutKey(F32 mag)		{ mOrbitOutKey = mag; }

	void			clearOrbitKeys();
private:
	F32				mOrbitLeftKey;
	F32				mOrbitRightKey;
	F32				mOrbitUpKey;
	F32				mOrbitDownKey;
	F32				mOrbitInKey;
	F32				mOrbitOutKey;

	F32				mOrbitAroundRadians;
	F32				mOrbitOverAngle;

	//--------------------------------------------------------------------
	// Pan
	//--------------------------------------------------------------------
public:
	F32				getPanLeftKey() const		{ return mPanLeftKey; }
	F32				getPanRightKey() const	{ return mPanRightKey; }
	F32				getPanUpKey() const		{ return mPanUpKey; }
	F32				getPanDownKey() const		{ return mPanDownKey; }
	F32				getPanInKey() const		{ return mPanInKey; }
	F32				getPanOutKey() const		{ return mPanOutKey; }

	void			setPanLeftKey(F32 mag)		{ mPanLeftKey = mag; }
	void			setPanRightKey(F32 mag)		{ mPanRightKey = mag; }
	void			setPanUpKey(F32 mag)		{ mPanUpKey = mag; }
	void			setPanDownKey(F32 mag)		{ mPanDownKey = mag; }
	void			setPanInKey(F32 mag)		{ mPanInKey = mag; }
	void			setPanOutKey(F32 mag)		{ mPanOutKey = mag; }

	void			clearPanKeys();
private:
	F32				mPanUpKey;						
	F32				mPanDownKey;					
	F32				mPanLeftKey;					
	F32				mPanRightKey;					
	F32				mPanInKey;
	F32				mPanOutKey;

	LLVector3d		mPanFocusDiff;

/**                    Keys
 **                                                                            **
 *******************************************************************************/

};

extern LLAgentCamera gAgentCamera;

#endif