2020-10-21 17:24:01 +02:00

427 lines
14 KiB
C++
Executable File

/****************************************************************************
* VCGLib o o *
* Visual and Computer Graphics Library o o *
* _ O _ *
* Copyright(C) 2007 \/)\/ *
* Visual Computing Lab /\/| *
* ISTI - Italian National Research Council | *
* \ *
* All rights reserved. *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program 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 General Public License (http://www.gnu.org/licenses/gpl.txt) *
* for more details. *
* *
****************************************************************************/
/****************************************************************************
History
$Log: not supported by cvs2svn $
Revision 1.1 2007/10/18 08:52:06 benedetti
Initial release.
****************************************************************************/
#include <QtGui>
#include "glarea.h"
#include <wrap/qt/trackball.h>
#include <vcg/math/histogram.h>
//---------------------------------------------------------
#include <stdio.h>
#include <string.h>
#include "libfreenect.h"
#include "freenect.h"
#include <qthread.h>
#include <qmutex.h>
#include <qwaitcondition.h>
#if defined(__APPLE__)
#include <GLUT/glut.h>
#include <OpenGL/gl.h>
#include <OpenGL/glu.h>
#else
#include <GL/glut.h>
#include <GL/gl.h>
#include <GL/glu.h>
#endif
#include <math.h>
#include <wrap/io_trimesh/export_ply.h>
using namespace vcg;
class CFace;
class CVertex;
GLuint gl_depth_tex,gl_rgb_tex;
bool snapshot = false;
bool pick_depth = false;
int i_pick,j_pick;
uint16_t t_gamma[2048];
unsigned int n_frames = 0;
unsigned int last_time_on[640*480];
uint16_t last_value_on[640*480];
vcg::Point3f normals[640*480];
vcg::Point3f points[640*480];
uint16_t gl_depths[100][640*480];
uint32_t gl_depths_sum[640*480];
unsigned int curs = 0;
const float ToZ(float v){return 0.1236 * tan(v / 2842.5 + 1.1863);
}
vcg::Point3f P( int i, int j){
vcg::Point3f p;
p[2] = ToZ(gl_depths_sum[640*j+i]/100.f);
if( (p[2]>5.0) ||(p[2]< 0.5))
p[2]=6.0;
p[0] = (i - 640 / 2) * p[2] * 0.00186;
p[1] = (j - 480 / 2) * p[2] * 0.00184;
return p;
}
vcg::Point3f N(int i, int j){
vcg::Point3f n;
vcg::Point3f p = points[j*640+i];
vcg::Point3f p0 = (points[j*640+i+1]-p).Normalize();
vcg::Point3f p1 = (points[(j+1)*640+i]-p).Normalize();
n = (p0^p1).Normalize();
return n;
// n= vcg::Point3f(ToZ(kinect_qt::gl_depth_front[640*j+i+1]) - ToZ(kinect_qt::gl_depth_front[640*j+i-1]),
// ToZ(kinect_qt::gl_depth_front[640*(j+1)+i]) -ToZ(kinect_qt::gl_depth_front[640*(j+1)+i]) ,
// 0.002);
// n.Normalize();
// return n;
}
void GLArea::paintGL()
{
n_frames++;
kinect_qt::qbackbuf_mutex.lock();
while ( kinect_qt::got_frames < 2) {
kinect_qt::qwait.wait(& kinect_qt::qbackbuf_mutex);
}
memcpy( kinect_qt::gl_rgb_front, kinect_qt::gl_rgb_back, sizeof( kinect_qt::gl_rgb_back));
for(unsigned int i = 0; i < 640*480;++i)
gl_depths_sum[i] -= gl_depths[curs][i];
memcpy( gl_depths[curs], kinect_qt::gl_depth_front, sizeof( kinect_qt::gl_depth_front));
for(unsigned int i = 0; i < 640*480;++i)
gl_depths_sum[i] += gl_depths[curs][i];
curs=(curs+1)%100;
if(pick_depth){
printf("depth %d \n",kinect_qt::gl_depth_front[640*j_pick+i_pick]);
vcg::Point3f p = P(i_pick,480-j_pick);
printf("p3: %f %f %f \n",p[0],p[1],p[2]);
pick_depth = false;
}
if(1) {
for(unsigned int i = 0; i < 640;++i)
for(unsigned int j = 0; j < 480;++j){
if(kinect_qt::gl_depth_front[640*j +i ]>=2047)
{
if(n_frames - last_time_on[j*640+i]< 15)
kinect_qt::gl_depth_front[640*j +i ] = last_value_on[j*640+i];
}else{
last_value_on[j*640+i] = kinect_qt::gl_depth_front[640*j +i ];
last_time_on[j*640+i] = n_frames;
}
}
}
vcg::Color4b im[640*480];
for (unsigned int i=0; i<FREENECT_FRAME_PIX; i++) {
int pval = t_gamma[kinect_qt::gl_depth_front[i]];
int lb = pval & 0xff;
switch (pval>>8) {
case 0:
im[i][0] = 255;
im[i][1] = 255-lb;
im[i][2] = 255-lb;
break;
case 1:
im[i][0] = 255;
im[i][1] = lb;
im[i][2] = 0;
break;
case 2:
im[i][0] = 255-lb;
im[i][1] = 255;
im[i][2] = 0;
break;
case 3:
im[i][0] = 0;
im[i][1] = 255;
im[i][2] = lb;
break;
case 4:
im[i][0] = 0;
im[i][1] = 255-lb;
im[i][2] = 255;
break;
case 5:
im[i][0] = 0;
im[i][1] = 0;
im[i][2] = 255-lb;
break;
default:
im[i][0] = 0;
im[i][1] = 0;
im[i][2] = 0;
break;
}
}
for(unsigned int i = 0; i < 640;++i)
for(unsigned int j = 0; j< 480;++j){
points[640*j+i] = P(i,480-j);
}
for(unsigned int i = 0; i < 640;++i)
for(unsigned int j = 0; j< 480;++j){
normals[640*j+i] = N(i,j);
}
kinect_qt::qbackbuf_mutex.unlock();
kinect_qt:: got_frames = 0;
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
if(0)
{
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, gl_depth_tex);
vcg::Color4b c;
// glPixelTransferf(GL_RED_SCALE,32.0);
// glTexImage2D(GL_TEXTURE_2D, 0, 1, 640, 480, 0, GL_LUMINANCE, GL_UNSIGNED_SHORT, kinect_qt::gl_depth_front);
glTexImage2D(GL_TEXTURE_2D, 0, 3, 640, 480, 0, GL_RGBA, GL_UNSIGNED_BYTE, im);
glPixelTransferf(GL_RED_SCALE,1.0);
glBegin(GL_TRIANGLE_FAN);
glColor4f(255.0f, 255.0f, 255.0f, 255.0f);
glTexCoord2f(0, 0); glVertex3f(-1,1,0);
glTexCoord2f(1, 0); glVertex3f(0,1,0);
glTexCoord2f(1, 1); glVertex3f(0,-1,0);
glTexCoord2f(0, 1);glVertex3f(-1,-1,0);
glEnd();
}// colored
else
{
glDisable(GL_TEXTURE_2D);
glEnable(GL_LIGHTING);
glColor3f(1,1,1);
glViewport(0,0,640,480);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
float w = 0.3;
glFrustum( w,-w, w/1.5, -w/1.5,0.5,6.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(0,0,0,0,0,1,0,1,0);
// glPointSize(2.0);
glBegin(GL_POINTS);
for(unsigned int i = 0; i < 640*480;++i){
glNormal(normals[i]);
glVertex(points[i]);
}
glEnd();
}
{
glEnable(GL_TEXTURE_2D);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glViewport(0,0,1280,480);
glBindTexture(GL_TEXTURE_2D, gl_rgb_tex);
glTexImage2D(GL_TEXTURE_2D, 0, 3, 640, 480, 0, GL_RGB, GL_UNSIGNED_BYTE, kinect_qt::gl_rgb_front);
glBegin(GL_TRIANGLE_FAN);
glColor4f(255.0f, 255.0f, 255.0f, 255.0f);
glTexCoord2f(0, 0); glVertex3f(0,1,0);
glTexCoord2f(1, 0); glVertex3f(1,1,0);
glTexCoord2f(1, 1); glVertex3f(1,-1,0);
glTexCoord2f(0, 1);glVertex3f(0,-1,0);
glEnd();
}
if(snapshot){
snapshot = false;
CMesh m;
CMesh::VertexIterator vi = vcg::tri::Allocator<CMesh>::AddVertices(m,640*480);
for(unsigned int i = 0; vi != m.vert.end(); ++vi,++i){
(*vi).N() = normals[i];
(*vi).P() = points[i];
//if((*vi).P()[2] <0)
// if(n_frames - last_time_on[i]>3)
// vcg::tri::Allocator<CMesh>::DeleteVertex(m,*vi);
}
// discard high rms
// float rms = 0;
for(unsigned int i = 0; i < 640*480;++i){
// vcg::Distribution<float> d;
float vmin = 2047,vmax=0;
for(unsigned int c = 0; c < 100;++c) {
vmin=std::min<float>(vmin,gl_depths[c][i]);
vmax=std::max<float>(vmax,gl_depths[c][i]);
}
// d.Add(gl_depths[c][i]);
// rms = d.RMS();
// if(rms>500)
if((vmax-vmin)>20)
vcg::tri::Allocator<CMesh>::DeleteVertex(m,m.vert[i]);
}
vcg::tri::UpdateBounding<CMesh>::Box(m);
vcg::tri::io::ExporterPLY<CMesh>::Save(m,"out.ply",vcg::tri::io::Mask::IOM_VERTNORMAL |vcg::tri::io::Mask::IOM_VERTCOORD);
}
}
//---------------------------------------------
GLArea::~GLArea(){
kinect_qt::kinect_thread.terminate();
}
GLArea::GLArea (QWidget * parent)
:QGLWidget (parent)
{
drawmode= SMOOTH;
QTimer *timer = new QTimer(this);
connect(timer, SIGNAL(timeout()), this, SLOT(update()));
timer->start(50);
}
void GLArea::initializeGL ()
{
glClearColor(0, 0, 0, 0);
glEnable(GL_BLEND);
glEnable(GL_LIGHT0);
glEnable(GL_COLOR_MATERIAL);
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glShadeModel(GL_SMOOTH);
glGenTextures(1, &gl_depth_tex);
glBindTexture(GL_TEXTURE_2D, gl_depth_tex);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glGenTextures(1, &gl_rgb_tex);
glBindTexture(GL_TEXTURE_2D, gl_rgb_tex);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
static bool first = true;
if(first){
first = false;
kinect_qt::start_kinect();
}
int i;
for (i=0; i<2048; i++) {
float v = i/2048.0;
v = powf(v, 3)* 6;
t_gamma[i] = v*6*256;
}
for (i=0; i<640*480; i++) {
last_time_on[i]=0;
last_value_on[i]=2049;
}
}
void GLArea::resizeGL (int w, int h)
{
glViewport (0, 0, (GLsizei) w, (GLsizei) h);
initializeGL();
}
void GLArea::keyReleaseEvent (QKeyEvent * e)
{
e->ignore ();
if (e->key () == Qt::Key_Control)
track.ButtonUp (QT2VCG (Qt::NoButton, Qt::ControlModifier));
if (e->key () == Qt::Key_Shift)
track.ButtonUp (QT2VCG (Qt::NoButton, Qt::ShiftModifier));
if (e->key () == Qt::Key_Alt)
track.ButtonUp (QT2VCG (Qt::NoButton, Qt::AltModifier));
updateGL ();
}
void GLArea::keyPressEvent (QKeyEvent * e)
{
e->ignore ();
if (e->key () == Qt::Key_Control)
track.ButtonDown (QT2VCG (Qt::NoButton, Qt::ControlModifier));
if (e->key () == Qt::Key_Shift)
track.ButtonDown (QT2VCG (Qt::NoButton, Qt::ShiftModifier));
if (e->key () == Qt::Key_Alt)
track.ButtonDown (QT2VCG (Qt::NoButton, Qt::AltModifier));
updateGL ();
}
void GLArea::mousePressEvent (QMouseEvent * e)
{
e->accept();
pick_depth = true;
i_pick = e->x();
j_pick = e->y();
snapshot = true;
// e->accept ();
// setFocus ();
// track.MouseDown (e->x (), height () - e->y (), QT2VCG (e->button (), e->modifiers ()));
// updateGL ();
}
void GLArea::mouseMoveEvent (QMouseEvent * e)
{
// if (e->buttons ()) {
// track.MouseMove (e->x (), height () - e->y ());
// updateGL ();
// }
}
void GLArea::mouseReleaseEvent (QMouseEvent * e)
{
// track.MouseUp (e->x (), height () - e->y (), QT2VCG (e->button (), e->modifiers ()));
// updateGL ();
}
void GLArea::wheelEvent (QWheelEvent * e)
{
// const int WHEEL_STEP = 120;
// track.MouseWheel (e->delta () / float (WHEEL_STEP), QTWheel2VCG (e->modifiers ()));
// updateGL ();
}