qtgl.cpp 13.3 KB
Newer Older
Sylvain Thery's avatar
Sylvain Thery committed
1 2 3
/*******************************************************************************
* CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps  *
* version 0.1                                                                  *
4
* Copyright (C) 2009-2012, IGG Team, LSIIT, University of Strasbourg           *
Sylvain Thery's avatar
Sylvain Thery committed
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
*                                                                              *
* This library is free software; you can redistribute it and/or modify it      *
* under the terms of the GNU Lesser General Public License as published by the *
* Free Software Foundation; either version 2.1 of the License, or (at your     *
* option) any later version.                                                   *
*                                                                              *
* This library is distributed in the hope that it will be useful, but WITHOUT  *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or        *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License  *
* for more details.                                                            *
*                                                                              *
* You should have received a copy of the GNU Lesser General Public License     *
* along with this library; if not, write to the Free Software Foundation,      *
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.           *
*                                                                              *
20
* Web site: http://cgogn.unistra.fr/                                           *
Sylvain Thery's avatar
Sylvain Thery committed
21 22 23
* Contact information: cgogn@unistra.fr                                        *
*                                                                              *
*******************************************************************************/
Pierre Kraemer's avatar
merge..  
Pierre Kraemer committed
24

Sylvain Thery's avatar
Sylvain Thery committed
25 26 27
#include <GL/glew.h>
#include <iostream>
#include "Utils/trackball.h"
28 29
#include "Utils/Qt/qtgl.h"
#include "Utils/Qt/qtSimple.h"
30
#include "glm/gtc/type_precision.hpp"
31
#include "Utils/GLSLShader.h"
Sylvain Thery's avatar
Sylvain Thery committed
32 33 34

