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

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