root/trunk/dep/include/g3dlite/G3D/CoordinateFrame.h

Revision 2, 9.2 kB (checked in by yumileroy, 17 years ago)

[svn] * Proper SVN structure

Original author: Neo2003
Date: 2008-10-02 16:23:55-05:00

Line 
1/**
2 @file CoordinateFrame.h
3
4 @maintainer Morgan McGuire, matrix@graphics3d.com
5 
6 @created 2001-03-04
7 @edited  2006-04-07
8
9 Copyright 2000-2006, Morgan McGuire.
10 All rights reserved.
11*/
12
13#ifndef G3D_COORDINATEFRAME_H
14#define G3D_COORDINATEFRAME_H
15
16#include "G3D/platform.h"
17#include "G3D/Vector3.h"
18#include "G3D/Vector4.h"
19#include "G3D/Matrix3.h"
20#include "G3D/Array.h"
21#include <math.h>
22#include <string>
23#include <stdio.h>
24#include <cstdarg>
25#include <assert.h>
26
27namespace G3D {
28
29/**
30 A rigid body RT (rotation-translation) transformation.
31   
32CoordinateFrame abstracts a 4x4 matrix that maps object space to world space:
33 
34  v_world = C * v_object
35
36CoordinateFrame::rotation is the upper 3x3 submatrix, CoordinateFrame::translation
37is the right 3x1 column.  The 4th row is always [0 0 0 1], so it isn't stored. 
38So you don't have to remember which way the multiplication and transformation work,
39it provides explicit toWorldSpace and toObjectSpace methods.  Also, points, vectors
40(directions), and surface normals transform differently, so they have separate methods.
41 
42Some helper functions transform whole primitives like boxes in and out of object space.
43
44Convert to Matrix4 using CoordinateFrame::toMatrix4.  You <I>can</I> construct a CoordinateFrame
45from a Matrix4 using Matrix4::approxCoordinateFrame, however, because a Matrix4 is more
46general than a CoordinateFrame, some information may be lost.
47
48See also: G3D::Matrix4, G3D::Quat
49*/
50class CoordinateFrame {
51public:
52
53    /**
54     Takes object space points to world space.
55     */
56    Matrix3                                                     rotation;
57
58    /**
59     Takes object space points to world space.
60     */
61    Vector3                                                     translation;
62
63    /**
64     The direction an object "looks" relative to its own axes.
65     @deprecated This is always -1 and will be fixed at that value in future releases.
66     */
67    static const float                          zLookDirection;
68
69    inline bool operator==(const CoordinateFrame& other) const {
70        return (translation == other.translation) && (rotation == other.rotation);
71    }
72
73    inline bool operator!=(const CoordinateFrame& other) const {
74        return !(*this == other);
75    }
76
77    bool fuzzyEq(const CoordinateFrame& other) const;
78
79    bool fuzzyIsIdentity() const;
80
81    bool isIdentity() const;
82
83    /**
84     Initializes to the identity coordinate frame.
85     */
86    inline CoordinateFrame() : 
87        rotation(Matrix3::identity()), translation(Vector3::zero()) {
88    }
89
90        CoordinateFrame(const Vector3& _translation) :
91        rotation(Matrix3::identity()), translation(_translation) {
92        }
93
94    CoordinateFrame(const Matrix3 &rotation, const Vector3 &translation) :
95        rotation(rotation), translation(translation) {
96    }
97
98    CoordinateFrame(const Matrix3 &rotation) :
99        rotation(rotation), translation(Vector3::zero()) {
100    }
101
102    CoordinateFrame(const CoordinateFrame &other) :
103        rotation(other.rotation), translation(other.translation) {}
104
105    /**
106      Computes the inverse of this coordinate frame.
107     */
108    inline CoordinateFrame inverse() const {
109        CoordinateFrame out;
110        out.rotation = rotation.transpose();
111        out.translation = -out.rotation * translation;
112        return out;
113    }
114
115    inline ~CoordinateFrame() {}
116
117    /** See also Matrix4::approxCoordinateFrame */
118    class Matrix4 toMatrix4() const;
119
120    /**
121     Produces an XML serialization of this coordinate frame.
122     */
123    std::string toXML() const;
124
125    /**
126     Returns the heading of the lookVector as an angle in radians relative to
127     the world -z axis.  That is, a counter-clockwise heading where north (-z)
128     is 0 and west (-x) is PI/2.
129
130     Note that the heading ignores the Y axis, so an inverted
131     object has an inverted heading.
132     */
133    inline float getHeading() const {
134        Vector3 look = rotation.getColumn(2);
135        float angle = -(float) atan2(-look.x, look.z);
136        return angle;
137    }
138
139    /**
140     Takes the coordinate frame into object space.
141     this->inverse() * c
142     */
143    inline CoordinateFrame toObjectSpace(const CoordinateFrame& c) const {
144        return this->inverse() * c;
145    }
146
147    inline Vector4 toObjectSpace(const Vector4& v) const {
148        return this->inverse().toWorldSpace(v);
149    }
150
151    inline Vector4 toWorldSpace(const Vector4& v) const {
152        return Vector4(rotation * Vector3(v.x, v.y, v.z) + translation * v.w, v.w);
153    }
154
155    /**
156     Transforms the point into world space.
157     */
158    inline Vector3 pointToWorldSpace(const Vector3& v) const {
159        return Vector3(
160                        rotation[0][0] * v[0] + rotation[0][1] * v[1] + rotation[0][2] * v[2] + translation[0],
161                        rotation[1][0] * v[0] + rotation[1][1] * v[1] + rotation[1][2] * v[2] + translation[1],
162                        rotation[2][0] * v[0] + rotation[2][1] * v[1] + rotation[2][2] * v[2] + translation[2]);
163    }
164
165    /**
166     Transforms the point into object space.
167     */
168        inline Vector3 pointToObjectSpace(const Vector3& v) const {
169                float p[3];
170                p[0] = v[0] - translation[0];
171                p[1] = v[1] - translation[1];
172                p[2] = v[2] - translation[2];
173                return Vector3(
174                        rotation[0][0] * p[0] + rotation[1][0] * p[1] + rotation[2][0] * p[2],
175                        rotation[0][1] * p[0] + rotation[1][1] * p[1] + rotation[2][1] * p[2],
176                        rotation[0][2] * p[0] + rotation[1][2] * p[1] + rotation[2][2] * p[2]);
177    }
178
179    /**
180     Transforms the vector into world space (no translation).
181     */
182    inline Vector3 vectorToWorldSpace(const Vector3& v) const {
183        return rotation * v;
184    }
185
186    inline Vector3 normalToWorldSpace(const Vector3& v) const {
187        return rotation * v;
188    }
189
190    class Ray toObjectSpace(const Ray& r) const;
191
192    Ray toWorldSpace(const Ray& r) const;
193
194    /**
195     Transforms the vector into object space (no translation).
196     */
197    inline Vector3 vectorToObjectSpace(const Vector3 &v) const {
198        // Multiply on the left (same as rotation.transpose() * v)
199        return v * rotation;
200    }
201
202    inline Vector3 normalToObjectSpace(const Vector3 &v) const {
203        // Multiply on the left (same as rotation.transpose() * v)
204        return v * rotation;
205    }
206
207    void pointToWorldSpace(const Array<Vector3>& v, Array<Vector3>& vout) const;
208
209    void normalToWorldSpace(const Array<Vector3>& v, Array<Vector3>& vout) const;
210
211    void vectorToWorldSpace(const Array<Vector3>& v, Array<Vector3>& vout) const;
212
213    void pointToObjectSpace(const Array<Vector3>& v, Array<Vector3>& vout) const;
214
215    void normalToObjectSpace(const Array<Vector3>& v, Array<Vector3>& vout) const;
216
217    void vectorToObjectSpace(const Array<Vector3>& v, Array<Vector3>& vout) const;
218
219    class Box toWorldSpace(const class AABox& b) const;
220
221    class Box toWorldSpace(const class Box& b) const;
222
223    class Cylinder toWorldSpace(const class Cylinder& b) const;
224
225    class Capsule toWorldSpace(const class Capsule& b) const;
226
227    class Plane toWorldSpace(const class Plane& p) const;
228
229    class Sphere toWorldSpace(const class Sphere& b) const;
230
231    class Triangle toWorldSpace(const class Triangle& t) const;
232
233    class Box toObjectSpace(const AABox& b) const;
234
235    class Box toObjectSpace(const Box& b) const;
236
237    class Plane toObjectSpace(const Plane& p) const;
238 
239    class Sphere toObjectSpace(const Sphere& b) const;
240
241    Triangle toObjectSpace(const Triangle& t) const;
242
243    /** Compose: create the transformation that is <I>other</I> followed by <I>this</I>.*/
244    CoordinateFrame operator*(const CoordinateFrame &other) const {
245        return CoordinateFrame(rotation * other.rotation,
246                               pointToWorldSpace(other.translation));
247    }
248
249    CoordinateFrame operator+(const Vector3& v) const {
250        return CoordinateFrame(rotation, translation + v);
251    }
252
253    CoordinateFrame operator-(const Vector3& v) const {
254        return CoordinateFrame(rotation, translation - v);
255    }
256
257    void lookAt(const Vector3& target);
258
259    void lookAt(
260        const Vector3&  target,
261        Vector3         up);
262
263    /** @deprecated See lookVector */
264        inline Vector3 getLookVector() const {
265                return rotation.getColumn(2) * zLookDirection;
266        }
267
268    /** The direction this camera is looking (its negative z axis)*/
269        inline Vector3 lookVector() const {
270                return rotation.getColumn(2) * zLookDirection;
271        }
272
273    /** Returns the ray starting at the camera origin travelling in direction CoordinateFrame::lookVector. */
274    class Ray lookRay() const;
275
276    /** Up direction for this camera (its y axis). */
277    inline Vector3 upVector() const {
278        return rotation.getColumn(1);
279    }
280
281    /**
282     If a viewer looks along the look vector, this is the viewer's "left"
283     @deprecated leftVector
284     */
285    inline Vector3 getLeftVector() const {
286                return -rotation.getColumn(0);
287        }
288
289    /** @deprecated See rightVector */
290    inline Vector3 getRightVector() const {
291                return rotation.getColumn(0);
292        }
293
294    /**
295     If a viewer looks along the look vector, this is the viewer's "left".
296     Useful for strafing motions and building alternative coordinate frames.
297     */
298    inline Vector3 leftVector() const {
299                return -rotation.getColumn(0);
300    }
301
302    inline Vector3 rightVector() const {
303                return rotation.getColumn(0);
304    }
305
306    /**
307     Linearly interpolates between two coordinate frames, using
308     Quat::slerp for the rotations.
309     */
310    CoordinateFrame lerp(
311        const CoordinateFrame&  other,
312        float                   alpha) const;
313
314};
315
316} // namespace
317
318#endif
Note: See TracBrowser for help on using the browser.