source: projectionDesigner/trunk/projdesigner/src/math/ProjectionMatrix.cpp @ 373

Last change on this file since 373 was 4, checked in by Torben Dannhauer, 15 years ago
File size: 4.4 KB
Line 
1#include "math/ProjectionMatrix.h"
2
3using namespace projection;
4using namespace gmtl;
5
6/**
7 * Constructor.
8 *
9 * Default projection matrix value is : FOV=30.0,
10 * AspectRatio=4/3, Near=0.1, Far=100.0
11 */
12ProjectionMatrix::ProjectionMatrix()
13{
14    m_fov = 30.0f;
15    m_aspectRatio = 1024.0f / 768.0f;
16    m_near = 0.1f;
17    m_far = 100.0f;
18    m_offaxisX = 0.0f;
19    m_offaxisY = 0.0f;
20}
21
22/**
23 * Destructor.
24 */
25ProjectionMatrix::~ProjectionMatrix()
26{
27}
28
29/**
30 * Copy constructor.
31 *
32 * @param matrix Copy source matrix.
33 */
34ProjectionMatrix::ProjectionMatrix(const ProjectionMatrix &matrix)
35{
36    m_fov = matrix.getFOV();
37    m_aspectRatio = matrix.getAspectRatio();
38    m_near = matrix.getNear();
39    m_far = matrix.getFar();
40    m_offaxisX = matrix.getOffaxisX();
41    m_offaxisY = matrix.getOffaxisY();
42}
43
44/**
45 * Retrieve matrix values for glMultMatrixd().
46 *
47 * @return Matrix values.
48 */
49float* ProjectionMatrix::getMatrix()
50{
51    // glMultMatrixd(getMatrix()) is same as glFrustum().
52    float left =   (-tanf(Math::deg2Rad(m_fov) / 2.0f * m_aspectRatio) - m_offaxisX) * m_near;
53    float right =  ( tanf(Math::deg2Rad(m_fov) / 2.0f * m_aspectRatio) - m_offaxisX) * m_near;
54    float top =    ( tanf(Math::deg2Rad(m_fov) / 2.0f) + m_offaxisY) * m_near;
55    float bottom = (-tanf(Math::deg2Rad(m_fov) / 2.0f) + m_offaxisY) * m_near;
56    m_mat[ 0] = (2.0f * m_near) / (right - left);
57    m_mat[ 1] = 0.0f;
58    m_mat[ 2] = 0.0f;
59    m_mat[ 3] = 0.0f;
60    m_mat[ 4] = 0.0f;
61    m_mat[ 5] = (2.0f * m_near) / (top - bottom);
62    m_mat[ 6] = 0.0f;
63    m_mat[ 7] = 0.0f;
64    m_mat[ 8] = (right + left) / (right - left);
65    m_mat[ 9] = (top + bottom) / (top - bottom);
66    m_mat[10] = -(m_far + m_near) / (m_far - m_near);
67    m_mat[11] = -1.0f;
68    m_mat[12] = 0.0f;
69    m_mat[13] = 0.0f;
70    m_mat[14] = -(2.0f * m_far * m_near) / (m_far - m_near);
71    m_mat[15] = 0.0f;
72
73    return m_mat;
74}
75
76/**
77 * Retrieve four corner vectors.
78 *
79 * @param Four corner vectors.
80 */
81void ProjectionMatrix::getCorners(gmtl::Vec3f vecs[4]) const
82{
83    float left =   (-tanf(Math::deg2Rad(m_fov) / 2.0f * m_aspectRatio) + m_offaxisX);
84    float right =  ( tanf(Math::deg2Rad(m_fov) / 2.0f * m_aspectRatio) + m_offaxisX);
85    float top =    ( tanf(Math::deg2Rad(m_fov) / 2.0f) + m_offaxisY);
86    float bottom = (-tanf(Math::deg2Rad(m_fov) / 2.0f) + m_offaxisY);
87    vecs[0].set(left, 1.0f, top);
88    vecs[1].set(right, 1.0f, top);
89    vecs[2].set(right, 1.0f, bottom);
90    vecs[3].set(left, 1.0f, bottom);
91    normalize(vecs[0]);
92    normalize(vecs[1]);
93    normalize(vecs[2]);
94    normalize(vecs[3]);
95}
96
97/**
98 * Retrieve frustum parameters as 'Frustum left right bottom top near far;'.
99 *
100 * @param numSpaces Number of space characters for indent.
101 * @return Frustum params.
102 */
103QString ProjectionMatrix::getParams(int numSpaces) const
104{
105    QString spc;
106    spc.fill(' ', numSpaces);
107    double left =   (-tan(Math::deg2Rad(m_fov) / 2.0 * m_aspectRatio) + m_offaxisX);
108    double right =  ( tan(Math::deg2Rad(m_fov) / 2.0 * m_aspectRatio) + m_offaxisX);
109    double top =    ( tan(Math::deg2Rad(m_fov) / 2.0) + m_offaxisY);
110    double bottom = (-tan(Math::deg2Rad(m_fov) / 2.0) + m_offaxisY);
111  return spc + QString("Frustum %1 %2 %3 %4 %5 %6;").arg(left*m_near).arg(right*m_near).arg(bottom*m_near).arg(top*m_near).arg(m_near).arg(m_far);
112}
113
114/**
115 * Restore the projection matrix from XML data.
116 *
117 * @param element Parent XML element of the projection matrix data.
118 */
119void ProjectionMatrix::initFromDOMElement(const QDomElement& element)
120{
121        m_fov = element.attribute("fov").toFloat();
122        m_aspectRatio = element.attribute("aspectRatio").toFloat();
123        m_near = element.attribute("near").toFloat();
124        m_far = element.attribute("far").toFloat();
125        m_offaxisX = element.attribute("offaxisX").toFloat();
126        m_offaxisY = element.attribute("offaxisY").toFloat();
127}
128
129/**
130 * Store the current projection matrix as XML data.
131 *
132 * @param name XML node name of the data.
133 * @param doc XML document to store the data.
134 * @return Current screen shape data as XML data.
135 */
136QDomElement ProjectionMatrix::domElement(const QString& name, QDomDocument& doc) const
137{
138        QDomElement de = doc.createElement(name);
139
140        de.setAttribute("fov", QString::number(m_fov));
141        de.setAttribute("aspectRatio", QString::number(m_aspectRatio));
142        de.setAttribute("near", QString::number(m_near));
143        de.setAttribute("far", QString::number(m_far));
144        de.setAttribute("offaxisX", QString::number(m_offaxisX));
145        de.setAttribute("offaxisY", QString::number(m_offaxisY));
146
147        return de;
148}
Note: See TracBrowser for help on using the repository browser.