source: projectionDesigner/trunk/projdesigner/src/Warp.cpp @ 433

Last change on this file since 433 was 433, checked in by Torben Dannhauer, 11 years ago
File size: 7.5 KB
Line 
1#include <math.h>
2
3#include <GL/glu.h>     // Added! for gluUnProject() calls. [ben 27Sep13]
4
5#include "Warp.h"
6
7using namespace projection;
8
9Warp::Warp()
10{
11    m_bEnabled = true;
12    m_pCtrlPoints = NULL;
13    setNumCtrlPoints(4);
14    m_gridSize = 24;
15    m_zoom = 1.0f;
16    m_selectedCtrlPoint = -1;
17    m_bShowCtrlPoints = true;
18}
19
20Warp::~Warp()
21{
22}
23
24void Warp::draw(bool bForExport, bool bForBlend)
25{
26    glPushAttrib(GL_ALL_ATTRIB_BITS);
27
28    glMatrixMode(GL_PROJECTION);
29    glLoadIdentity();
30
31    glGetIntegerv(GL_VIEWPORT, m_viewport);
32
33    glOrtho(-0.5f, 0.5f, -0.5f, 0.5f, -1.0f, 1.0f);
34    glGetDoublev(GL_PROJECTION_MATRIX, m_projMatrix);
35
36    glMatrixMode(GL_MODELVIEW);
37    glPushMatrix();
38    glLoadIdentity();
39    if (!bForExport)
40        glScalef(m_zoom, m_zoom, 1.0f);
41    glGetDoublev(GL_MODELVIEW_MATRIX, m_modelMatrix);
42
43    glDisable(GL_LIGHTING);
44    glColor3f(1.0, 1.0, 1.0);
45    glEnable(GL_TEXTURE_2D);
46    glEnable(GL_MAP2_VERTEX_3);
47    glEnable(GL_MAP2_TEXTURE_COORD_2);
48    glMapGrid2f(m_gridSize, 0.0f, 1.0f, m_gridSize, 0.0f, 1.0f);
49    glMap2f(GL_MAP2_VERTEX_3, 0, 1, 3, m_numCtrlPoints, 0, 1, m_numCtrlPoints * 3, m_numCtrlPoints, m_pCtrlPoints);
50    GLfloat pTexCoords[2][2][2] = {
51        {{0.0f, 0.0f}, {1.0f, 0.0f}},
52        {{0.0f, 1.0f}, {1.0f, 1.0f}}};
53    glMap2f(GL_MAP2_TEXTURE_COORD_2, 0.0f, 1.0f, 2, 2, 0.0f, 1.0f, 4, 2, &pTexCoords[0][0][0]);
54    glEvalMesh2(GL_FILL, 0, m_gridSize, 0, m_gridSize);
55
56    if (m_bShowCtrlPoints && !bForExport)
57    {
58        glDisable(GL_TEXTURE_2D);
59        glDisable(GL_DEPTH_TEST);
60
61        glLineWidth(1.0f);
62        for (int y=0; y<m_numCtrlPoints; ++y)
63        {
64            for (int x=0; x<m_numCtrlPoints; ++x)
65            {
66                float dx = 1.0f / (m_numCtrlPoints-1) * (float)x - 0.5f;
67                float dy = 1.0f / (m_numCtrlPoints-1) * (float)y - 0.5f;
68                if (m_selectedCtrlPoint == y*m_numCtrlPoints+x)
69                    glColor3f(0.0f, 1.0f, 0.0f);
70                else
71                {
72                    if (bForBlend)
73                        glColor3f(0.0f, 0.0f, 1.0f);
74                    else
75                        glColor3f(1.0f, 1.0f, 1.0f);
76                }
77                glBegin(GL_LINES);
78                glVertex3f(dx, dy, 0.0f);
79                glVertex3fv(&m_pCtrlPoints[(y*m_numCtrlPoints+x)*3]);
80                glEnd();
81            }
82        }
83
84        glPointSize(6.0f);
85        glColor3f(1.0f, 1.0f, 0.0f);
86        glBegin(GL_POINTS);
87        for (int i=0; i<m_numCtrlPoints*m_numCtrlPoints; ++i) {
88            if (i != m_selectedCtrlPoint)
89                glVertex3fv(&m_pCtrlPoints[i*3]);
90        }
91        glEnd();
92        if (m_selectedCtrlPoint >= 0)
93        {
94            glColor3f(1.0f, 0.0f, 0.0f);
95            glBegin(GL_POINTS);
96            glVertex3fv(&m_pCtrlPoints[m_selectedCtrlPoint*3]);
97            glEnd();
98        }
99    }
100
101    glPopMatrix();
102
103    glPopAttrib();
104}
105
106bool Warp::pick(int x, int y)
107{
108    if (!m_bEnabled)
109        return 0;
110
111    m_lastMouseX = x;
112    m_lastMouseY = y;
113
114    int newCtrlPoint = pickCtrlPoint(x, y);
115    if (newCtrlPoint != m_selectedCtrlPoint && newCtrlPoint >= 0)
116    {
117        m_selectedCtrlPoint = newCtrlPoint;
118        return true;
119    }
120    return false;
121}
122
123bool Warp::drag(int x, int y)
124{
125    if (!m_bEnabled)
126        return 0;
127
128    if (m_selectedCtrlPoint < 0)
129        return false;
130
131    GLdouble objx, objy, objz;
132    GLdouble objx2, objy2, objz2;
133
134    gluUnProject(x - m_lastMouseX, -(y - m_lastMouseY), 0.95,
135                 m_modelMatrix, m_projMatrix, m_viewport,
136                 &objx, &objy, &objz);
137    gluUnProject(0, 0, 0.95,
138                 m_modelMatrix, m_projMatrix, m_viewport,
139                 &objx2, &objy2, &objz2);
140    m_pCtrlPoints[m_selectedCtrlPoint * 3 + 0] += objx-objx2;
141    m_pCtrlPoints[m_selectedCtrlPoint * 3 + 1] += objy-objy2;
142
143    m_lastMouseX = x;
144    m_lastMouseY = y;
145
146    return true;
147}
148
149void Warp::setEnabled(bool bEnabled)
150{
151    m_bEnabled = bEnabled;
152}
153
154bool Warp::getEnabled() const
155{
156    return m_bEnabled;
157}
158
159void Warp::setNumCtrlPoints(int num)
160{
161    if (num == 0)
162        return;
163
164    if (num > 8)
165        num = 8;
166    if (num <2)
167        num = 2;
168
169    if (m_pCtrlPoints)
170        delete [] m_pCtrlPoints;
171    m_numCtrlPoints = num;
172    m_pCtrlPoints = new float[num*num*3];
173    reset();
174}
175
176int Warp::getNumCtrlPoints() const
177{
178    return m_numCtrlPoints;
179}
180
181void Warp::setZoom(float zoom)
182{
183    m_zoom = zoom;
184}
185
186float Warp::getZoom() const
187{
188    return m_zoom;
189}
190
191void Warp::setGridSize(int gridSize)
192{
193    m_gridSize = gridSize;
194}
195
196int Warp::getGridSize() const
197{
198    return m_gridSize;
199}
200
201void Warp::setShowCtrlPoints(bool bShow)
202{
203    m_bShowCtrlPoints = bShow;
204}
205
206bool Warp::getShowCtrlPoints() const
207{
208    return m_bShowCtrlPoints;
209}
210
211void Warp::reset()
212{
213    for (int y=0; y<m_numCtrlPoints; ++y) {
214        for (int x=0; x<m_numCtrlPoints; ++x) {
215            m_pCtrlPoints[(y*m_numCtrlPoints+x)*3+0] = 1.0f / (m_numCtrlPoints-1) * (float)x - 0.5f;
216            m_pCtrlPoints[(y*m_numCtrlPoints+x)*3+1] = 1.0f / (m_numCtrlPoints-1) * (float)y - 0.5f;
217            m_pCtrlPoints[(y*m_numCtrlPoints+x)*3+2] = 0.0f;
218        }
219    }
220}
221
222int Warp::pickCtrlPoint(float x, float y)
223{
224    int hits;
225
226    GLuint selectBuffer[64];
227    glSelectBuffer(sizeof(selectBuffer), selectBuffer);
228
229    glRenderMode(GL_SELECT);
230    glInitNames();
231    glPushName(~0);
232    glMatrixMode(GL_PROJECTION);
233    glLoadIdentity();
234    gluPickMatrix(x, m_viewport[3] - y, 8.0, 8.0, m_viewport);
235    glMultMatrixd(m_projMatrix);
236    glMatrixMode(GL_MODELVIEW);
237    glPushMatrix();
238    glLoadIdentity();
239    glMultMatrixd(m_modelMatrix);
240    for (int i=0; i<m_numCtrlPoints*m_numCtrlPoints; ++i) {
241        glLoadName(i);
242        glBegin(GL_POINTS);
243        glVertex3fv(&m_pCtrlPoints[i*3]);
244        glEnd();
245    }
246    glPopMatrix();
247    hits = glRenderMode(GL_RENDER);
248
249    if (hits)
250        return selectBuffer[3];
251    return ~0;
252}
253
254/**
255 * Restore the channel data from XML data.
256 *
257 * @param element Parent XML element of the warp data.
258 */
259void Warp::initFromDOMElement(const QDomElement& element)
260{
261    if (!element.isNull())
262    {
263        m_bEnabled = (element.attribute("enabled")=="true");
264        int numCtrlPoints = (int)sqrtf(element.attribute("numCtrlPoints").toInt());
265        if (numCtrlPoints != m_numCtrlPoints)
266            setNumCtrlPoints(numCtrlPoints);
267
268        int count = 0;
269        QDomElement ctrlPointElem = element.firstChildElement("ctrlPoint");
270        while (!ctrlPointElem.isNull()) {
271            if (count >= m_numCtrlPoints * m_numCtrlPoints)
272                break;
273            m_pCtrlPoints[count*3+0] = ctrlPointElem.attribute("x").toDouble();
274            m_pCtrlPoints[count*3+1] = ctrlPointElem.attribute("y").toDouble();
275            m_pCtrlPoints[count*3+2] = 0.0f;
276            ctrlPointElem = ctrlPointElem.nextSiblingElement("ctrlPoint");
277            count++;
278        }
279    }
280}
281
282/**
283 * Store the current warp data as XML data.
284 *
285 * @param name XML node name of the data.
286 * @param doc XML document to store the data.
287 * @return Current warp data as XML data.
288 */
289QDomElement Warp::domElement(const QString& name, QDomDocument& doc) const
290{
291    QDomElement de = doc.createElement(name);
292    de.setAttribute("enabled", m_bEnabled?"true":"false");
293    de.setAttribute("numCtrlPoints", m_numCtrlPoints*m_numCtrlPoints);
294    for (int i=0; i<m_numCtrlPoints*m_numCtrlPoints; ++i) {
295        QDomElement ctrlPointElem = doc.createElement("ctrlPoint");
296        ctrlPointElem.setAttribute("x", m_pCtrlPoints[i*3+0]);
297        ctrlPointElem.setAttribute("y", m_pCtrlPoints[i*3+1]);
298        de.appendChild(ctrlPointElem);
299    }
300
301    return de;
302}
Note: See TracBrowser for help on using the repository browser.