summaryrefslogtreecommitdiff
path: root/indra/llmath/llcoordframe.h
blob: 802b98425a5439a2c482597261bceab65bf93792 (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
/**
 * @file llcoordframe.h
 * @brief LLCoordFrame 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_COORDFRAME_H
#define LL_COORDFRAME_H

#include "v3math.h"
#include "v4math.h"
#include "llerror.h"

// XXX : The constructors of the LLCoordFrame class assume that all vectors
//       and quaternion being passed as arguments are normalized, and all matrix
//       arguments are unitary.  VERY BAD things will happen if these assumptions fail.
//       Also, segfault hazzards exist in methods that accept F32* arguments.


class LLCoordFrame
{
public:
    LLCoordFrame();                                         // Inits at zero with identity rotation
    explicit LLCoordFrame(const LLVector3 &origin);         // Sets origin, and inits rotation = Identity
    LLCoordFrame(const LLVector3 &x_axis,
                 const LLVector3 &y_axis,
                 const LLVector3 &z_axis);                  // Sets coordinate axes and inits origin at zero
    LLCoordFrame(const LLVector3 &origin,
                 const LLVector3 &x_axis,
                 const LLVector3 &y_axis,
                 const LLVector3 &z_axis);                  // Sets the origin and coordinate axes
    LLCoordFrame(const LLVector3 &origin,
                 const LLMatrix3 &rotation);                // Sets axes to 3x3 matrix
    LLCoordFrame(const LLVector3 &origin,
                 const LLVector3 &direction);               // Sets origin and calls lookDir(direction)
    explicit LLCoordFrame(const LLQuaternion &q);           // Sets axes using q and inits mOrigin to zero
    LLCoordFrame(const LLVector3 &origin,
                 const LLQuaternion &q);                    // Uses quaternion to init axes
    explicit LLCoordFrame(const LLMatrix4 &mat);            // Extracts frame from a 4x4 matrix
    // The folowing two constructors are dangerous due to implicit casting and have been disabled - SJB
    //LLCoordFrame(const F32 *origin, const F32 *rotation); // Assumes "origin" is 1x3 and "rotation" is 1x9 array
    //LLCoordFrame(const F32 *origin_and_rotation);         // Assumes "origin_and_rotation" is 1x12 array

    BOOL isFinite() { return mOrigin.isFinite() && mXAxis.isFinite() && mYAxis.isFinite() && mZAxis.isFinite(); }

    void reset();
    void resetAxes();

    void setOrigin(F32 x, F32 y, F32 z);                    // Set mOrigin
    void setOrigin(const LLVector3 &origin);
    void setOrigin(const F32 *origin);
    void setOrigin(const LLCoordFrame &frame);

    inline void setOriginX(F32 x) { mOrigin.mV[VX] = x; }
    inline void setOriginY(F32 y) { mOrigin.mV[VY] = y; }
    inline void setOriginZ(F32 z) { mOrigin.mV[VZ] = z; }

    void setAxes(const LLVector3 &x_axis,                   // Set axes
                 const LLVector3 &y_axis,
                 const LLVector3 &z_axis);
    void setAxes(const LLMatrix3 &rotation_matrix);
    void setAxes(const LLQuaternion &q);
    void setAxes(const F32 *rotation_matrix);
    void setAxes(const LLCoordFrame &frame);

    void translate(F32 x, F32 y, F32 z);                    // Move mOrgin
    void translate(const LLVector3 &v);
    void translate(const F32 *origin);

    void rotate(F32 angle, F32 x, F32 y, F32 z);            // Move axes
    void rotate(F32 angle, const LLVector3 &rotation_axis);
    void rotate(const LLQuaternion &q);
    void rotate(const LLMatrix3 &m);

    void orthonormalize();  // Makes sure axes are unitary and orthogonal.

    // These methods allow rotations in the LLCoordFrame's frame
    void roll(F32 angle);       // RH rotation about mXAxis, radians
    void pitch(F32 angle);      // RH rotation about mYAxis, radians
    void yaw(F32 angle);        // RH rotation about mZAxis, radians

    inline const LLVector3 &getOrigin() const { return mOrigin; }

    inline const LLVector3 &getXAxis() const  { return mXAxis; }
    inline const LLVector3 &getYAxis() const  { return mYAxis; }
    inline const LLVector3 &getZAxis() const  { return mZAxis; }

    inline const LLVector3 &getAtAxis() const   { return mXAxis; }
    inline const LLVector3 &getLeftAxis() const { return mYAxis; }
    inline const LLVector3 &getUpAxis() const   { return mZAxis; }

    // These return representations of the rotation or orientation of the LLFrame
    // it its absolute frame.  That is, these rotations acting on the X-axis {1,0,0}
    // will produce the mXAxis.
    //      LLMatrix3 getMatrix3() const;               // Returns axes in 3x3 matrix
    LLQuaternion getQuaternion() const;         // Returns axes in quaternion form

    // Same as above, except it also includes the translation of the LLFrame
    //      LLMatrix4 getMatrix4() const;               // Returns position and axes in 4x4 matrix

    // Returns matrix which expresses point in local frame in the parent frame
    void getMatrixToParent(LLMatrix4 &mat) const;
    // Returns matrix which expresses point in parent frame in the local frame
    void getMatrixToLocal(LLMatrix4 &mat) const; // Returns matrix which expresses point in parent frame in the local frame

    void getRotMatrixToParent(LLMatrix4 &mat) const;

    // Copies mOrigin, then the three axes to buffer, returns number of bytes copied.
    size_t writeOrientation(char *buffer) const;

    // Copies mOrigin, then the three axes from buffer, returns the number of bytes copied.
    // Assumes the data in buffer is correct.
    size_t readOrientation(const char *buffer);

    LLVector3 rotateToLocal(const LLVector3 &v) const;      // Returns v' rotated to local
    LLVector4 rotateToLocal(const LLVector4 &v) const;      // Returns v' rotated to local
    LLVector3 rotateToAbsolute(const LLVector3 &v) const;   // Returns v' rotated to absolute
    LLVector4 rotateToAbsolute(const LLVector4 &v) const;   // Returns v' rotated to absolute

    LLVector3 transformToLocal(const LLVector3 &v) const;       // Returns v' in local coord
    LLVector4 transformToLocal(const LLVector4 &v) const;       // Returns v' in local coord
    LLVector3 transformToAbsolute(const LLVector3 &v) const;    // Returns v' in absolute coord
    LLVector4 transformToAbsolute(const LLVector4 &v) const;    // Returns v' in absolute coord

    // Write coord frame orientation into provided array in OpenGL matrix format.
    void getOpenGLTranslation(F32 *ogl_matrix) const;
    void getOpenGLRotation(F32 *ogl_matrix) const;
    void getOpenGLTransform(F32 *ogl_matrix) const;

    // lookDir orients to (xuv, presumed normalized) and does not affect origin
    void lookDir(const LLVector3 &xuv, const LLVector3 &up);
    void lookDir(const LLVector3 &xuv); // up = 0,0,1
    // lookAt orients to (point_of_interest - origin) and sets origin
    void lookAt(const LLVector3 &origin, const LLVector3 &point_of_interest, const LLVector3 &up);
    void lookAt(const LLVector3 &origin, const LLVector3 &point_of_interest); // up = 0,0,1

    // deprecated
    void setOriginAndLookAt(const LLVector3 &origin, const LLVector3 &up, const LLVector3 &point_of_interest)
    {
        lookAt(origin, point_of_interest, up);
    }

    friend std::ostream& operator<<(std::ostream &s, const LLCoordFrame &C);

    // These vectors are in absolute frame
    LLVector3 mOrigin;
    LLVector3 mXAxis;
    LLVector3 mYAxis;
    LLVector3 mZAxis;
};


#endif