qtgl.cpp 13.2 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]);
Sylvain Thery's avatar
Sylvain Thery committed
72 73
}

74 75 76 77 78 79 80 81 82 83 84 85 86 87 88
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;

//	float Z[3] = { 0.0f, 0.0f, 1.0f };
//	axis_to_quat(Z, 0.0f, m_cbs->curquat());

	setParamObject(width,pos);

	recalcModelView();
}


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 264 265 266
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);
		}
	}
}

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

		switch (m_current_button)
Pierre Kraemer's avatar
merge..  
Pierre Kraemer committed
276
		{
277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296
			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
297 298 299 300 301 302 303 304 305 306
				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());
				}
307 308
			}
				break;
Pierre Kraemer's avatar
merge..  
Pierre Kraemer committed
309 310
		}

311 312 313 314 315
		beginx = x;
		beginy = y;
		newModel = 1;
		updateGL();
	}
Sylvain Thery's avatar
Sylvain Thery committed
316 317

	if (m_cbs)
Sylvain Thery's avatar
Sylvain Thery committed
318
		m_cbs->cb_mouseMove(event->buttons(), event->x(), getHeight() - event->y());
Sylvain Thery's avatar
Sylvain Thery committed
319 320
}

321
void GLWidget::wheelEvent(QWheelEvent* event)
Sylvain Thery's avatar
Sylvain Thery committed
322
{
323 324 325
	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
326

327 328 329 330
		if (event->delta() > 0)
			m_cbs->trans_z() += wl;
		else
			m_cbs->trans_z() -= wl;
Sylvain Thery's avatar
Sylvain Thery committed
331

332 333 334
		newModel = 1;
		updateGL();
	}
Pierre Kraemer's avatar
Pierre Kraemer committed
335 336 337

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

340

341
void GLWidget::keyPressEvent(QKeyEvent* event)
Sylvain Thery's avatar
Sylvain Thery committed
342
{
343
	if (event->key() == Qt::Key_Escape)
Sylvain Thery's avatar
Sylvain Thery committed
344
	{
Pierre Kraemer's avatar
Pierre Kraemer committed
345
		close();
Sylvain Thery's avatar
Sylvain Thery committed
346
		m_cbs->close();
347
		return;
Sylvain Thery's avatar
Sylvain Thery committed
348
	}
Sylvain Thery's avatar
Sylvain Thery committed
349

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

Pierre Kraemer's avatar
Pierre Kraemer committed
352
	int k = event->key();
353 354
	if ( (k >= 65) && (k <= 91) && !(event->modifiers() & Qt::ShiftModifier) )
		k += 32;
Sylvain Thery's avatar
Sylvain Thery committed
355

Pierre Kraemer's avatar
Pierre Kraemer committed
356
	if (m_cbs)
Sylvain Thery's avatar
Sylvain Thery committed
357 358 359 360 361
		m_cbs->cb_keyPress(k);
}

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

Sylvain Thery's avatar
Sylvain Thery committed
364 365
	m_state_modifier = event->modifiers();
    int k = event->key();
366 367

    // align on axis
368
	if ((k == 'Z') && (event->modifiers() & Qt::ShiftModifier))
369
	{
370 371 372
	    float Z[3] = { 0.0f, 0.0f, 1.0f };
		axis_to_quat(Z, 0.0f, m_cbs->curquat());
		newModel = 1;
373 374 375
		updateGL();
	}

376
	if ((k == 'Y') && (event->modifiers() & Qt::ShiftModifier))
377
	{
378 379 380
		float X[3] = { 1.0f, 0.0f, 0.0f };
		axis_to_quat(X, M_PI / 2.0f, m_cbs->curquat());
		newModel = 1;
381 382 383
		updateGL();
	}

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

Pierre Kraemer's avatar
merge..  
Pierre Kraemer committed
392
    if ( (k >= 65) && (k <= 91) && (event->modifiers() != Qt::ShiftModifier) )
393
    	k += 32;
Sylvain Thery's avatar
Sylvain Thery committed
394 395 396 397 398

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

399 400 401 402 403 404 405 406 407

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
408 409 410 411 412 413 414 415 416 417 418 419 420 421 422
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));
}

423

424 425 426 427 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
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));
501
	recalcModelView() ;
502 503 504 505 506 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
}

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
547

Pierre Kraemer's avatar
merge..  
Pierre Kraemer committed
548
} // namespace QT
Sylvain Thery's avatar
Sylvain Thery committed
549

Pierre Kraemer's avatar
merge..  
Pierre Kraemer committed
550 551 552
} // namespace Utils

} // namespace CGoGN