summaryrefslogtreecommitdiff
path: root/indra/llmath/llmatrix3a.h
blob: 9b173c22eddcfc5df0ebc61d6660404ca2d5dccf (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
/**
 * @file llmatrix3a.h
 * @brief LLMatrix3a class header file - memory aligned and vectorized 3x3 matrix
 *
 * $LicenseInfo:firstyear=2010&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_LLMATRIX3A_H
#define LL_LLMATRIX3A_H

/////////////////////////////
// LLMatrix3a, LLRotation
/////////////////////////////
// This class stores a 3x3 (technically 4x3) matrix in column-major order
/////////////////////////////
/////////////////////////////
// These classes are intentionally minimal right now. If you need additional
// functionality, please contact someone with SSE experience (e.g., Falcon or
// Huseby).
/////////////////////////////

// LLMatrix3a is the base class for LLRotation, which should be used instead any time you're dealing with a
// rotation matrix.
class LLMatrix3a
{
public:

    // Utility function for quickly transforming an array of LLVector4a's
    // For transforming a single LLVector4a, see LLVector4a::setRotated
    static void batchTransform( const LLMatrix3a& xform, const LLVector4a* src, int numVectors, LLVector4a* dst );

    // Utility function to obtain the identity matrix
    static inline const LLMatrix3a& getIdentity();

    //////////////////////////
    // Ctors
    //////////////////////////

    // Ctor
    LLMatrix3a() = default;

    // Ctor for setting by columns
    inline LLMatrix3a( const LLVector4a& c0, const LLVector4a& c1, const LLVector4a& c2 );

    //////////////////////////
    // Get/Set
    //////////////////////////

    // Loads from an LLMatrix3
    inline void loadu(const LLMatrix3& src);

    // Set rows
    inline void setRows(const LLVector4a& r0, const LLVector4a& r1, const LLVector4a& r2);

    // Set columns
    inline void setColumns(const LLVector4a& c0, const LLVector4a& c1, const LLVector4a& c2);

    // Get the read-only access to a specified column. Valid columns are 0-2, but the
    // function is unchecked. You've been warned.
    inline const LLVector4a& getColumn(const U32 column) const;

    /////////////////////////
    // Matrix modification
    /////////////////////////

    // Set this matrix to the product of lhs and rhs ( this = lhs * rhs )
    void setMul( const LLMatrix3a& lhs, const LLMatrix3a& rhs );

    // Set this matrix to the transpose of src
    inline void setTranspose(const LLMatrix3a& src);

    // Set this matrix to a*w + b*(1-w)
    inline void setLerp(const LLMatrix3a& a, const LLMatrix3a& b, F32 w);

    /////////////////////////
    // Matrix inspection
    /////////////////////////

    // Sets all 4 elements in 'dest' to the determinant of this matrix.
    // If you will be using the determinant in subsequent ops with LLVector4a, use this version
    inline void getDeterminant( LLVector4a& dest ) const;

    // Returns the determinant as an LLSimdScalar. Use this if you will be using the determinant
    // primary for scalar operations.
    inline LLSimdScalar getDeterminant() const;

    // Returns nonzero if rows 0-2 and colums 0-2 contain no NaN or INF values. Row 3 is ignored
    inline LLBool32 isFinite() const;

    // Returns true if this matrix is equal to 'rhs' up to 'tolerance'
    inline bool isApproximatelyEqual( const LLMatrix3a& rhs, F32 tolerance = F_APPROXIMATELY_ZERO ) const;

protected:

    LL_ALIGN_16(LLVector4a mColumns[3]);

};

static_assert(std::is_trivial<LLMatrix3a>::value, "LLMatrix3a must be a trivial type");

class LLRotation : public LLMatrix3a
{
public:

    LLRotation() = default;

    // Returns true if this rotation is orthonormal with det ~= 1
    inline bool isOkRotation() const;
};

static_assert(std::is_trivial<LLRotation>::value, "LLRotation must be a trivial type");

#endif