summaryrefslogtreecommitdiff
path: root/indra/newview/llfollowcam.h
blob: 20f3d45cbb4a104b81cea69253491aeed6587f62 (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
/**
 * @file llfollowcam.h
 * @author Jeffrey Ventrella
 * @brief LLFollowCam class definition
 *
 * $LicenseInfo:firstyear=2005&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$
 */

//--------------------------------------------------------------------
// FollowCam
//
// The FollowCam controls three dynamic variables which determine
// a camera orientation and position for a "loose" third-person view
// (orientation being derived from a combination of focus and up
// vector). It is good for fast-moving vehicles that change
// acceleration a lot, but it can also be general-purpose, like for
// avatar navigation. It has a handful of parameters allowing it to
// be tweaked to assume different styles of tracking objects.
//
//--------------------------------------------------------------------
#ifndef LL_FOLLOWCAM_H
#define LL_FOLLOWCAM_H

#include "llcoordframe.h"
#include "indra_constants.h"
#include "llmath.h"
#include "lltimer.h"
#include "llquaternion.h"
#include "llcriticaldamp.h"
#include <map>
#include <vector>

class LLFollowCamParams
{
public:
    LLFollowCamParams();
    virtual ~LLFollowCamParams();

    //--------------------------------------
    // setty setty set set
    //--------------------------------------
    virtual void setPositionLag         ( F32 );
    virtual void setFocusLag            ( F32 );
    virtual void setFocusThreshold      ( F32 );
    virtual void setPositionThreshold   ( F32 );
    virtual void setDistance            ( F32 );
    virtual void setPitch               ( F32 );
    virtual void setFocusOffset         ( const LLVector3& );
    virtual void setBehindnessAngle     ( F32 );
    virtual void setBehindnessLag       ( F32 );
    virtual void setPosition            ( const LLVector3& );
    virtual void setFocus               ( const LLVector3& );
    virtual void setPositionLocked      ( bool );
    virtual void setFocusLocked         ( bool );


    //--------------------------------------
    // getty getty get get
    //--------------------------------------
    virtual F32         getPositionLag() const;
    virtual F32         getFocusLag() const;
    virtual F32         getPositionThreshold() const;
    virtual F32         getFocusThreshold() const;
    virtual F32         getDistance() const;
    virtual F32         getPitch() const;
    virtual LLVector3   getFocusOffset() const;
    virtual F32         getBehindnessAngle() const;
    virtual F32         getBehindnessLag() const;
    virtual LLVector3   getPosition() const;
    virtual LLVector3   getFocus() const;
    virtual bool        getFocusLocked() const;
    virtual bool        getPositionLocked() const;
    virtual bool        getUseFocus() const { return mUseFocus; }
    virtual bool        getUsePosition() const { return mUsePosition; }

protected:
    F32     mPositionLag;
    F32     mFocusLag;
    F32     mFocusThreshold;
    F32     mPositionThreshold;
    F32     mDistance;
    F32     mPitch;
    LLVector3   mFocusOffset;
    F32     mBehindnessMaxAngle;
    F32     mBehindnessLag;
    F32     mMaxCameraDistantFromSubject;

    bool            mPositionLocked;
    bool            mFocusLocked;
    bool            mUsePosition; // specific camera point specified by script
    bool            mUseFocus; // specific focus point specified by script
    LLVector3       mPosition;          // where the camera is (in world-space)
    LLVector3       mFocus;             // what the camera is aimed at (in world-space)
};

class LLFollowCam : public LLFollowCamParams
{
public:
    //--------------------
    // Contructor
    //--------------------
    LLFollowCam();

    //--------------------
    // Destructor
    //--------------------
    virtual ~LLFollowCam();

    //---------------------------------------------------------------------------------------
    // The following methods must be called every time step. However, if you know for
    // sure that your  subject matter (what the camera is looking at) is not moving,
    // then you can get away with not calling "update" But keep in mind that "update"
    // may still be needed after the subject matter has stopped moving because the
    // camera may still need to animate itself catching up to its ideal resting place.
    //---------------------------------------------------------------------------------------
    void setSubjectPositionAndRotation  ( const LLVector3 p, const LLQuaternion r );
    void update();

    // initialize from another instance of llfollowcamparams
    void copyParams(LLFollowCamParams& params);

    //-----------------------------------------------------------------------------------
    // this is how to bang the followCam into a specific configuration. Keep in mind
    // that it will immediately try to adjust these values according to its attributes.
    //-----------------------------------------------------------------------------------
    void reset( const LLVector3 position, const LLVector3 focus, const LLVector3 upVector );

    void setMaxCameraDistantFromSubject ( F32 m ); // this should be determined by llAgent
    bool isZoomedToMinimumDistance();
    LLVector3   getUpVector();
    void zoom( S32 );

    // overrides for setters and getters
    virtual void setPitch( F32 );
    virtual void setDistance( F32 );
    virtual void setPosition(const LLVector3& pos);
    virtual void setFocus(const LLVector3& focus);
    virtual void setPositionLocked      ( bool );
    virtual void setFocusLocked         ( bool );

    LLVector3   getSimulatedPosition() const;
    LLVector3   getSimulatedFocus() const;

    //------------------------------------------
    // protected members of FollowCam
    //------------------------------------------
protected:
    F32     mPitchCos;                  // derived from mPitch
    F32     mPitchSin;                  // derived from mPitch
    LLGlobalVec     mSimulatedPositionGlobal;       // where the camera is (global coordinates), simulated
    LLGlobalVec     mSimulatedFocusGlobal;      // what the camera is aimed at (global coordinates), simulated
    F32             mSimulatedDistance;

    //---------------------
    // dynamic variables
    //---------------------
    bool            mZoomedToMinimumDistance;
    LLFrameTimer    mTimer;
    LLVector3       mSubjectPosition;   // this is the position of what I'm looking at
    LLQuaternion    mSubjectRotation;   // this is the rotation of what I'm looking at
    LLVector3       mUpVector;          // the camera's up vector in world-space (determines roll)
    LLVector3       mRelativeFocus;
    LLVector3       mRelativePos;

    bool mPitchSineAndCosineNeedToBeUpdated;

    //------------------------------------------
    // protected methods of FollowCam
    //------------------------------------------
protected:
        void    calculatePitchSineAndCosine();
        bool    updateBehindnessConstraint(LLVector3 focus, LLVector3& cam_position);

};// end of FollowCam class


class LLFollowCamMgr : public LLSingleton<LLFollowCamMgr>
{
    LLSINGLETON(LLFollowCamMgr);
    ~LLFollowCamMgr();
public:
    void setPositionLag         ( const LLUUID& source, F32 lag);
    void setFocusLag                ( const LLUUID& source, F32 lag);
    void setFocusThreshold      ( const LLUUID& source, F32 threshold);
    void setPositionThreshold   ( const LLUUID& source, F32 threshold);
    void setDistance                ( const LLUUID& source, F32 distance);
    void setPitch               ( const LLUUID& source, F32 pitch);
    void setFocusOffset         ( const LLUUID& source, const LLVector3& offset);
    void setBehindnessAngle     ( const LLUUID& source, F32 angle);
    void setBehindnessLag       ( const LLUUID& source, F32 lag);
    void setPosition                ( const LLUUID& source, const LLVector3 position);
    void setFocus               ( const LLUUID& source, const LLVector3 focus);
    void setPositionLocked      ( const LLUUID& source, bool locked);
    void setFocusLocked         ( const LLUUID& source, bool locked );

    void setCameraActive            ( const LLUUID& source, bool active );

    LLFollowCamParams* getActiveFollowCamParams();
    LLFollowCamParams* getParamsForID(const LLUUID& source);
    void removeFollowCamParams(const LLUUID& source);
    bool isScriptedCameraSource(const LLUUID& source);
    void dump();

protected:

    typedef std::map<LLUUID, LLFollowCamParams*> param_map_t;
    param_map_t mParamMap;

    typedef std::vector<LLFollowCamParams*> param_stack_t;
    param_stack_t mParamStack;
};

#endif //LL_FOLLOWCAM_H