source: projectionDesigner/trunk/projdesignerplugins/defaultplugin/DefaultProjectorData.cpp @ 373

Last change on this file since 373 was 4, checked in by Torben Dannhauer, 15 years ago
File size: 9.4 KB
Line 
1#include "DefaultProjectorData.h"
2#include <stdlib.h>
3#include <GL/glut.h>
4#include <math.h>
5
6#ifndef M_PI
7#define M_PI 3.1415926535897932384626433832795
8#endif // M_PI
9#define RAD(angle) ((angle)*M_PI/180.f)
10
11
12const QString DefaultPluginData::g_projector_name=QObject::tr("Standard Frustum");
13
14
15/**
16 * Default constructor fot the DefaultPluginData.
17 *
18 */
19DefaultPluginData::DefaultPluginData(ProjectorInterface* plugin, float fov, float aspectRatio, float nearDist, float farDist, float offaxisX, float offaxisY):
20    ProjectorData(plugin),
21    m_fov(fov),
22    m_aspectRatio(aspectRatio),
23    m_nearDist(nearDist),
24    m_farDist(farDist),
25    m_offaxisX(offaxisX),
26    m_offaxisY(offaxisY),
27    m_visibleFar(1.2f)
28{
29}
30
31
32/**
33 * Destructor fot the DefaultPluginData.
34 *
35 */
36DefaultPluginData::~DefaultPluginData()
37{
38}
39
40
41/**
42 * Implements the copy from other datas.
43 *
44 * This method is used by the copy constructor.
45 *
46 * @param data The source data.
47 *
48 * @return true if the copy is ok, false otherwise. The copy can fail if
49 *         ProjectorData is not a DefaultPluginData.
50 *
51 * @seealso is_equal_to
52 *
53 */
54bool DefaultPluginData::copy_from(const ProjectorData& data) 
55{
56    if (!ProjectorData::copy_from(data)) return false;
57    Q_ASSERT(NULL!=plugin());
58    Q_ASSERT(NULL!=data.plugin());
59    const DefaultPluginData& _data = static_cast<const DefaultPluginData&>(data);
60    m_fov = _data.m_fov;
61    m_aspectRatio = _data.m_aspectRatio;
62    m_nearDist = _data.m_nearDist;
63    m_farDist = _data.m_farDist;
64    m_offaxisX = _data.m_offaxisX;
65    m_offaxisY = _data.m_offaxisY;
66    m_visibleFar = _data.m_visibleFar;
67    return true;
68}
69
70
71/**
72 * Implements the egality-test with other datas.
73 *
74 * This could be an operator==.
75 *
76 * @param data The data to test with.
77 *
78 * @return true if the data are equal, false otherwise. The test can fail if
79 *         the data have different parameters, but also it ProjectorData is
80 *         not a DefaultPluginData.
81 *
82 * @seealso copy_from
83 *
84 */
85bool DefaultPluginData::is_equal_to(const ProjectorData& data) const
86{
87    if (!ProjectorData::is_equal_to(data)) return false;
88    const DefaultPluginData& _data = static_cast<const DefaultPluginData&>(data);
89    return m_fov==_data.m_fov&&
90        m_aspectRatio==_data.m_aspectRatio&&
91        m_nearDist==_data.m_nearDist&&
92        m_farDist==_data.m_farDist&&
93        m_offaxisX==_data.m_offaxisX&&
94        m_offaxisY==_data.m_offaxisY&&
95        m_visibleFar==_data.m_visibleFar;
96}
97
98
99/**
100 * Draws the frustum (a truncated pyramid).
101 *
102 * This method draws the frustum from outside. If the frustum is selected,
103 * the lines are a little bigger.
104 *
105 * @param bSelected true if the frustum is selected.
106 *
107 * @seealso copy_from
108 *
109 */
110void DefaultPluginData::draw(bool bSelected)
111{
112    QColor m_color(0,0,255);
113
114    if (m_bShow)
115    {
116        glPushMatrix();
117        glPushAttrib(GL_ENABLE_BIT | GL_CURRENT_BIT | GL_LINE_BIT);
118
119        if (bSelected)
120            glLineWidth(3.0f);
121
122        float left =  -tan(RAD(m_fov/2.0f)) * m_aspectRatio + m_offaxisX;
123        float right =  tan(RAD(m_fov/2.0f)) * m_aspectRatio + m_offaxisX;
124        float top =   -tan(RAD(m_fov/2.0f)) + m_offaxisY;
125        float bottom = tan(RAD(m_fov/2.0f)) + m_offaxisY;
126        float nearDist = m_nearDist;
127        float farDist = m_farDist;
128        if (m_visibleFar < farDist)
129            farDist = m_visibleFar;
130
131        glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
132        glDisable(GL_LIGHTING);
133
134        glBegin(GL_LINE_LOOP);
135        glVertex3f(nearDist*left,  nearDist*bottom, -nearDist);
136        glVertex3f(nearDist*right, nearDist*bottom, -nearDist);
137        glVertex3f(nearDist*right, nearDist*top,    -nearDist);
138        glVertex3f(nearDist*left,  nearDist*top,    -nearDist);
139        glEnd();
140        glBegin(GL_LINE_LOOP);
141        glVertex3f(farDist*left,  farDist*bottom, -farDist);
142        glVertex3f(farDist*right, farDist*bottom, -farDist);
143        glVertex3f(farDist*right, farDist*top,    -farDist);
144        glVertex3f(farDist*left,  farDist*top,    -farDist);
145        glEnd();
146        glBegin(GL_LINES);
147        glVertex3f(0.0f, 0.0f, 0.0f);
148        glVertex3f(farDist*left,  farDist*bottom, -farDist);
149        glVertex3f(0.0f, 0.0f, 0.0f);
150        glVertex3f(farDist*right, farDist*bottom, -farDist);
151        glVertex3f(0.0f, 0.0f, 0.0f);
152        glVertex3f(farDist*right, farDist*top,    -farDist);
153        glVertex3f(0.0f, 0.0f, 0.0f);
154        glVertex3f(farDist*left,  farDist*top,    -farDist);
155        glEnd();
156
157        glColor4f((float)m_color.red()/255.0f, (float)m_color.green()/255.0f, (float)m_color.blue()/255.0f, 0.25f);
158        glEnable(GL_LIGHTING);
159        glEnable(GL_BLEND);
160        glDepthMask(false);
161
162        glBegin(GL_TRIANGLES);
163        glNormal3f(0.0f, cos(RAD(m_fov)/2.0f), -sin(RAD(m_fov)/2.0f));
164        glVertex3f(0.0f, 0.0f, 0.0f);
165        glVertex3f(farDist*left,  farDist*bottom, -farDist);
166        glVertex3f(farDist*right, farDist*bottom, -farDist);
167        glNormal3f( cos(RAD(m_fov)*m_aspectRatio/2.0f),
168                    0.0f,
169                    -sin(RAD(m_fov)*m_aspectRatio/2.0f));
170        glVertex3f(0.0f, 0.0f, 0.0f);
171        glVertex3f(farDist*right, farDist*bottom, -farDist);
172        glVertex3f(farDist*right, farDist*top,    -farDist);
173        glNormal3f(0.0f, -cos(RAD(m_fov)/2.0f), -sin(RAD(m_fov)/2.0f));
174        glVertex3f(0.0f, 0.0f, 0.0f);
175        glVertex3f(farDist*right, farDist*top, -farDist);
176        glVertex3f(farDist*left,  farDist*top, -farDist);
177        glNormal3f(-cos(RAD(m_fov)*m_aspectRatio/2.0f),
178                   0.0f,
179                   -sin(RAD(m_fov)*m_aspectRatio/2.0f));
180        glVertex3f(0.0f, 0.0f, 0.0f);
181        glVertex3f(farDist*left, farDist*top,    -farDist);
182        glVertex3f(farDist*left, farDist*bottom, -farDist);
183        glEnd();
184
185        glDepthMask(true);
186        glPopAttrib();
187        glPopMatrix();
188    }
189}
190
191
192/**
193 * Begins the draw through the frustum.
194 *
195 * The draw must end with a endDraw().
196 *
197 * This is the same than glFrustum(), with some glPush...() before.
198 *
199 * @seealso endDraw
200 *
201 */
202void DefaultPluginData::beginDraw(void)
203{
204    // Get the previous matrix mode
205    GLint previous_matrix_mode=-1;
206    glGetIntegerv(GL_MATRIX_MODE, &previous_matrix_mode);
207
208    // Push and load the new projection matrix
209    glMatrixMode(GL_PROJECTION);
210    glPushMatrix();
211    glLoadIdentity();
212    glFrustum((-tan(RAD(m_fov) / 2.0 * m_aspectRatio) - m_offaxisX) * m_nearDist, 
213              ( tan(RAD(m_fov) / 2.0 * m_aspectRatio) - m_offaxisX) * m_nearDist, 
214              (-tan(RAD(m_fov) / 2.0) + m_offaxisY) * m_nearDist, 
215              ( tan(RAD(m_fov) / 2.0) + m_offaxisY) * m_nearDist, 
216              m_nearDist, 
217              m_farDist);
218
219    // Restore the previous matrix mode
220    glMatrixMode(previous_matrix_mode);
221}
222
223
224/**
225 * Ends the draw through the frustum.
226 *
227 * Must be used each time a draw through the projector has begun with a
228 * beginDraw().
229 *
230 * This is the same than some glPop...().
231 *
232 * @seealso beginDraw
233 *
234 */
235void DefaultPluginData::endDraw(void)
236{
237    // Get the previous matrix mode
238    GLint previous_matrix=-1;
239    glGetIntegerv(GL_MATRIX_MODE, &previous_matrix);
240    // Pop the projection matrix stack
241    glMatrixMode(GL_PROJECTION);
242    glPopMatrix();
243    // Restore the previous matrix mode
244    glMatrixMode(previous_matrix);
245}
246
247
248/**
249 * Begins the projection.
250 *
251 * The projection must end with a endProjection().
252 *
253 * This is the same than glFrustum(), without anything else.
254 * beginDraw and beginProjection are quite close and it is perhaps to merge
255 * them, but for the moment, to respect the Projection Designer
256 * implementation, it will be let like this.
257 *
258 * endProjection is not implemented here because it does nothing more than
259 * the ProjectorData::endProjection().
260 *
261 */
262void DefaultPluginData::beginProjection(void)
263{
264    glFrustum((-tan(RAD(m_fov) / 2.0 * m_aspectRatio) - m_offaxisX) * m_nearDist, 
265              ( tan(RAD(m_fov) / 2.0 * m_aspectRatio) - m_offaxisX) * m_nearDist, 
266              (-tan(RAD(m_fov) / 2.0) + m_offaxisY) * m_nearDist, 
267              ( tan(RAD(m_fov) / 2.0) + m_offaxisY) * m_nearDist, 
268              m_nearDist, 
269              m_farDist);
270}
271
272
273/**
274 * Loads the frustum from a QDomElement.
275 *
276 * @param element The QDomElement to read from.
277 *
278 */
279void DefaultPluginData::initFromDOMElement(const QDomElement& element)
280{
281    if (!element.isNull())
282    {
283        m_fov=element.attribute("fov").toFloat();
284        m_aspectRatio=element.attribute("aspectRatio").toFloat();
285        m_nearDist=element.attribute("near").toFloat();
286        m_farDist=element.attribute("far").toFloat();
287        m_offaxisX=element.attribute("offaxisX").toFloat();
288        m_offaxisY=element.attribute("offaxisY").toFloat();
289        m_visibleFar=element.attribute("visibleFar").toFloat();
290        ProjectorData::initFromDOMElement(element);
291    }
292}
293
294
295/**
296 * Writes the frustum in a QDomDocument.
297 *
298 * @param name The name of the element.
299 * @param doc The document whom belongs the element.
300 *
301 * @return The QDomElement to add.
302 *
303 */
304QDomElement DefaultPluginData::domElement(const QString& name, QDomDocument& doc) const
305{
306    QDomElement de = ProjectorData::domElement(name, doc);
307    de.setAttribute("fov", m_fov);
308    de.setAttribute("aspectRatio", m_aspectRatio);
309    de.setAttribute("near", m_nearDist);
310    de.setAttribute("far", m_farDist);
311    de.setAttribute("offaxisX", m_offaxisX);
312    de.setAttribute("offaxisY", m_offaxisY);
313    de.setAttribute("visibleFar", m_visibleFar);
314    return de;
315}
Note: See TracBrowser for help on using the repository browser.