summaryrefslogtreecommitdiff
path: root/indra/llmath/llcoordframe.h
blob: 89b5d8beffcb7331fa4b8de0b5e982e83c8e3522 (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
/** 
 * @file llcoordframe.h
 * @brief LLCoordFrame class header file.
 *
 * $LicenseInfo:firstyear=2000&license=viewergpl$
 * 
 * Copyright (c) 2000-2009, Linden Research, Inc.
 * 
 * Second Life Viewer Source Code
 * The source code in this file ("Source Code") is provided by Linden Lab
 * to you under the terms of the GNU General Public License, version 2.0
 * ("GPL"), unless you have obtained a separate licensing agreement
 * ("Other License"), formally executed by you and Linden Lab.  Terms of
 * the GPL can be found in doc/GPL-license.txt in this distribution, or
 * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
 * 
 * There are special exceptions to the terms and conditions of the GPL as
 * it is applied to this Source Code. View the full text of the exception
 * in the file doc/FLOSS-exception.txt in this software distribution, or
 * online at
 * http://secondlifegrid.net/programs/open_source/licensing/flossexception
 * 
 * By copying, modifying or distributing this software, you acknowledge
 * that you have read and understood your obligations described above,
 * and agree to abide by those obligations.
 * 
 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
 * COMPLETENESS OR PERFORMANCE.
 * $/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