namespace CGoGN
{
Pierre Kraemer's avatar
merge..  
Pierre Kraemer committed
35

Sylvain Thery's avatar
Sylvain Thery committed
36 37
namespace Utils
{
Pierre Kraemer's avatar
merge..  
Pierre Kraemer committed
38

Sylvain Thery's avatar
Sylvain Thery committed
39 40 41
namespace QT
{

Pierre Kraemer's avatar
Pierre Kraemer committed
42
float GLWidget::FAR_PLANE = 500.0f;
43

Sylvain Thery's avatar
Sylvain Thery committed
44
GLWidget::GLWidget(SimpleQT* cbs, QWidget *parent) :
Pierre Kraemer's avatar
merge..  
Pierre Kraemer committed
45 46
	QGLWidget(QGLFormat(QGL::Rgba | QGL::DoubleBuffer| QGL::DepthBuffer), parent),
	m_cbs(cbs),
Pierre Kraemer's avatar
Pierre Kraemer committed
47 48
	m_state_modifier(0),
	allow_rotation(true)
Sylvain Thery's avatar
Sylvain Thery committed
49 50 51 52 53
{
	makeCurrent();
	glewInit();

	newModel = 1;
Pierre Kraemer's avatar
merge..  
Pierre Kraemer committed
54 55
	m_cbs->trans_x() = 0.;
	m_cbs->trans_y() = 0.;
Sylvain Thery's avatar
Sylvain Thery committed
56
	float f = FAR_PLANE;
Pierre Kraemer's avatar
merge..  
Pierre Kraemer committed
57 58
	m_cbs->trans_z() = -f / 5.0f;
	foc = 2.0f;
Sylvain Thery's avatar
Sylvain Thery committed
59 60

	// init trackball
61
	trackball(m_cbs->curquat(), 0.0f, 0.0f, 0.0f, 0.0f);
Sylvain Thery's avatar
Sylvain Thery committed
62 63 64 65 66 67 68 69
}

GLWidget::~GLWidget()
{
}

void GLWidget::setParamObject(float width, float* pos)
{
Pierre Kraemer's avatar
merge..  
Pierre Kraemer committed
70 71
	m_obj_sc = ((FAR_PLANE / 5.0f) / foc) / width;
	m_obj_pos = glm::vec3(-pos[0], -pos[1], -pos[2]);
72 73
	m_obj_pos_save = glm::vec3(pos[0], pos[1], pos[2]);
	m_obj_width = width;
Sylvain Thery's avatar
Sylvain Thery committed
74 75
}

76 77 78 79 80
void GLWidget::resetCenterOfRotation(float width, float* pos)
{
	m_cbs->trans_x() = 0.;
	m_cbs->trans_y() = 0.;
	m_cbs->trans_z() = -FAR_PLANE / 5.0f;
81
	m_obj_sc = ((FAR_PLANE / 5.0f) / foc) / width;
82

83 84
	m_obj_pos = glm::vec3(-pos[0], -pos[1], -pos[2]);
	newModel=1;
85 86 87 88

}


Pierre Kraemer's avatar
Pierre Kraemer committed
89 90 91 92 93
void GLWidget::setRotation(bool b)
{
	allow_rotation = b;
}

Sylvain Thery's avatar
Sylvain Thery committed
94 95
void  GLWidget::setFocal(float df)
{
96 97
	if (df > 5.0f)
		df = 5.0f;
Pierre Kraemer's avatar
merge..  
Pierre Kraemer committed
98 99
	if (df < 0.2f)
		df = 0.2f;
Sylvain Thery's avatar
Sylvain Thery committed
100

Pierre Kraemer's avatar
merge..  
Pierre Kraemer committed
101
	m_obj_sc *= foc / df;
Sylvain Thery's avatar
Sylvain Thery committed
102 103

	foc = df;
Pierre Kraemer's avatar
merge..  
Pierre Kraemer committed
104
	resizeGL(W, H);
Sylvain Thery's avatar
Sylvain Thery committed
105 106 107 108 109 110 111 112 113 114 115 116 117 118
}

QSize GLWidget::minimumSizeHint() const
{
    return QSize(200, 200);
}

QSize GLWidget::sizeHint() const
{
    return QSize(500, 500);
}

void GLWidget::recalcModelView()
{
119 120 121 122 123 124
	m_cbs->modelViewMatrix()= glm::mat4(1.0f);

	// positionne l'objet / mvt souris
	oglTranslate(m_cbs->trans_x(), m_cbs->trans_y(), m_cbs->trans_z());

	// tourne l'objet / mvt souris
Sylvain Thery's avatar
Sylvain Thery committed
125
	glm::mat4 m;
126
	build_rotmatrixgl3(m, m_cbs->curquat());
Pierre Kraemer's avatar
Pierre Kraemer committed
127
	// update matrice
128
	m_cbs->modelViewMatrix() *= m;
Sylvain Thery's avatar
Sylvain Thery committed
129

130 131 132 133
	// transfo pour que l'objet soit centre et a la bonne taille
	oglScale(m_obj_sc, m_obj_sc, m_obj_sc);
	oglTranslate(m_obj_pos[0], m_obj_pos[1], m_obj_pos[2]);

134
	// ajout transformation
135
	// m_cbs->modelViewMatrix() *= m_cbs->transfoMatrix();
136

137 138 139 140 141 142 143 144
	newModel = 0;

	if (m_cbs)
		m_cbs->cb_updateMatrix();
}

void GLWidget::changeCenterOfRotation(const glm::vec3& newCenter)
{
145
	glm::mat4 storeMVM(m_cbs->modelViewMatrix());
146

147
	m_cbs->modelViewMatrix() = glm::mat4(1.0f);
148

Sylvain Thery's avatar
Sylvain Thery committed
149
	// positionne l'objet / mvt souris
Pierre Kraemer's avatar
merge..  
Pierre Kraemer committed
150
	oglTranslate(m_cbs->trans_x(), m_cbs->trans_y(), m_cbs->trans_z());
Sylvain Thery's avatar
Sylvain Thery committed
151 152

	// tourne l'objet / mvt souris
153
	glm::mat4 m;
154
	build_rotmatrixgl3(m, m_cbs->curquat());
Sylvain Thery's avatar
Sylvain Thery committed
155 156 157
	// update matrice
	m_cbs->modelViewMatrix() *= m;

158 159 160
	// ajout transformation in screen
	m_cbs->modelViewMatrix()*= m_cbs->transfoMatrix();

Sylvain Thery's avatar
Sylvain Thery committed
161
	// transfo pour que l'objet soit centre et a la bonne taille
Pierre Kraemer's avatar
merge..  
Pierre Kraemer committed
162
	oglScale(m_obj_sc, m_obj_sc, m_obj_sc);
Sylvain Thery's avatar
Sylvain Thery committed
163 164
	oglTranslate(m_obj_pos[0], m_obj_pos[1], m_obj_pos[2]);

165
	oglTranslate(newCenter[0], newCenter[1], newCenter[2]);
166
	oglScale(1.0f / m_obj_sc, 1.0f / m_obj_sc, 1.0f / m_obj_sc);
Sylvain Thery's avatar
Sylvain Thery committed
167

168
	m = glm::inverse(m_cbs->transfoMatrix());
169
	m_cbs->modelViewMatrix() *= m;
170 171 172 173 174 175

	matrix_to_quat( m_cbs->curquat(), m_cbs->modelViewMatrix());

	m_cbs->trans_x() = m_cbs->modelViewMatrix()[3][0];
	m_cbs->trans_y() = m_cbs->modelViewMatrix()[3][1];
	m_cbs->trans_z() = m_cbs->modelViewMatrix()[3][2];
176

177
	m_cbs->modelViewMatrix() = storeMVM;
178

179
	m_obj_pos = glm::vec3(-newCenter[0], -newCenter[1], -newCenter[2]);
Sylvain Thery's avatar
Sylvain Thery committed
180 181
}

182 183 184 185
glm::vec3& GLWidget::getObjPos()
{
	return m_obj_pos ;
}
186

Sylvain Thery's avatar
Sylvain Thery committed
187 188 189 190 191 192 193 194 195 196
void GLWidget::initializeGL()
{
	glEnable(GL_DEPTH_TEST);

	if (m_cbs)
		m_cbs->cb_initGL();
}

void GLWidget::resizeGL(int w, int h)
{
Sylvain Thery's avatar
Sylvain Thery committed
197 198
	W = w;
	H = h;
Sylvain Thery's avatar
Sylvain Thery committed
199

Pierre Kraemer's avatar
merge..  
Pierre Kraemer committed
200
	glViewport(0, 0, W, H);
Sylvain Thery's avatar
Sylvain Thery committed
201
	float f = FAR_PLANE;
Pierre Kraemer's avatar
merge..  
Pierre Kraemer committed
202
	m_cbs->projectionMatrix() = glm::frustum(-1.0f, 1.0f, -1.0f * H / W, 1.0f * H / W, foc, f);
Sylvain Thery's avatar
Sylvain Thery committed
203 204 205 206 207 208 209 210 211 212 213

	recalcModelView();
}

void GLWidget::paintGL()
{
	if (newModel)
	    recalcModelView();

	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	if (m_cbs)
214 215
	{
		Utils::GLSLShader::s_current_matrices = m_cbs->matricesPtr();
Sylvain Thery's avatar
Sylvain Thery committed
216
		m_cbs->cb_redraw();
217
	}
Sylvain Thery's avatar
Sylvain Thery committed
218 219 220 221 222 223
}

void GLWidget::mousePressEvent(QMouseEvent* event)
{
	beginx = event->x();
	beginy = event->y();
224
	clickPoint = event->pos();
Sylvain Thery's avatar
Sylvain Thery committed
225 226 227
	m_current_button = event->button();

	if (m_cbs)
228
		m_cbs->cb_mousePress(event->button(), event->x(), getHeight() - event->y());
Sylvain Thery's avatar
Sylvain Thery committed
229
	setFocus(Qt::MouseFocusReason);
Sylvain Thery's avatar
Sylvain Thery committed
230 231 232 233 234
}

void GLWidget::mouseReleaseEvent(QMouseEvent* event)
{
	if (m_cbs)
235 236 237 238
		m_cbs->cb_mouseRelease(event->button(), event->x(), getHeight() - event->y());

	if(event->pos() == clickPoint)
		mouseClickEvent(event) ;
Sylvain Thery's avatar
Sylvain Thery committed
239 240
}

241
void GLWidget::mouseClickEvent(QMouseEvent* event)
Sylvain Thery's avatar
Sylvain Thery committed
242
{
243

244 245 246
	if (m_cbs)
		m_cbs->cb_mouseClick(event->button(), event->x(), getHeight() - event->y());
}
Sylvain Thery's avatar
Sylvain Thery committed
247

248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263
void GLWidget::mouseDoubleClickEvent(QMouseEvent* event)
{
	if (event->button()==1)
	{
		GLint x = event->x();
		GLint y = getHeight() - event->y();
		GLfloat depth;
		glReadPixels(x, y, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &depth);
		if (depth < 1.0f)
		{
			glm::i32vec4 viewport;
			glGetIntegerv(GL_VIEWPORT, &(viewport[0]));
			glm::vec3 win(x, y, depth);
			glm::vec3 P = glm::unProject(win, m_cbs->modelViewMatrix(), m_cbs->projectionMatrix(), viewport);
			changeCenterOfRotation(P);
		}
264 265 266 267 268
		else
		{
			resetCenterOfRotation(m_obj_width, static_cast<float*>(&m_obj_pos_save.x)) ;
			updateGL();
		}
269 270 271
	}
}

272 273
void GLWidget::mouseMoveEvent(QMouseEvent* event)
{
274
	// move object only if no special keys pressed
275
	if (!(m_state_modifier & ( Qt::ShiftModifier | Qt::ControlModifier | Qt::AltModifier | Qt::MetaModifier)))
Sylvain Thery's avatar
Sylvain Thery committed
276
	{
277 278 279 280
		int x = event->x();
		int y = event->y();

		switch (m_current_button)
Pierre Kraemer's avatar
merge..  
Pierre Kraemer committed
281
		{
282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301
			case Qt::RightButton:
			{
				float wl;
				if (m_cbs->trans_z() > -20.0f)
					wl = 20.0f / foc;
				else
					wl = -2.0f * m_cbs->trans_z() / foc;
				m_cbs->trans_x() += wl / W * (x - beginx);
				m_cbs->trans_y() += wl / H * (beginy - y);
			}
				break;
			case Qt::MidButton:
			{
				float wl = -0.5f * FAR_PLANE / foc;
				m_cbs->trans_z() -= wl / W * (x - beginx);
				m_cbs->trans_z() -= wl / H * (y - beginy);
			}
				break;
			case Qt::LeftButton:
			{
Pierre Kraemer's avatar
Pierre Kraemer committed
302 303 304 305 306 307 308 309 310 311
				if(allow_rotation)
				{
					trackball(
						m_cbs->lastquat(),
						(2.0f * beginx - W) / W,
						(H - 2.0f * beginy) / H,
						(2.0f * x - W) / W,(H - 2.0f * y) / H
					);
					add_quats(m_cbs->lastquat(), m_cbs->curquat(), m_cbs->curquat());
				}
312 313
			}
				break;
Pierre Kraemer's avatar
merge..  
Pierre Kraemer committed
314 315
		}

316 317 318 319 320
		beginx = x;
		beginy = y;
		newModel = 1;
		updateGL();
	}
Sylvain Thery's avatar
Sylvain Thery committed
321 322

	if (m_cbs)
Sylvain Thery's avatar
Sylvain Thery committed
323
		m_cbs->cb_mouseMove(event->buttons(), event->x(), getHeight() - event->y());
Sylvain Thery's avatar
Sylvain Thery committed
324 325
}

326
void GLWidget::wheelEvent(QWheelEvent* event)
Sylvain Thery's avatar
Sylvain Thery committed
327
{
328 329 330
	if (!(m_state_modifier & ( Qt::ShiftModifier | Qt::ControlModifier | Qt::AltModifier | Qt::MetaModifier)))
	{
		float wl = -0.05f * FAR_PLANE / foc;
Sylvain Thery's avatar
Sylvain Thery committed
331

332 333 334 335
		if (event->delta() > 0)
			m_cbs->trans_z() += wl;
		else
			m_cbs->trans_z() -= wl;
Sylvain Thery's avatar
Sylvain Thery committed
336

337 338 339
		newModel = 1;
		updateGL();
	}
Pierre Kraemer's avatar
Pierre Kraemer committed
340 341 342

	if (m_cbs)
		m_cbs->cb_wheelEvent(event->delta(), event->x(), getHeight() - event->y());
Sylvain Thery's avatar
Sylvain Thery committed
343 344
}

345

346
void GLWidget::keyPressEvent(QKeyEvent* event)
Sylvain Thery's avatar
Sylvain Thery committed
347
{
348
	if (event->key() == Qt::Key_Escape)
Sylvain Thery's avatar
Sylvain Thery committed
349
	{
Pierre Kraemer's avatar
Pierre Kraemer committed
350
		close();
Sylvain Thery's avatar
Sylvain Thery committed
351
		m_cbs->close();
352
		return;
Sylvain Thery's avatar
Sylvain Thery committed
353
	}
Sylvain Thery's avatar
Sylvain Thery committed
354

Pierre Kraemer's avatar
Pierre Kraemer committed
355
	m_state_modifier = event->modifiers();
Sylvain Thery's avatar
Sylvain Thery committed
356

Pierre Kraemer's avatar
Pierre Kraemer committed
357
	int k = event->key();
358 359
	if ( (k >= 65) && (k <= 91) && !(event->modifiers() & Qt::ShiftModifier) )
		k += 32;
Sylvain Thery's avatar
Sylvain Thery committed
360

Pierre Kraemer's avatar
Pierre Kraemer committed
361
	if (m_cbs)
Sylvain Thery's avatar
Sylvain Thery committed
362 363 364 365 366
		m_cbs->cb_keyPress(k);
}

void GLWidget::keyReleaseEvent(QKeyEvent *event)
{
367
//	QWidget::keyReleaseEvent(event);
Sylvain Thery's avatar
Sylvain Thery committed
368

Sylvain Thery's avatar
Sylvain Thery committed
369 370
	m_state_modifier = event->modifiers();
    int k = event->key();
371 372

    // align on axis
373
	if ((k == 'Z') && (event->modifiers() & Qt::ShiftModifier))
374
	{
375 376 377
	    float Z[3] = { 0.0f, 0.0f, 1.0f };
		axis_to_quat(Z, 0.0f, m_cbs->curquat());
		newModel = 1;
378 379 380
		updateGL();
	}

381
	if ((k == 'Y') && (event->modifiers() & Qt::ShiftModifier))
382
	{
383 384 385
		float X[3] = { 1.0f, 0.0f, 0.0f };
		axis_to_quat(X, M_PI / 2.0f, m_cbs->curquat());
		newModel = 1;
386 387 388
		updateGL();
	}

389
	if ((k == 'X') && (event->modifiers() & Qt::ShiftModifier))
390
	{
391 392 393
		float Y[3] = { 0.0f, 1.0f, 0.0f };
		axis_to_quat(Y, -M_PI / 2.0f, m_cbs->curquat());
		newModel = 1;
394 395 396
		updateGL();
	}

Pierre Kraemer's avatar
merge..  
Pierre Kraemer committed
397
    if ( (k >= 65) && (k <= 91) && (event->modifiers() != Qt::ShiftModifier) )
398
    	k += 32;
Sylvain Thery's avatar
Sylvain Thery committed
399 400 401 402 403

	if (m_cbs)
		m_cbs->cb_keyRelease(k);
}

404 405 406 407 408 409 410 411 412

void GLWidget::glMousePosition(int& x, int& y)
{
	QPoint xy = mapFromGlobal(QCursor::pos());
	x = xy.x();
	y = getHeight() - xy.y();
}


Sylvain Thery's avatar
Sylvain Thery committed
413 414 415 416 417 418 419 420 421 422 423 424 425 426 427
void GLWidget::oglRotate(float angle, float x, float y, float z)
{
	m_cbs->modelViewMatrix() = glm::rotate(m_cbs->modelViewMatrix(), angle, glm::vec3(x,y,z));
}

void GLWidget::oglTranslate(float tx, float ty, float tz)
{
	m_cbs->modelViewMatrix() = glm::translate(m_cbs->modelViewMatrix(), glm::vec3(tx,ty,tz));
}

void GLWidget::oglScale(float sx, float sy, float sz)
{
	m_cbs->modelViewMatrix() = glm::scale(m_cbs->modelViewMatrix(), glm::vec3(sx,sy,sz));
}

428

429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505
GLfloat GLWidget::getOrthoScreenRay(int x, int y, Geom::Vec3f& rayA, Geom::Vec3f& rayB, int radius)
{
	// get Z from depth buffer
	int yy = y;
	GLfloat depth_t[25];
	glReadPixels(x-2, yy-2, 5, 5, GL_DEPTH_COMPONENT, GL_FLOAT, depth_t);

	GLfloat depth=0.0f;
	unsigned int nb=0;
	for (unsigned int i=0; i< 25; ++i)
	{
		if (depth_t[i] != 1.0f)
		{
			depth += depth_t[i];
			nb++;
		}
	}
	if (nb>0)
		depth /= float(nb);
	else
		depth = 0.5f;

	glm::i32vec4 viewport;
	glGetIntegerv(GL_VIEWPORT, &(viewport[0]));

	glm::vec3 win(x, yy, 0.0f);

	glm::vec3 P = glm::unProject(win, m_cbs->modelViewMatrix(), m_cbs->projectionMatrix(), viewport);

	rayA[0] = P[0];
	rayA[1] = P[1];
	rayA[2] = P[2];

	win[2] = depth;

	P = glm::unProject(win, m_cbs->modelViewMatrix(), m_cbs->projectionMatrix(), viewport);
	rayB[0] = P[0];
	rayB[1] = P[1];
	rayB[2] = P[2];

	if (depth == 1.0f)	// depth vary in [0-1]
		win[2] = 0.5f;

	win[0] += radius;
	P = glm::unProject(win, m_cbs->modelViewMatrix(), m_cbs->projectionMatrix(), viewport);
	Geom::Vec3f Q;
	Q[0] = P[0];
	Q[1] = P[1];
	Q[2] = P[2];

	// compute & return distance
	Q -= rayB;
	return float(Q.norm());
}

float GLWidget::getWidthInWorld(unsigned int pixel_width, const Geom::Vec3f& center)
{

	glm::i32vec4 viewport;
	glGetIntegerv(GL_VIEWPORT, &(viewport[0]));

	glm::vec3 win = glm::project(glm::vec3(center[0],center[1],center[2]), m_cbs->modelViewMatrix(), m_cbs->projectionMatrix(), viewport);

	win[0]-= pixel_width/2;

	glm::vec3 P = glm::unProject(win, m_cbs->modelViewMatrix(), m_cbs->projectionMatrix(), viewport);

	win[0] += pixel_width;

	glm::vec3 Q = glm::unProject(win, m_cbs->modelViewMatrix(), m_cbs->projectionMatrix(), viewport);

	return glm::distance(P,Q);
}

void GLWidget::transfoRotate(float angle, float x, float y, float z)
{
	m_cbs->transfoMatrix() = glm::rotate( m_cbs->transfoMatrix(), angle, glm::vec3(x,y,z));
506
	recalcModelView() ;
507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551
}

void GLWidget::transfoTranslate(float tx, float ty, float tz)
{
	m_cbs->transfoMatrix() = glm::translate( m_cbs->transfoMatrix(), glm::vec3(tx,ty,tz));
}

void GLWidget::transfoScale(float sx, float sy, float sz)
{
	m_cbs->transfoMatrix() = glm::scale( m_cbs->transfoMatrix(), glm::vec3(sx,sy,sz));
}

void GLWidget::pushTransfoMatrix()
{
	m_stack_trf.push( m_cbs->transfoMatrix());
}

bool GLWidget::popTransfoMatrix()
{
	if (m_stack_trf.empty())
		return false;
	 m_cbs->transfoMatrix() = m_stack_trf.top();
	m_stack_trf.pop();
	return true;
}

/**
 * current transfo matrix
 */
const glm::mat4& GLWidget::transfoMatrix() const { return m_cbs->transfoMatrix(); }
glm::mat4& GLWidget::transfoMatrix() { return m_cbs->transfoMatrix(); }

/**
 * current modelview matrix
 */
const glm::mat4& GLWidget::modelViewMatrix() const { return m_cbs->modelViewMatrix(); }
glm::mat4& GLWidget::modelViewMatrix() { return m_cbs->modelViewMatrix(); }

/**
 * current projection matrix
 */
const glm::mat4& GLWidget::projectionMatrix() const { return m_cbs->projectionMatrix(); }
glm::mat4& GLWidget::projectionMatrix() { return m_cbs->projectionMatrix(); }


Sylvain Thery's avatar
Sylvain Thery committed
552

Pierre Kraemer's avatar
merge..  
Pierre Kraemer committed
553
} // namespace QT
Sylvain Thery's avatar
Sylvain Thery committed
554

Pierre Kraemer's avatar
merge..  
Pierre Kraemer committed
555 556 557
} // namespace Utils

} // namespace CGoGN