2047 lines
54 KiB
Text
2047 lines
54 KiB
Text
/*
|
|
* show_gl implementation
|
|
*
|
|
* Copyright (C) Kai Lingemann, Andreas Nuechter, Jan Elseberg, Dorit Borrmann
|
|
*
|
|
* Released under the GPL version 3.
|
|
*
|
|
*/
|
|
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
#include "show/viewcull.h"
|
|
#include "show/scancolormanager.h"
|
|
|
|
bool fullydisplayed = true; // true if all points have been drawn to the screen
|
|
bool mousemoving = false; // true iff a mouse button has been pressed inside a window,
|
|
// but hs not been released
|
|
bool keypressed = false; // true iff a key button has been pressed inside a window,
|
|
// but hs not been released
|
|
double ptstodisplay = 100000;
|
|
double lastfps = idealfps; // last frame rate
|
|
int pointmode = -1;
|
|
|
|
bool smallfont = true;
|
|
bool label = true;
|
|
|
|
/**
|
|
* Displays all data (i.e., points) that are to be displayed
|
|
* @param mode spezification for drawing to screen or in selection mode
|
|
*/
|
|
void DrawPoints(GLenum mode, bool interruptable)
|
|
{
|
|
long time = GetCurrentTimeInMilliSec();
|
|
double min = 0.000000001;
|
|
double max = 1.0;
|
|
LevelOfDetail *= 1.0 + adaption_rate*(lastfps - idealfps)/idealfps;
|
|
if (LevelOfDetail > max) LevelOfDetail = max;
|
|
else if (LevelOfDetail < min) LevelOfDetail = min;
|
|
|
|
// In case of animation
|
|
if(frameNr != 0) {
|
|
cm->setMode(ScanColorManager::MODE_ANIMATION);
|
|
|
|
#ifdef USE_GL_POINTS
|
|
for(int iterator = (int)octpts.size()-1; iterator >= 0; iterator--) {
|
|
#else
|
|
for(int iterator = (int)Scan::allScans.size()-1; iterator >= 0; iterator--) {
|
|
#endif
|
|
// ignore scans that don't have any frames associated with them
|
|
if((unsigned int)iterator >= MetaMatrix.size()) continue;
|
|
// set usable frame
|
|
double* frame;
|
|
Scan::AlgoType type;
|
|
if((unsigned int)frameNr >= MetaMatrix[iterator].size()) {
|
|
// use last possible frame
|
|
frame = MetaMatrix[iterator].back();
|
|
type = MetaAlgoType[iterator].back();
|
|
} else {
|
|
frame = MetaMatrix[iterator][frameNr];
|
|
type = MetaAlgoType[iterator][frameNr];
|
|
}
|
|
if(type == Scan::INVALID) continue;
|
|
cm->selectColors(type);
|
|
glPushMatrix();
|
|
glMultMatrixd(frame);
|
|
|
|
|
|
glPointSize(pointsize);
|
|
#ifdef USE_GL_POINTS
|
|
ExtractFrustum(pointsize);
|
|
cm->selectColors(type);
|
|
if (pointmode == 1 ) {
|
|
octpts[iterator]->display();
|
|
} else {
|
|
octpts[iterator]->displayLOD(LevelOfDetail);
|
|
}
|
|
#else
|
|
for (unsigned int jterator = 0; jterator < vvertexArrayList[iterator].size(); jterator++) {
|
|
|
|
if ((jterator == 0) && vvertexArrayList[iterator][jterator]->numPointsToRender > 0) {
|
|
cm->selectColors(type);
|
|
}
|
|
|
|
if (vvertexArrayList[iterator][jterator]->numPointsToRender > 0) {
|
|
glCallList(vvertexArrayList[iterator][jterator]->name);
|
|
}
|
|
}
|
|
#endif
|
|
glPopMatrix();
|
|
}
|
|
|
|
setScansColored(0);
|
|
} else {
|
|
|
|
if(mode == GL_SELECT){
|
|
// select points mode
|
|
// ------------------
|
|
GLuint name = 0;
|
|
for(int iterator = (int)octpts.size()-1; iterator >= 0; iterator--) {
|
|
glPushMatrix();
|
|
glMultMatrixd(MetaMatrix[iterator].back());
|
|
|
|
glColor4f(1.0, 0.0, 0.0,1.0);
|
|
glPointSize(pointsize + 2.0);
|
|
for ( set<sfloat*>::iterator it = selected_points[iterator].begin();
|
|
it != selected_points[iterator].end(); it++) {
|
|
glLoadName(name++);
|
|
glBegin(GL_POINTS);
|
|
glVertex3d((*it)[0], (*it)[1], (*it)[2]);
|
|
glEnd();
|
|
}
|
|
glPointSize(pointsize);
|
|
|
|
glFlush();
|
|
glPopMatrix();
|
|
}
|
|
|
|
} else {
|
|
|
|
// draw point is normal mode
|
|
// -------------------------
|
|
|
|
if (interruptable) {
|
|
glDrawBuffer (GL_FRONT);
|
|
}
|
|
glPointSize(pointsize);
|
|
|
|
vector<int> sequence;
|
|
calcPointSequence(sequence, current_frame);
|
|
#ifdef USE_GL_POINTS
|
|
//for(int iterator = (int)octpts.size()-1; iterator >= 0; iterator--) {
|
|
for(unsigned int i = 0; i < sequence.size(); i++) {
|
|
int iterator = sequence[i];
|
|
#else
|
|
for(int iterator = (int)Scan::allScans.size()-1; iterator >= 0; iterator--) {
|
|
#endif
|
|
// ignore scans that don't have any frames associated with them
|
|
if((unsigned int)iterator >= MetaMatrix.size()) continue;
|
|
// set usable frame
|
|
double* frame;
|
|
Scan::AlgoType type;
|
|
if((unsigned int)current_frame >= MetaMatrix[iterator].size()) {
|
|
// use last possible frame
|
|
frame = MetaMatrix[iterator].back();
|
|
type = MetaAlgoType[iterator].back();
|
|
} else {
|
|
frame = MetaMatrix[iterator][current_frame];
|
|
type = MetaAlgoType[iterator][current_frame];
|
|
}
|
|
if (type == Scan::INVALID) continue;
|
|
glPushMatrix();
|
|
if (invert) // default: white points on black background
|
|
glColor4d(1.0, 1.0, 1.0, 0.0);
|
|
else // black points on white background
|
|
glColor4d(0.0, 0.0, 0.0, 0.0);
|
|
|
|
// glMultMatrixd(MetaMatrix[iterator].back());
|
|
if (current_frame != (int)MetaMatrix.back().size() - 1) {
|
|
cm->setMode(ScanColorManager::MODE_ANIMATION);
|
|
cm->selectColors(type);
|
|
}
|
|
glMultMatrixd(frame);
|
|
|
|
#ifdef USE_GL_POINTS
|
|
//cout << endl << endl; calcRay(570, 266, 1.0, 40000.0);
|
|
/* // for height mapped color in the vertex shader
|
|
GLfloat v[16];
|
|
for (unsigned int l = 0; l < 16; l++)
|
|
v[l] = MetaMatrix[iterator].back()[l];
|
|
glUniformMatrix4fvARB(glGetUniformLocationARB(p, "MYMAT"), 1, 0, v);
|
|
*/
|
|
ExtractFrustum(pointsize);
|
|
if (pointmode == 1 ) {
|
|
octpts[iterator]->display();
|
|
} else if (interruptable) {
|
|
checkForInterrupt();
|
|
glFlush();
|
|
glFinish();
|
|
if (isInterrupted()) {
|
|
glPopMatrix();
|
|
return;
|
|
}
|
|
octpts[iterator]->display();
|
|
} else {
|
|
octpts[iterator]->displayLOD(LevelOfDetail);
|
|
}
|
|
if (!selected_points[iterator].empty()) {
|
|
glColor4f(1.0, 0.0, 0.0, 1.0);
|
|
glPointSize(pointsize + 2.0);
|
|
glBegin(GL_POINTS);
|
|
for ( set<sfloat*>::iterator it = selected_points[iterator].begin();
|
|
it != selected_points[iterator].end(); it++) {
|
|
glVertex3d((*it)[0], (*it)[1], (*it)[2]);
|
|
}
|
|
glEnd();
|
|
glPointSize(pointsize);
|
|
}
|
|
|
|
#else
|
|
for (unsigned int jterator = 0; jterator < vvertexArrayList[iterator].size(); jterator++) {
|
|
if (vvertexArrayList[iterator][jterator]->numPointsToRender > 0) {
|
|
glCallList(vvertexArrayList[iterator][jterator]->name);
|
|
}
|
|
}
|
|
#endif
|
|
glPopMatrix();
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
if (pointmode == 1 ) {
|
|
fullydisplayed = true;
|
|
} else {
|
|
unsigned long td = (GetCurrentTimeInMilliSec() - time);
|
|
if (td > 0)
|
|
lastfps = 1000.0/td;
|
|
else
|
|
lastfps = 1000.0;
|
|
fullydisplayed = false;
|
|
}
|
|
if (interruptable)
|
|
fullydisplayed = true;
|
|
}
|
|
|
|
|
|
void DrawObjects(GLenum mode) {
|
|
for (unsigned int i = 0; i < displays.size(); i++)
|
|
displays[i]->displayAll();
|
|
|
|
}
|
|
|
|
/**
|
|
* Draw a smooth path passing from all the camera points.
|
|
*
|
|
*/
|
|
void DrawPath()
|
|
{
|
|
|
|
glLineWidth(10.0);
|
|
// draw path
|
|
glBegin(GL_LINE_STRIP);
|
|
for(unsigned int j = 0; j < path_vectorX.size(); j++){
|
|
// set the color
|
|
glColor4f(0.0, 1.0, 0.0, 1.0);
|
|
// set the points
|
|
glVertex3f(path_vectorX.at(j).x,path_vectorX.at(j).y,path_vectorZ.at(j).y);
|
|
}
|
|
glEnd();
|
|
|
|
// draw lookat path
|
|
glBegin(GL_LINE_STRIP);
|
|
for(unsigned int j = 0; j < lookat_vectorX.size(); j++){
|
|
//set the color
|
|
glColor4d(1.0, 1.0, 0.0, 1.0);
|
|
//set the points
|
|
glVertex3f(lookat_vectorX.at(j).x,lookat_vectorX.at(j).y,lookat_vectorZ.at(j).y);
|
|
}
|
|
glEnd();
|
|
|
|
// draw up path
|
|
/*
|
|
glBegin(GL_LINE_STRIP);
|
|
for(unsigned int j = 0; j < ups_vectorX.size(); j++){
|
|
//set the color
|
|
glColor4d(0.0, 1.0, 0.0, 0.7);
|
|
//set the points
|
|
glVertex3f(ups_vectorX.at(j).x,ups_vectorX.at(j).y,ups_vectorZ.at(j).y);
|
|
}
|
|
glEnd();
|
|
*/
|
|
}
|
|
|
|
/**
|
|
* Draw the camera boxes in the viewer
|
|
*
|
|
*/
|
|
void DrawCameras(void)
|
|
{
|
|
for (unsigned int i = 0; i < cams.size(); i++) {
|
|
glPushMatrix();
|
|
|
|
// TODO improve upon this primitive camera
|
|
Point p = cams[i];
|
|
Point l = Point::norm( lookats[i] - p ); // forward vector
|
|
Point u = Point::norm( ups[i] - p ); // up vector
|
|
Point r = Point::cross(l,u); // right vector
|
|
l = 5 * l;
|
|
r = 5 * r;
|
|
u = 5 * u;
|
|
|
|
Point cube[8];
|
|
cube[0] = p + l - r - u;
|
|
cube[1] = p + l + r - u;
|
|
cube[2] = p - l + r - u;
|
|
cube[3] = p - l - r - u;
|
|
cube[4] = p + l - r + u;
|
|
cube[5] = p + l + r + u;
|
|
cube[6] = p - l + r + u;
|
|
cube[7] = p - l - r + u;
|
|
|
|
int sides[6][4] = {{0,1,2,3}, {4,5,6,7}, {0,1,5,4},
|
|
{3,2,6,7}, {1,2,6,5}, {0,3,7,4}};
|
|
|
|
if (i+1 == cam_choice) {
|
|
glColor4f(1, 0, 1, 1);
|
|
} else {
|
|
glColor4f(0, 1, 0, 1);
|
|
}
|
|
// camera cube
|
|
glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
|
|
glBegin(GL_QUADS);
|
|
for (int j = 0; j < 6; j++) {
|
|
if (j == 2) continue;
|
|
for (int k = 0; k < 4; k++) {
|
|
int index = sides[j][k];
|
|
glVertex3d(cube[index].x, cube[index].y, cube[index].z);
|
|
}
|
|
}
|
|
glEnd();
|
|
|
|
r = 5 * r;
|
|
u = 5 * u;
|
|
|
|
glColor4f(1, 1, 0, 1);
|
|
if (i+1 == cam_choice) {
|
|
glPointSize(10);
|
|
} else {
|
|
glPointSize(5);
|
|
}
|
|
glBegin(GL_POINTS);
|
|
glVertex3d( lookats[i].x, lookats[i].y, lookats[i].z);
|
|
glEnd();
|
|
|
|
Point fcube[8];
|
|
fcube[0] = cube[4];
|
|
fcube[1] = cube[5];
|
|
fcube[2] = cube[1];
|
|
fcube[3] = cube[0];
|
|
fcube[4] = lookats[i] - r + u;
|
|
fcube[5] = lookats[i] + r + u;
|
|
fcube[6] = lookats[i] + r - u;
|
|
fcube[7] = lookats[i] - r - u;
|
|
|
|
glLineWidth(2.0);
|
|
glLineStipple(1, 0x0C0F);
|
|
glEnable(GL_LINE_STIPPLE);
|
|
glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
|
|
// camera FOV
|
|
glBegin(GL_QUADS);
|
|
for (int j = 0; j < 6; j++) {
|
|
for (int k = 0; k < 4; k++) {
|
|
int index = sides[j][k];
|
|
glVertex3d(fcube[index].x, fcube[index].y, fcube[index].z);
|
|
}
|
|
}
|
|
glEnd();
|
|
glDisable(GL_LINE_STIPPLE);
|
|
|
|
|
|
/*
|
|
if (i+1 == cam_choice) {
|
|
glColor3f(1, 1, 0);
|
|
glPointSize(20);
|
|
} else {
|
|
glColor3f(0, 0, 1);
|
|
glPointSize(10);
|
|
}
|
|
glBegin(GL_POINTS);
|
|
glVertex3d(p.x, p.y, p.z);
|
|
glEnd();
|
|
|
|
if (i+1 == cam_choice) {
|
|
glColor3f(0, 1, 1);
|
|
glPointSize(20);
|
|
} else {
|
|
glColor3f(1, 0, 0);
|
|
glPointSize(10);
|
|
}
|
|
glBegin(GL_POINTS);
|
|
glVertex3d( l.x, l.y, l.z);
|
|
glEnd();
|
|
|
|
if (i+1 == cam_choice) {
|
|
glColor3f(1, 0, 1);
|
|
glPointSize(20);
|
|
} else {
|
|
glColor3f(0, 1, 0);
|
|
glPointSize(10);
|
|
}
|
|
glBegin(GL_POINTS);
|
|
glVertex3d( u.x, u.y, u.z);
|
|
glEnd();
|
|
*/
|
|
|
|
glPopMatrix();
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------------
|
|
|
|
|
|
/**
|
|
* Display function
|
|
*/
|
|
void DisplayItFunc(GLenum mode, bool interruptable)
|
|
{
|
|
/**
|
|
* Color of the fog
|
|
*/
|
|
|
|
GLfloat fogColor[4];
|
|
|
|
if(!invert) {
|
|
glEnable(GL_COLOR_LOGIC_OP);
|
|
glLogicOp(GL_COPY_INVERTED);
|
|
}
|
|
|
|
// set the clear color buffer in case of
|
|
// both invert and non invert mode
|
|
if (invert)
|
|
glClearColor(0.0, 0.0, 0.0, 0.0);
|
|
else
|
|
glClearColor(1.0, 1.0, 1.0, 1.0);
|
|
|
|
// clear the color and depth buffer bit
|
|
if (!interruptable) { // single buffer mode, we need the depth buffer
|
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
|
}
|
|
|
|
glPushMatrix();
|
|
|
|
// set the matrix mode
|
|
glMatrixMode(GL_MODELVIEW);
|
|
|
|
// init modelview matrix
|
|
glLoadIdentity();
|
|
|
|
// set the polygon mode
|
|
glPolygonMode(GL_FRONT/*_AND_BACK*/, GL_LINE);
|
|
|
|
// do the model-transformation
|
|
if (haveToUpdate == 6 && path_iterator < path_vectorX.size() ) {
|
|
gluLookAt(path_vectorX.at(path_iterator).x,
|
|
path_vectorX.at(path_iterator).y,
|
|
path_vectorZ.at(path_iterator).y,
|
|
lookat_vectorX.at(path_iterator).x,
|
|
lookat_vectorX.at(path_iterator).y,
|
|
lookat_vectorZ.at(path_iterator).y,
|
|
ups_vectorX.at(path_iterator).x - path_vectorX.at(path_iterator).x,
|
|
ups_vectorX.at(path_iterator).y - path_vectorX.at(path_iterator).y,
|
|
ups_vectorZ.at(path_iterator).y - path_vectorZ.at(path_iterator).y);
|
|
} else {
|
|
if (cameraNavMouseMode == 1) {
|
|
glRotated( mouseRotX, 1, 0, 0);
|
|
glRotated( mouseRotY, 0, 1, 0);
|
|
glRotated( mouseRotZ, 0, 0, 1);
|
|
glGetFloatv(GL_MODELVIEW_MATRIX, view_rotate_button);
|
|
update_view_rotate(0);
|
|
} else {
|
|
double t[3] = {0,0,0};
|
|
double mat[16];
|
|
QuatToMatrix4(quat, t, mat);
|
|
glMultMatrixd(mat);
|
|
|
|
glGetFloatv(GL_MODELVIEW_MATRIX, view_rotate_button);
|
|
//glRotated(angle, axis[0], axis[1], axis[2]); // rotate the camera
|
|
double rPT[3];
|
|
Matrix4ToEuler(mat, rPT);
|
|
mouseRotX = deg(rPT[0]);
|
|
mouseRotY = deg(rPT[1]);
|
|
mouseRotZ = deg(rPT[2]);
|
|
|
|
}
|
|
updateControls();
|
|
|
|
glTranslated(X, Y, Z); // move camera
|
|
}
|
|
|
|
// cout << "Position :" << X << " " << Y << " " << Z << endl;
|
|
// cout << "Quaternion:" << quat[0] << " " << quat[1] << " " << quat[2] << " " << quat[3] << endl;
|
|
// cout << "Axis/Angle:" << axis[0] << " " << axis[1] << " " << axis[2] << " " << angle << endl;
|
|
// cout << "Apex angle:" << cangle << endl;
|
|
// cout << endl;
|
|
|
|
// process fog
|
|
if (show_fog > 0) {
|
|
if (show_fog > 3)
|
|
fogColor[0] = fogColor[1] = fogColor[2] = fogColor[3] = 1.0;
|
|
else
|
|
fogColor[0] = fogColor[1] = fogColor[2] = fogColor[3] = 0.0;
|
|
glEnable(GL_FOG);
|
|
{
|
|
// ln(1/2^8) = -5.54517744 -> threshold at which the last color bit is gone due to fog
|
|
if (show_fog==1) {fogMode = GL_EXP; fardistance = min(5.54517744 / fogDensity, (double)maxfardistance);}
|
|
else if (show_fog==2) {fogMode = GL_EXP2; fardistance = min(sqrt(5.54517744) / fogDensity, (double)maxfardistance);}
|
|
else if (show_fog==3) {fogMode = GL_LINEAR; fardistance = 32000.0;}
|
|
else if (show_fog==4) {fogMode = GL_EXP; fardistance = (double)maxfardistance; }
|
|
else if (show_fog==5) {fogMode = GL_EXP2; fardistance = (double)maxfardistance; }
|
|
else if (show_fog==6) {fogMode = GL_LINEAR; fardistance = (double)maxfardistance;}
|
|
glFogi(GL_FOG_MODE, fogMode);
|
|
glFogfv(GL_FOG_COLOR, fogColor);
|
|
glFogf(GL_FOG_DENSITY, fogDensity);
|
|
glHint(GL_FOG_HINT, GL_FASTEST);
|
|
glFogf(GL_FOG_START, neardistance);
|
|
glFogf(GL_FOG_END, maxfardistance);
|
|
}
|
|
} else {
|
|
glDisable(GL_FOG);
|
|
fardistance = maxfardistance;
|
|
}
|
|
if (fardistance > maxfardistance) fardistance = maxfardistance;
|
|
if ( fabs(oldfardistance - fardistance) > 0.00001 || fabs(oldneardistance - neardistance) > 0.00001 ) {
|
|
oldfardistance = fardistance;
|
|
oldneardistance = neardistance;
|
|
int viewport[4];
|
|
glGetIntegerv(GL_VIEWPORT, viewport);
|
|
CallBackReshapeFunc(viewport[2],viewport[3]);
|
|
}
|
|
|
|
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
|
//
|
|
// show the objects __after__ the model-transformation
|
|
// for all status variables we show the appropiated thing
|
|
// using the drawing functions
|
|
//
|
|
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
|
|
|
if (show_path == 1) {
|
|
double *pose;
|
|
glColor4d(1.0, 0.0, 0.0, 1.0);
|
|
glLineWidth(5);
|
|
glBegin(GL_LINE_STRIP);
|
|
for(unsigned int i = 0; i < MetaMatrix.size(); i++){
|
|
// set usable type
|
|
Scan::AlgoType type;
|
|
if((unsigned int)frameNr >= MetaMatrix[i].size()) {
|
|
type = MetaAlgoType[i].back();
|
|
} else {
|
|
type = MetaAlgoType[i][frameNr];
|
|
}
|
|
if(frameNr >= 1 && frameNr < (int)MetaMatrix[i].size()) {
|
|
if(type == Scan::INVALID) continue;
|
|
// avoid incomplete frames in a scan
|
|
if((unsigned int)frameNr >= MetaMatrix[i].size())
|
|
pose = MetaMatrix[i].back();
|
|
else
|
|
pose = MetaMatrix[i][frameNr];
|
|
} else {
|
|
//pose = MetaMatrix[i].back();
|
|
// avoid incomplete frames in a scan
|
|
if((unsigned int)current_frame >= MetaMatrix[i].size())
|
|
pose = MetaMatrix[i].back();
|
|
else
|
|
pose = MetaMatrix[i][current_frame];
|
|
}
|
|
if(showTopView) {
|
|
glVertex3f(pose[12], 2000, pose[14]);
|
|
} else {
|
|
glVertex3f(pose[12], pose[13], pose[14]);
|
|
}
|
|
}
|
|
glEnd();
|
|
}
|
|
|
|
// if show camera is true then draw cameras.
|
|
if (show_cameras == 1) {
|
|
DrawCameras();
|
|
}
|
|
|
|
// if show path is true the draw path.
|
|
if (show_path == 1) {
|
|
DrawPath();
|
|
}
|
|
DrawObjects(mode);
|
|
|
|
if (label) DrawUrl();
|
|
|
|
// if show points is true the draw points
|
|
if (show_points == 1) DrawPoints(mode, interruptable);
|
|
|
|
|
|
glPopMatrix();
|
|
|
|
if (!invert) {
|
|
glDisable(GL_COLOR_LOGIC_OP);
|
|
}
|
|
|
|
// force draw the scene
|
|
glFlush();
|
|
glFinish();
|
|
}
|
|
|
|
void DrawUrl() {
|
|
glMatrixMode(GL_MODELVIEW);
|
|
glPushMatrix();
|
|
glLoadIdentity();
|
|
glMatrixMode(GL_PROJECTION);
|
|
|
|
// Save the current projection matrix
|
|
glPushMatrix();
|
|
// Make the current matrix the identity matrix
|
|
glLoadIdentity();
|
|
|
|
// Set the projection (to 2D orthographic)
|
|
glOrtho(0.0,100.0,0.0,100.0,-1.5,1.5);
|
|
|
|
glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
|
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // TODO
|
|
|
|
glColor4d(0.0,0.0,0.0,0.7);
|
|
|
|
glBegin(GL_QUADS);
|
|
glVertex3f(0,0,1.49);
|
|
glVertex3f(0,6,1.49);
|
|
if(smallfont) {
|
|
glVertex3f(22,6,1.49);
|
|
glVertex3f(22,0,1.49);
|
|
} else {
|
|
glVertex3f(25,6,1.49);
|
|
glVertex3f(25,0,1.49);
|
|
}
|
|
glEnd();
|
|
|
|
glBlendFunc(GL_ONE, GL_ZERO);
|
|
glColor3f(1,1,1);
|
|
if(smallfont) {
|
|
glRasterPos3f(1,3.5,1.5);
|
|
_glutBitmapString(GLUT_BITMAP_8_BY_13, "created by 3DTK");
|
|
glRasterPos3f(1,1,1.5);
|
|
_glutBitmapString(GLUT_BITMAP_8_BY_13, "http://threedtk.de");
|
|
} else {
|
|
glRasterPos3f(1,3.5,1.5);
|
|
_glutBitmapString(GLUT_BITMAP_9_BY_15, "created by 3DTK");
|
|
glRasterPos3f(1,1,1.5);
|
|
_glutBitmapString(GLUT_BITMAP_9_BY_15, "http://threedtk.de");
|
|
}
|
|
|
|
// Restore the original projection matrix
|
|
glPopMatrix();
|
|
glMatrixMode(GL_MODELVIEW);
|
|
glPopMatrix();
|
|
|
|
}
|
|
/**
|
|
* Function topview. Set the screen for top view.
|
|
*/
|
|
void topView()
|
|
{
|
|
static GLdouble save_qx, save_qy, save_qz, save_qangle, save_X, save_Y, save_Z;
|
|
static GLdouble saveMouseRotX, saveMouseRotY, saveMouseRotZ;
|
|
|
|
if (!showTopView) // set to top view
|
|
{
|
|
showTopView = true;
|
|
// save current pose
|
|
save_X = X;
|
|
save_Y = Y;
|
|
save_Z = Z;
|
|
save_qx = quat[0];
|
|
save_qy = quat[1];
|
|
save_qz = quat[2];
|
|
save_qangle = quat[3];
|
|
saveMouseRotX = mouseRotX;
|
|
saveMouseRotY = mouseRotY;
|
|
saveMouseRotZ = mouseRotZ;
|
|
|
|
Y = Y - 350.0;
|
|
Z = Z + 500.0;
|
|
quat[0] = quat[1] = sqrt(0.5);
|
|
quat[2] = quat[3] = 0.0;
|
|
mouseRotX = 90;
|
|
mouseRotY = 0;
|
|
mouseRotZ = 0;
|
|
|
|
haveToUpdate = 2;
|
|
} else {
|
|
showTopView = false;
|
|
|
|
// restore old settings
|
|
X = save_X;
|
|
Y = save_Y;
|
|
Z = save_Z;
|
|
quat[0] = save_qx;
|
|
quat[1] = save_qy;
|
|
quat[2] = save_qz;
|
|
quat[3] = save_qangle;
|
|
mouseRotX = saveMouseRotX;
|
|
mouseRotY = saveMouseRotY;
|
|
mouseRotZ = saveMouseRotZ;
|
|
|
|
haveToUpdate = 2;
|
|
}
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
/**
|
|
* This function is called when the user wants to
|
|
* delete a camera.
|
|
*/
|
|
|
|
void callDeleteCamera(int dummy){
|
|
|
|
//iterator for the position of camera
|
|
//in the camera list
|
|
vector<Point>::iterator position;
|
|
vector<Point>::iterator positionL;
|
|
vector<Point>::iterator positionU;
|
|
|
|
//calculate the position of the camera. we are referring
|
|
//to the selected camera
|
|
position = cams.begin()+ (cam_choice-1);
|
|
positionL = lookats.begin()+ (cam_choice-1);
|
|
positionU = ups.begin()+ (cam_choice-1);
|
|
|
|
//if no camera present then return
|
|
if(cam_choice == 0)
|
|
return;
|
|
|
|
//if the list is not empty then
|
|
if(!cams.empty()){
|
|
//delete the camera from the position
|
|
cams.erase(position);
|
|
lookats.erase(positionL);
|
|
ups.erase(positionU);
|
|
//reset the cam_choice spinner values
|
|
}
|
|
|
|
updateCamera();
|
|
}
|
|
|
|
|
|
//---------------------------------------------------------------------------
|
|
/**
|
|
* Function to reset the viewer window.
|
|
*/
|
|
|
|
void resetView(int dummy)
|
|
{
|
|
cangle = 60.0;
|
|
pzoom = defaultZoom;
|
|
X = RVX;
|
|
Y = RVY;
|
|
Z = RVZ;
|
|
quat[0] = Rquat[0];
|
|
quat[1] = Rquat[1];
|
|
quat[2] = Rquat[2];
|
|
quat[3] = Rquat[3];
|
|
haveToUpdate = 2;
|
|
mouseRotX = 0;
|
|
mouseRotY = 0;
|
|
mouseRotZ = 0;
|
|
|
|
resetRotationButton();
|
|
}
|
|
|
|
/**
|
|
* Function to set the viewer window back to a previously saved state.
|
|
*/
|
|
|
|
void setView(double pos[3], double new_quat[4],
|
|
double newMouseRotX, double newMouseRotY, double newMouseRotZ,
|
|
double newCangle,
|
|
bool sTV, bool cNMM, double pzoom_new,
|
|
bool s_points, bool s_path, bool s_cameras, double ps, int
|
|
sf, double fD, bool inv)
|
|
{
|
|
X = pos[0];
|
|
Y = pos[1];
|
|
Z = pos[2];
|
|
for(int i = 0; i < 4; i++) {
|
|
quat[i] = new_quat[i];
|
|
}
|
|
cangle = newCangle;
|
|
mouseRotX = newMouseRotX;
|
|
mouseRotY = newMouseRotY;
|
|
mouseRotZ = newMouseRotZ;
|
|
showTopView = sTV,
|
|
cameraNavMouseMode = cNMM;
|
|
pzoom = pzoom_new;
|
|
updateTopViewControls();
|
|
|
|
show_points = s_points;
|
|
show_path = s_path;
|
|
show_cameras = s_cameras;
|
|
pointsize = ps;
|
|
show_fog = sf;
|
|
fogDensity = fD;
|
|
invert = inv;
|
|
|
|
haveToUpdate = 2;
|
|
}
|
|
|
|
|
|
/**
|
|
* This function is called when the viewer is created. This
|
|
* acts as the display function.
|
|
*/
|
|
void CallBackDisplayFunc()
|
|
{
|
|
if ((cangle_spinner != 0 && (fabs(cangle_old - cangle) > 0.5)) ||
|
|
(pzoom_spinner != 0 && (fabs(pzoom_old - pzoom) > 0.5))) {
|
|
|
|
cangle_old = cangle;
|
|
pzoom_old = pzoom;
|
|
int viewport[4];
|
|
glGetIntegerv(GL_VIEWPORT, viewport);
|
|
CallBackReshapeFunc(viewport[2],viewport[3]);
|
|
#ifdef _MSC_VER
|
|
Sleep(25);
|
|
#else
|
|
usleep(250000);
|
|
#endif
|
|
}
|
|
|
|
glDrawBuffer(buffermode);
|
|
// delete framebuffer and z-buffer
|
|
|
|
//Call the display function
|
|
DisplayItFunc(GL_RENDER );
|
|
|
|
// show the rednered scene
|
|
glutSwapBuffers();
|
|
|
|
}
|
|
|
|
/**
|
|
* This function is called when there is nothing to be done
|
|
* in the screen.
|
|
*/
|
|
void CallBackIdleFunc(void)
|
|
{
|
|
|
|
#ifdef _MSC_VER
|
|
Sleep(1);
|
|
#else
|
|
usleep(1000);
|
|
#endif
|
|
|
|
if(glutGetWindow() != window_id)
|
|
glutSetWindow(window_id);
|
|
|
|
// return as nothing has to be updated
|
|
if (haveToUpdate == 0) {
|
|
if (!fullydisplayed && !mousemoving && !keypressed && pointmode == 0
|
|
) {
|
|
glDrawBuffer(buffermode);
|
|
//Call the display function
|
|
DisplayItFunc(GL_RENDER, true);
|
|
}
|
|
return;
|
|
}
|
|
|
|
// case: display is invalid - update it
|
|
if (haveToUpdate == 1) {
|
|
glutPostRedisplay();
|
|
haveToUpdate = 0;
|
|
return;
|
|
}
|
|
// case: display is invalid - update it with all points
|
|
/* if (haveToUpdate == 7) {
|
|
showall = true;
|
|
glutPostRedisplay();
|
|
haveToUpdate = 0;
|
|
return;
|
|
}*/
|
|
|
|
// case: camera angle is changed - instead of repeating code call Reshape,
|
|
// since these OpenGL commands are the same
|
|
if (haveToUpdate == 2) {
|
|
int viewport[4];
|
|
glGetIntegerv(GL_VIEWPORT, viewport);
|
|
CallBackReshapeFunc(viewport[2],viewport[3]);
|
|
glutPostRedisplay();
|
|
haveToUpdate = 0;
|
|
return;
|
|
}
|
|
|
|
// case: animation
|
|
if(haveToUpdate == 3 ){
|
|
frameNr += 1;
|
|
if(!(MetaMatrix.size() > 1 && frameNr < (int) MetaMatrix[1].size())){
|
|
frameNr = 0;
|
|
haveToUpdate = 4;
|
|
return;
|
|
}
|
|
glutPostRedisplay();
|
|
|
|
if(save_animation){
|
|
string filename = scan_dir + "animframe" + to_string(frameNr,5) + ".ppm";
|
|
cout << "write " << filename << endl;
|
|
int tmpUpdate = haveToUpdate;
|
|
glWriteImagePPM(filename.c_str(), factor, 0);
|
|
haveToUpdate = tmpUpdate;
|
|
|
|
string jpgname = scan_dir + "animframe" + to_string(frameNr,5) + ".jpg";
|
|
string systemcall = "convert -quality 100 -type TrueColor " + filename + " " + jpgname;
|
|
// cout << systemcall << endl;
|
|
system(systemcall.c_str());
|
|
systemcall = "rm " + filename;
|
|
system(systemcall.c_str());
|
|
// cout << systemcall << endl;
|
|
// for f in *ppm ; do convert -quality 100 -type TrueColor $f `basename $f ppm`jpg; done
|
|
}
|
|
|
|
}
|
|
#ifdef _MSC_VER
|
|
Sleep(300);
|
|
Sleep(anim_delay);
|
|
#else
|
|
usleep(anim_delay * 10000);
|
|
#endif
|
|
|
|
if (haveToUpdate == 4) { // stop animation
|
|
frameNr = 0; // delete these lines if you want a 'continue' functionality.
|
|
haveToUpdate = 1;
|
|
}
|
|
|
|
// case: path animation
|
|
if(haveToUpdate == 6){
|
|
|
|
if (path_iterator == 0) {
|
|
oldcamNavMode = cameraNavMouseMode; // remember state of old mousenav
|
|
cameraNavMouseMode = 0;
|
|
}
|
|
|
|
// check if the user wants to animate both
|
|
// scan matching and the path at the same
|
|
//time
|
|
|
|
// cout << "path_iterator: " << path_iterator << endl;
|
|
if(path_iterator < path_vectorX.size()){ // standard animation case
|
|
|
|
// call the path animation function
|
|
// hide both the cameras and the path
|
|
show_cameras = 0;
|
|
show_path = 0;
|
|
// increase the iteration count
|
|
|
|
path_iterator += 1;
|
|
// repaint the screen
|
|
glutPostRedisplay();
|
|
|
|
// save the animation
|
|
if(save_animation){
|
|
string filename = scan_dir + "animframe" + to_string(path_iterator,5) + ".ppm";
|
|
string jpgname = scan_dir + "animframe" + to_string(path_iterator,5) + ".jpg";
|
|
cout << "written " << filename << " of " << path_vectorX.size() << " files" << endl;
|
|
glWriteImagePPM(filename.c_str(), factor, 0);
|
|
string systemcall = "convert -quality 100 " + filename + " " + jpgname;
|
|
system(systemcall.c_str());
|
|
systemcall = "rm " + filename;
|
|
system(systemcall.c_str());
|
|
haveToUpdate = 6;
|
|
|
|
}
|
|
}else{ // animation has just ended
|
|
cameraNavMouseMode = oldcamNavMode;
|
|
show_cameras = 1;
|
|
show_path = 1;
|
|
haveToUpdate = 0;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
|
|
/**
|
|
* This function handles the rotation of the view
|
|
*/
|
|
|
|
void update_view_rotate(int t)
|
|
{
|
|
double view_rotate_button_quat[4];
|
|
|
|
// convert the rotate button matrix to quaternion
|
|
//Matrix4ToQuaternion(view_rotate_button, view_rotate_button_quat);
|
|
double mat[16];
|
|
for (int i = 0; i < 16; i++)
|
|
mat[i] = view_rotate_button[i];
|
|
Matrix4ToQuat(mat, view_rotate_button_quat);
|
|
|
|
// normalize the quartenion
|
|
QuatNormalize(view_rotate_button_quat);
|
|
|
|
// copy it to the global quartenion quat
|
|
memcpy(quat, view_rotate_button_quat, sizeof(quat));
|
|
}
|
|
|
|
/**
|
|
* This function handles the translation of view.
|
|
*/
|
|
void update_view_translation(int t)
|
|
{
|
|
double obj_pos_button1[3];
|
|
|
|
for (int i = 0; i < 3; i++) {
|
|
if (fabs(obj_pos_button_old[i] - obj_pos_button[i]) > COMPARE_EPSILON) {
|
|
obj_pos_button1[i] = obj_pos_button[i] - obj_pos_button_old[i];
|
|
obj_pos_button_old[i] = obj_pos_button[i];
|
|
} else obj_pos_button1[i] = 0.0;
|
|
}
|
|
|
|
X = X + obj_pos_button1[0] * view_rotate_button[0] + obj_pos_button1[1] * view_rotate_button[1] + obj_pos_button1[2] * view_rotate_button[2];
|
|
Y = Y + obj_pos_button1[0] * view_rotate_button[4] + obj_pos_button1[1] * view_rotate_button[5] + obj_pos_button1[2] * view_rotate_button[6];
|
|
Z = Z + obj_pos_button1[0] * view_rotate_button[8] + obj_pos_button1[1] * view_rotate_button[9] + obj_pos_button1[2] * view_rotate_button[10];
|
|
|
|
}
|
|
|
|
|
|
/**
|
|
* handles the animation button
|
|
* @param dummy not needed necessary for glui
|
|
*/
|
|
void startAnimation(int dummy)
|
|
{
|
|
if (MetaMatrix.size() > 0) {
|
|
if (haveToUpdate != 3) {
|
|
haveToUpdate = 3;
|
|
}
|
|
else // stop animation
|
|
haveToUpdate = 4;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* calls the resetView function
|
|
* @param dummy not needed necessary for glui
|
|
*/
|
|
void callResetView(int dummy)
|
|
{
|
|
if (showTopView) callTopView(dummy);
|
|
resetView(0);
|
|
}
|
|
|
|
/**
|
|
* calls the resetView function
|
|
* @param dummy not needed necessary for glui
|
|
*/
|
|
void invertView(int dummy)
|
|
{
|
|
invert = !invert;
|
|
}
|
|
|
|
/**
|
|
* calls the topView function
|
|
* @param dummy not needed necessary for glui
|
|
*/
|
|
void callTopView(int dummy)
|
|
{
|
|
topView();
|
|
if (showTopView) {
|
|
rotButton->disable();
|
|
cangle_spinner->disable();
|
|
pzoom_spinner->enable();
|
|
} else {
|
|
rotButton->enable();
|
|
cangle_spinner->enable();
|
|
pzoom_spinner->disable();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* calls the cameraView function
|
|
* @param dummy not needed necessary for glui
|
|
*/
|
|
void callAddCamera(int dummy)
|
|
{
|
|
Point campos(-X, -Y, -Z);
|
|
|
|
// calculate lookat point
|
|
Point lookat;
|
|
Point up(0, 0, 0);
|
|
double tmat[16];
|
|
for (int i =0;i<16;i++) tmat[i] = view_rotate_button[i];
|
|
|
|
lookat.x = -50*tmat[2] -X;
|
|
lookat.y = -50*tmat[6] -Y;
|
|
lookat.z = -50*tmat[10] -Z;
|
|
|
|
up.x = 50*tmat[1] -X;
|
|
up.y = 50*tmat[5] -Y;
|
|
up.z = 50*tmat[9] -Z;
|
|
|
|
cams.push_back(campos);
|
|
lookats.push_back(lookat);
|
|
ups.push_back(up);
|
|
|
|
updateCamera();
|
|
|
|
// signal to repaint screen
|
|
haveToUpdate = 1;
|
|
}
|
|
|
|
void selectPoints(int x, int y) {
|
|
|
|
GLuint selectBuf[BUFSIZE];
|
|
GLint hits;
|
|
GLint viewport[4];
|
|
if (selectOrunselect) {
|
|
// set the matrix mode
|
|
glMatrixMode(GL_MODELVIEW);
|
|
// init modelview matrix
|
|
glLoadIdentity();
|
|
|
|
// do the model-transformation
|
|
if (cameraNavMouseMode == 1) {
|
|
glRotated( mouseRotX, 1, 0, 0);
|
|
glRotated( mouseRotY, 0, 1, 0);
|
|
glRotated( mouseRotZ, 0, 0, 1);
|
|
} else {
|
|
double t[3] = {0,0,0};
|
|
double mat[16];
|
|
QuatToMatrix4(quat, t, mat);
|
|
glMultMatrixd(mat);
|
|
|
|
glGetFloatv(GL_MODELVIEW_MATRIX, view_rotate_button);
|
|
double rPT[3];
|
|
Matrix4ToEuler(mat, rPT);
|
|
mouseRotX = deg(rPT[0]);
|
|
mouseRotY = deg(rPT[1]);
|
|
mouseRotZ = deg(rPT[2]);
|
|
}
|
|
updateControls();
|
|
glTranslated(X, Y, Z); // move camera
|
|
|
|
static sfloat *sp2 = 0;
|
|
/* for(int iterator = (int)octpts.size()-1; iterator >= 0; iterator--) {
|
|
if (!selected_points[iterator].empty()) sp2 = *selected_points[iterator].begin();
|
|
|
|
// selected_points[iterator].clear();
|
|
}*/
|
|
for(int iterator = (int)octpts.size()-1; iterator >= 0; iterator--) {
|
|
glPushMatrix();
|
|
glMultMatrixd(MetaMatrix[iterator].back());
|
|
calcRay(x, y, 1.0, 40000.0);
|
|
if (select_voxels) {
|
|
octpts[iterator]->selectRay(selected_points[iterator], selection_depth);
|
|
} else if (brush_size == 0) {
|
|
sfloat *sp = 0;
|
|
octpts[iterator]->selectRay(sp);
|
|
if (sp != 0) {
|
|
cout << "Selected point: " << sp[0] << " " << sp[1] << " " << sp[2] << endl;
|
|
|
|
if (sp2 != 0) {
|
|
cout << "Distance to last point: "
|
|
<< sqrt( sqr(sp2[0] - sp[0]) + sqr(sp2[1] - sp[1]) + sqr(sp2[2] - sp[2]) ) << endl;
|
|
}
|
|
sp2 = sp;
|
|
|
|
selected_points[iterator].insert(sp);
|
|
}
|
|
} else { // select multiple points with a given brushsize
|
|
octpts[iterator]->selectRayBrushSize(selected_points[iterator], brush_size);
|
|
}
|
|
|
|
glPopMatrix();
|
|
}
|
|
|
|
} else {
|
|
// unselect points
|
|
glGetIntegerv(GL_VIEWPORT, viewport);
|
|
|
|
glSelectBuffer(BUFSIZE, selectBuf);
|
|
(void) glRenderMode(GL_SELECT);
|
|
|
|
glInitNames();
|
|
glPushName(0);
|
|
|
|
glMatrixMode(GL_PROJECTION);
|
|
glPushMatrix();
|
|
glLoadIdentity();
|
|
|
|
// gluPickMatrix((GLdouble)x, (GLdouble)(viewport[3]-y), 10.0, 10.0, viewport);
|
|
gluPickMatrix((GLdouble)x, (GLdouble)(viewport[3]-y), brush_size*2, brush_size*2, viewport);
|
|
gluPerspective(cangle, aspect, neardistance, fardistance);
|
|
glMatrixMode(GL_MODELVIEW);
|
|
DisplayItFunc(GL_SELECT);
|
|
|
|
glMatrixMode(GL_PROJECTION);
|
|
glPopMatrix();
|
|
glMatrixMode(GL_MODELVIEW);
|
|
|
|
hits = glRenderMode(GL_RENDER); // get hits
|
|
ProcessHitsFunc(hits, selectBuf);
|
|
}
|
|
glPopMatrix();
|
|
glutPostRedisplay();
|
|
}
|
|
|
|
void CallBackMouseFuncMoving(int button, int state, int x, int y)
|
|
{
|
|
|
|
if( state == GLUT_DOWN) {
|
|
mousemoving = true;
|
|
} else {
|
|
mousemoving = false;
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* This function is called after a mousebutton has been pressed.
|
|
*/
|
|
void CallBackMouseFunc(int button, int state, int x, int y)
|
|
{
|
|
// Are we selecting points or moving the camera?
|
|
if(cameraNavMouseMode != 1) { // selecting points
|
|
if (state == GLUT_DOWN && (button == GLUT_LEFT_BUTTON || button == GLUT_RIGHT_BUTTON)) {
|
|
selectPoints(x,y);
|
|
}
|
|
} else {
|
|
if( state == GLUT_DOWN) {
|
|
|
|
mouseNavX = x;
|
|
mouseNavY = y;
|
|
mouseNavButton = button;
|
|
|
|
mousemoving = true;
|
|
} else {
|
|
mouseNavButton = -1;
|
|
mousemoving = false;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void moveCamera(double x, double y, double z, double rotx, double roty, double rotz) {
|
|
interruptDrawing();
|
|
double mat[9];
|
|
|
|
double xr = M_PI * mouseRotX / 180;
|
|
double yr = M_PI * mouseRotY / 180;
|
|
double zr = M_PI * mouseRotZ / 180;
|
|
double c1,c2,c3,s1,s2,s3;
|
|
s1 = sin(xr); c1 = cos(xr);
|
|
s2 = sin(yr); c2 = cos(yr);
|
|
s3 = sin(zr); c3 = cos(zr);
|
|
mat[0] = c2*c3;
|
|
mat[1] = -c2*s3;
|
|
mat[2] = s2;
|
|
mat[3] = c1*s3+c3*s1*s2;
|
|
mat[4] = c1*c3-s1*s2*s3;
|
|
mat[5] = -c2*s1;
|
|
mat[6] = s1*s3-c1*c3*s2;
|
|
mat[7] = c1*s2*s3+c3*s1;
|
|
mat[8] = c1*c2;
|
|
|
|
double transX, transY, transZ;
|
|
transX = transY = transZ = 0.0;
|
|
|
|
mouseRotX += rotx;
|
|
mouseRotY -= roty;
|
|
mouseRotZ -= rotz;
|
|
|
|
if (mouseRotX < -90) mouseRotX=-90;
|
|
else if (mouseRotX > 90) mouseRotX=90;
|
|
if (mouseRotY > 360) mouseRotY-=360;
|
|
else if (mouseRotY < 0) mouseRotY+=360;
|
|
if (mouseRotZ > 360) mouseRotZ-=360;
|
|
else if (mouseRotZ < 0) mouseRotZ+=360;
|
|
|
|
transX += x * mat[0] + y * mat[3] + z * mat[6];
|
|
transY += x * mat[1] + y * mat[4] + z * mat[7];
|
|
transZ += x * mat[2] + y * mat[5] + z * mat[8];
|
|
|
|
|
|
X += transX;
|
|
Y += transY;
|
|
Z += transZ;
|
|
haveToUpdate = 1;
|
|
|
|
}
|
|
|
|
void KeyboardFunc(int key, bool control, bool alt, bool shift) {
|
|
double stepsize = movementSpeed;
|
|
if (shift) stepsize *= 10.0;
|
|
if (control) stepsize *= 0.1;
|
|
|
|
double rotsize = 0.2 * stepsize;
|
|
|
|
switch (key) {
|
|
case 'w':
|
|
case 'W':
|
|
moveCamera(0,0,stepsize,0,0,0);
|
|
break;
|
|
case 'a':
|
|
case 'A':
|
|
moveCamera(stepsize,0,0,0,0,0);
|
|
break;
|
|
case 's':
|
|
case 'S':
|
|
moveCamera(0,0,-stepsize,0,0,0);
|
|
break;
|
|
case 'd':
|
|
case 'D':
|
|
moveCamera(-stepsize,0,0,0,0,0);
|
|
break;
|
|
case 'c':
|
|
case 'C':
|
|
moveCamera(0,stepsize,0,0,0,0);
|
|
break;
|
|
case 32: // WXK_SPACE
|
|
moveCamera(0,-stepsize,0,0,0,0);
|
|
break;
|
|
case 314: // WXK_LEFT
|
|
moveCamera(0,0,0,0,rotsize,0);
|
|
break;
|
|
case 315: // WXK_UP
|
|
moveCamera(0,0,0,rotsize,0,0);
|
|
break;
|
|
case 316: // WXK_RIGHT
|
|
moveCamera(0,0,0,0,-rotsize,0);
|
|
break;
|
|
case 317: // WXK_DOWN
|
|
moveCamera(0,0,0,-rotsize,0,0);
|
|
break;
|
|
case 'q':
|
|
case 'Q':
|
|
case 366: // WXK_PAGEUP
|
|
moveCamera(0,0,0,0,0,rotsize);
|
|
break;
|
|
case 'e':
|
|
case 'E':
|
|
case 367: // WXK_PAGEDOWN
|
|
moveCamera(0,0,0,0,0,-rotsize);
|
|
break;
|
|
case 'f':
|
|
if (!fullscreen) {
|
|
fullscreen = true;
|
|
glutFullScreen();
|
|
} else {
|
|
fullscreen = false;
|
|
glutReshapeWindow(current_width, current_height);
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
void CallBackMouseMotionFunc(int x, int y) {
|
|
double deltaMouseX = x - mouseNavX;
|
|
double deltaMouseY = mouseNavY - y;
|
|
mouseNavX = x;
|
|
mouseNavY = y;
|
|
|
|
if(cameraNavMouseMode == 1) {
|
|
if( mouseNavButton == GLUT_RIGHT_BUTTON){
|
|
if ( showTopView ) {
|
|
deltaMouseX *= 5;
|
|
deltaMouseY *= 5;
|
|
}
|
|
deltaMouseX *= movementSpeed/10.0; // moving 10 pixels is equivalent to one key stroke
|
|
deltaMouseY *= movementSpeed/10.0;
|
|
moveCamera(deltaMouseX, deltaMouseY, 0, 0,0,0);
|
|
} else if( mouseNavButton == GLUT_MIDDLE_BUTTON ){
|
|
if ( !showTopView ) {
|
|
deltaMouseY *= -5;
|
|
}
|
|
deltaMouseX *= movementSpeed/10.0; // moving 10 pixels is equivalent to one key stroke
|
|
deltaMouseY *= movementSpeed/10.0;
|
|
moveCamera(deltaMouseX, 0, deltaMouseY, 0,0,0);
|
|
} else if ( mouseNavButton == GLUT_LEFT_BUTTON ){
|
|
moveCamera(0, 0, 0, deltaMouseY,deltaMouseX,0);
|
|
} else {
|
|
return;
|
|
}
|
|
} else {
|
|
selectPoints(x,y);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void initScreenWindow()
|
|
{
|
|
// init display
|
|
glutInitDisplayMode(GLUT_DEPTH | GLUT_RGBA | GLUT_DOUBLE);
|
|
|
|
// define the window position and size
|
|
glutInitWindowPosition(START_X, START_Y);
|
|
glutInitWindowSize( START_WIDTH, START_HEIGHT );
|
|
|
|
// create window and append callback functions
|
|
window_id = glutCreateWindow("3D_Viewer");
|
|
|
|
glutDisplayFunc( CallBackDisplayFunc );
|
|
glutReshapeFunc( CallBackReshapeFunc );
|
|
|
|
glutMouseFunc ( CallBackMouseFunc );
|
|
glutKeyboardFunc ( CallBackKeyboardFunc);
|
|
glutKeyboardUpFunc ( CallBackKeyboardUpFunc);
|
|
glutMotionFunc ( CallBackMouseMotionFunc);
|
|
glutSpecialFunc ( CallBackSpecialFunc);
|
|
// glutEntryFunc ( CallBackEntryFunc);
|
|
GLUI_Master.set_glutReshapeFunc( CallBackReshapeFunc );
|
|
GLUI_Master.set_glutIdleFunc( CallBackIdleFunc );
|
|
|
|
update_view_rotate(0);
|
|
glClearColor(0.0, 0.0, 0.0, 0.0);
|
|
// glClearColor(1.0, 1.0, 1.0, 1.0);
|
|
}
|
|
|
|
|
|
/* +++++++++-------------++++++++++++
|
|
* NAME
|
|
* glDumpWindowPPM
|
|
* DESCRIPTION
|
|
* writes an ppm file of the window
|
|
* content
|
|
* PARAMETERS
|
|
* filename
|
|
* RESULT
|
|
* writes the framebuffer content
|
|
* to a ppm file
|
|
+++++++++-------------++++++++++++ */
|
|
void glDumpWindowPPM(const char *filename, GLenum mode)
|
|
{
|
|
int win_height, win_width;
|
|
int i,j,k,l; // Counter variables
|
|
GLubyte *buffer; // The GL Frame Buffer
|
|
unsigned char *ibuffer; // The PPM Output Buffer
|
|
ofstream fp; // The PPM File
|
|
|
|
GLint viewport[4];
|
|
glGetIntegerv(GL_VIEWPORT, viewport);
|
|
win_height = viewport[3];
|
|
win_width = viewport[2];
|
|
|
|
// Allocate memory for the the frame buffer and output buffer
|
|
buffer = new GLubyte[win_width * win_height * RGBA];
|
|
ibuffer = new unsigned char[win_width * win_height * RGB];
|
|
|
|
// Read window contents from GL frame buffer with glReadPixels
|
|
glFinish();
|
|
glReadBuffer(buffermode);
|
|
glReadPixels(0, 0, win_width, win_height,
|
|
GL_RGBA, GL_UNSIGNED_BYTE, buffer);
|
|
|
|
// Open the output file
|
|
fp.open(filename, ios::out);
|
|
|
|
// Write a proper P6 PPM header
|
|
fp << "P6" << endl << "# CREATOR: 3D_Viewer by Andreas Nuechter, University of Osnabrueck"
|
|
<< endl << win_width << " " << win_height << " " << UCHAR_MAX << endl;
|
|
|
|
// Loop through the frame buffer data, writing to the PPM file. Be careful
|
|
// to account for the frame buffer having 4 bytes per pixel while the
|
|
// output file has 3 bytes per pixel
|
|
l = 0;
|
|
for (i = 0; i < win_height; i++) { // For each row
|
|
for (j = 0; j < win_width; j++) { // For each column
|
|
for (k = 0; k < RGB; k++) { // For each RGB component
|
|
//cout << (RGBA*((win_height-1-i)*win_width+j)+k) << endl;
|
|
ibuffer[l++] = (unsigned char)
|
|
*(buffer + (RGBA*((win_height-1-i)*win_width+j)+k));
|
|
} // end RGB
|
|
} // end column
|
|
} // end row
|
|
|
|
// to make a video do:
|
|
// for f in *ppm ; do convert -quality 100 $f `basename $f ppm`jpg; done
|
|
// mencoder "mf://*.jpg" -mf fps=10 -o test.avi -ovc lavc -lavcopts vcodec=msmpeg4v2:vbitrate=800
|
|
// Write output buffer to the file */
|
|
fp.write((const char*)ibuffer, sizeof(unsigned char) * (RGB * win_width * win_height));
|
|
fp.close();
|
|
fp.clear();
|
|
delete [] buffer;
|
|
delete [] ibuffer;
|
|
}
|
|
|
|
/* +++++++++-------------++++++++++++
|
|
* NAME
|
|
* glDumpWindowPPM
|
|
* DESCRIPTION
|
|
* writes an ppm file of the window
|
|
* content
|
|
* size is scale times the window size
|
|
* PARAMETERS
|
|
* filename
|
|
* RESULT
|
|
* writes the framebuffer content
|
|
* to a ppm file
|
|
+++++++++-------------++++++++++++ */
|
|
void glWriteImagePPM(const char *filename, int scale, GLenum mode)
|
|
{
|
|
//if(!showTopView) {
|
|
int m,o,k; // Counter variables
|
|
// Get viewport parameters
|
|
double left, right, top, bottom;
|
|
double tmp = 1.0/tan(rad(cangle)/2.0);
|
|
|
|
// Save camera parameters
|
|
GLdouble savedMatrix[16];
|
|
glGetDoublev(GL_PROJECTION_MATRIX,savedMatrix);
|
|
GLdouble savedModel[16];
|
|
glGetDoublev(GL_MODELVIEW_MATRIX,savedModel);
|
|
//glMatrixMode(GL_PROJECTION);
|
|
//glPushMatrix();
|
|
//glMatrixMode(GL_MODELVIEW);
|
|
//glPushMatrix();
|
|
top = 1.0/tmp;
|
|
bottom = -top;
|
|
right = (aspect)/tmp;
|
|
left = -right;
|
|
|
|
double part_height, part_width;
|
|
if(!showTopView) {
|
|
part_width = (right - left)/(double)scale;
|
|
part_height = (top - bottom)/(double)scale;
|
|
} else {
|
|
part_height = (2*pzoom)/scale;
|
|
part_width = (2*pzoom*aspect)/scale;
|
|
cout << part_width << " " << part_height << endl;
|
|
}
|
|
// Calculate part parameters
|
|
GLint viewport[4];
|
|
glGetIntegerv(GL_VIEWPORT, viewport);
|
|
int win_width = viewport[2];
|
|
int win_height = viewport[3];
|
|
int image_width = scale * win_width;
|
|
int image_height = scale * win_height;
|
|
|
|
// Allocate memory for the the frame buffer and output buffer
|
|
GLubyte *buffer; // The GL Frame Buffer
|
|
unsigned char *ibuffer; // The PPM Output Buffer
|
|
buffer = new GLubyte[win_width * win_height * RGBA];
|
|
ibuffer = new unsigned char[image_width * image_height * RGB];
|
|
|
|
smallfont = (scale==1);
|
|
double height;
|
|
if(!showTopView) {
|
|
height = bottom;
|
|
} else {
|
|
height = -pzoom;
|
|
}
|
|
for(int i = 0; i < scale; i++) {
|
|
double width;
|
|
if(!showTopView) {
|
|
width = left;
|
|
} else {
|
|
width = -pzoom*aspect;
|
|
}
|
|
for(int j = 0; j < scale; j++) {
|
|
glMatrixMode(GL_PROJECTION);
|
|
glLoadIdentity();
|
|
label = false;
|
|
if(!showTopView) {
|
|
glFrustum(neardistance*width, neardistance*(width + part_width),
|
|
neardistance*(height),
|
|
neardistance*(height + part_height),
|
|
neardistance, fardistance);
|
|
glMatrixMode(GL_MODELVIEW);
|
|
if(i==0 && j==0) {
|
|
label = true;
|
|
}
|
|
DisplayItFunc(mode);
|
|
} else {
|
|
glOrtho( width, width + part_width,
|
|
height, height + part_height,
|
|
1.0, 32000.0 );
|
|
glMatrixMode(GL_MODELVIEW);
|
|
if(i==0 && j==0) {
|
|
label = true;
|
|
}
|
|
DisplayItFunc(mode);
|
|
}
|
|
|
|
// Read window contents from GL frame buffer with glReadPixels
|
|
glFinish();
|
|
glReadBuffer(buffermode);
|
|
glReadPixels(0, 0, win_width, win_height, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
|
|
|
|
// Loop through the frame buffer data, writing to the PPM file. Be careful
|
|
// to account for the frame buffer having 4 bytes per pixel while the
|
|
// output file has 3 bytes per pixel
|
|
// end row
|
|
for (m = 0; m < win_height; m++) { // For each row
|
|
for (o = 0; o < win_width; o++) { // For each column
|
|
for (k = 0; k < RGB; k++) { // For each RGB component
|
|
int l = (k+RGB*(image_width*((scale - 1 - i)*win_height + m) + j*win_width + o));
|
|
ibuffer[l] = (unsigned char) *(buffer + (RGBA*((win_height-1-m)*win_width+o)+k));
|
|
} // end RGB
|
|
} // end column
|
|
}
|
|
width += part_width;
|
|
}
|
|
height += part_height;
|
|
}
|
|
|
|
// show the starting scene
|
|
|
|
// Restore the original projection matrix
|
|
glMatrixMode(GL_PROJECTION);
|
|
glLoadMatrixd(savedMatrix);
|
|
glMatrixMode(GL_MODELVIEW);
|
|
glLoadMatrixd(savedModel);
|
|
// show the rednered scene
|
|
label = true;
|
|
smallfont = true;
|
|
haveToUpdate=2;
|
|
DisplayItFunc(mode);
|
|
|
|
ofstream fp; // The PPM File
|
|
|
|
// Open the output file
|
|
fp.open(filename, ios::out);
|
|
|
|
// Write a proper P6 PPM header
|
|
fp << "P6" << endl << "# CREATOR: 3D_Viewer by Dorit Borrmann, Jacobs University Bremen gGmbH"
|
|
<< endl << image_width << " " << image_height << " " << UCHAR_MAX << endl;
|
|
|
|
// Write output buffer to the file
|
|
fp.write((const char*)ibuffer, sizeof(unsigned char) * (RGB * image_width * image_height));
|
|
fp.close();
|
|
fp.clear();
|
|
delete [] buffer;
|
|
delete [] ibuffer;
|
|
}
|
|
|
|
/** Reshape Function
|
|
* TODO: have to describe it.
|
|
*
|
|
*/
|
|
void CallBackReshapeFunc(int width, int height)
|
|
{
|
|
if (!fullscreen) {
|
|
current_height = height;
|
|
current_width = width;
|
|
}
|
|
aspect = (double)width/(double)height;
|
|
if (!showTopView) {
|
|
// usage of the vsize of a structiewport
|
|
glViewport(0, 0, (GLint)width, (GLint)height);
|
|
|
|
glMatrixMode(GL_PROJECTION);
|
|
glLoadIdentity();
|
|
|
|
// angle, aspect, near clip, far clip
|
|
// get matrix
|
|
gluPerspective(cangle, aspect, neardistance, fardistance);
|
|
|
|
// now use modelview-matrix as current matrix
|
|
glMatrixMode(GL_MODELVIEW);
|
|
|
|
haveToUpdate = 1;
|
|
|
|
} else {
|
|
|
|
// usage of the viewport
|
|
glViewport ( 0, 0, width, height);
|
|
|
|
glMatrixMode ( GL_PROJECTION );
|
|
glLoadIdentity ();
|
|
|
|
// get matrix
|
|
glOrtho ( -aspect * pzoom, aspect * pzoom,
|
|
-1 * pzoom, pzoom,
|
|
1.0, 32000.0 );
|
|
|
|
// now use modelview-matrix as current matrix
|
|
glMatrixMode(GL_MODELVIEW);
|
|
|
|
haveToUpdate = 1;
|
|
|
|
}
|
|
// glDepthMask(false);
|
|
glEnable(GL_BLEND); // TODO
|
|
glBlendFunc(GL_ONE, GL_ZERO); // TODO
|
|
// glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // TODO
|
|
// glBlendFunc(GL_ONE, GL_ONE); // TODO
|
|
// glBlendFunc(GL_SRC_COLOR, GL_DST_COLOR);
|
|
glHint(GL_POINT_SMOOTH_HINT, GL_NICEST);
|
|
// TODO glDepthFunc(GL_LEQUAL);
|
|
glDepthFunc(GL_LESS); //TODO
|
|
glEnable(GL_DEPTH_TEST);
|
|
glEnable (GL_POINT_SMOOTH);
|
|
}
|
|
|
|
/**
|
|
* Prints out which points were clicked on
|
|
*/
|
|
void ProcessHitsFunc(GLint hits, GLuint buffer[])
|
|
{
|
|
//cout << "SIZE " << selected_points[0].size() << endl;
|
|
//cout << "processing " << endl;
|
|
set<int> names;
|
|
set<sfloat *> unsel_points;
|
|
|
|
GLuint *ptr, nr_names;
|
|
|
|
ptr = (GLuint *)buffer;
|
|
|
|
for(int i = 0 ; i < hits ; i++) {
|
|
nr_names = *ptr;
|
|
ptr+=3; // skip 2 z values
|
|
for(unsigned int j = 0;j < nr_names ; j++){ // iterate over all names
|
|
names.insert(*ptr);
|
|
|
|
ptr++;
|
|
}
|
|
}
|
|
//cout << "number of names " << names.size() << endl;
|
|
if (names.empty()) return;
|
|
|
|
int index = 0;
|
|
set<int>::iterator nit = names.begin();
|
|
// find the respective name
|
|
|
|
for(int iterator = (int)octpts.size()-1; iterator >= 0; iterator--) {
|
|
// iterate over the selected points as in DrawPoints
|
|
for ( set<sfloat*>::iterator it = selected_points[iterator].begin();
|
|
it != selected_points[iterator].end(); it++) {
|
|
if (index == *nit) { // if the current index is the current name
|
|
unsel_points.insert(*it);
|
|
nit++;
|
|
}
|
|
if (nit == names.end()) goto Done; // break out of the loop
|
|
index++;
|
|
}
|
|
}
|
|
|
|
Done:
|
|
|
|
cout << "Erasing " << endl;
|
|
for (set<sfloat*>::iterator it = unsel_points.begin();
|
|
it != unsel_points.end(); it++) { // iterate to the index as indicated by the name *ptr
|
|
for(int iterator = (int)octpts.size()-1; iterator >= 0; iterator--) { // erase for all scans
|
|
selected_points[iterator].erase(*it);
|
|
}
|
|
}
|
|
|
|
|
|
cout << "processing done" << endl;
|
|
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------
|
|
/**
|
|
* This function deals with all our keyboard activities
|
|
*/
|
|
|
|
void InterfaceFunc(unsigned char key){
|
|
|
|
strncpy(path_file_name, path_filename_edit->get_text(), 1024);
|
|
strncpy(pose_file_name, pose_filename_edit->get_text(), 1024);
|
|
return;
|
|
}
|
|
|
|
|
|
void CallBackSpecialFunc(int key , int x, int y) {
|
|
//KeyboardFunc(key + 214, false, false, false);
|
|
// return;
|
|
}
|
|
|
|
/**
|
|
* Function drawRobotPath
|
|
* \brief This functions draws the path where the
|
|
* robot has travelled along while taking the scans
|
|
*/
|
|
void drawRobotPath(int dummy){
|
|
// clear the camera list as we are going to add the cameras
|
|
// in the path where the robot travelled.
|
|
|
|
// lets loop through the entire frame files to extract the
|
|
// total number of places where the robot has taken the scans from
|
|
for(unsigned int i = 0; i < MetaMatrix.size(); i++){
|
|
//temp variable
|
|
double *temp;
|
|
// Now, lets go to the last of each frame file to
|
|
// extract the transformation matrix obtained
|
|
// after scan matching has been done.
|
|
glMultMatrixd(MetaMatrix[i].back());
|
|
|
|
// temp is final transformation matrix
|
|
temp = MetaMatrix[i].back();
|
|
|
|
Point campos(temp[12], temp[13] + 100, temp[14]);
|
|
|
|
// calculate lookat point
|
|
Point lookat(0, 0, 50);
|
|
Point up(0, 50, 0);
|
|
double tmat[16];
|
|
for (int i =0;i<16;i++) tmat[i] = temp[i];
|
|
lookat.transform(tmat);
|
|
lookat.x = lookat.x ;
|
|
lookat.y = lookat.y + 100;
|
|
lookat.z = lookat.z ;
|
|
|
|
up.transform(tmat);
|
|
up.x = up.x ;
|
|
up.y = up.y + 100;
|
|
up.z = up.z ;
|
|
|
|
cams.push_back(campos);
|
|
lookats.push_back(lookat);
|
|
ups.push_back(up);
|
|
}
|
|
updateCamera();
|
|
|
|
// signal for the update of scene
|
|
haveToUpdate = 1;
|
|
}
|
|
|
|
/**
|
|
* Calculates the positions of the interpolated camera path positions on the
|
|
* Nurbs path. There will be an equal number of intermediate positions between
|
|
* neighboring cameras.
|
|
*/
|
|
void calcInterpolatedCameras(vector<PointXY> vec1, vector<PointXY> vec2) {
|
|
NurbsPath::camRatio.clear();
|
|
double distance = 0.0;
|
|
double dx, dy, dz;
|
|
for(unsigned int i=0;i<vec1.size()-1;i++){
|
|
dx = vec1.at(i+1).x - vec1.at(i).x;
|
|
dy = vec1.at(i+1).y - vec1.at(i).y;
|
|
dz = vec2.at(i+1).y - vec2.at(i).y;
|
|
|
|
distance += sqrt(dx*dx + dy*dy + dz*dz );
|
|
}
|
|
double distance2 = 0.0;
|
|
int im_per_cam = (distance/2.0)/(vec1.size() - 1);
|
|
int count = 0;
|
|
for(unsigned int i = 0; i < vec1.size()-1; i++) {
|
|
dx = vec1.at(i+1).x - vec1.at(i).x;
|
|
dy = vec1.at(i+1).y - vec1.at(i).y;
|
|
dz = vec2.at(i+1).y - vec2.at(i).y;
|
|
double curr_dist = sqrt(dx*dx + dy*dy + dz*dz);
|
|
for(int j = 0; j < im_per_cam; j++) {
|
|
count++;
|
|
NurbsPath::camRatio.push_back((distance2 + ((double)j * (curr_dist/(double)im_per_cam)))/(distance + 0.1));
|
|
}
|
|
|
|
distance2 += sqrt(dx*dx + dy*dy + dz*dz);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Calculates the number of interpolation points for the camera path based on
|
|
* the length of the path
|
|
*/
|
|
int calcNoOfPoints(vector<PointXY> vec1, vector<PointXY> vec2)
|
|
{
|
|
double distance = 0.0;
|
|
double dx, dy, dz;
|
|
for(unsigned int i=0;i<vec1.size()-1;i++){
|
|
dx = vec1.at(i+1).x - vec1.at(i).x;
|
|
dy = vec1.at(i+1).y - vec1.at(i).y;
|
|
dz = vec2.at(i+1).y - vec2.at(i).y;
|
|
|
|
distance += sqrt(dx*dx + dy*dy + dz*dz );
|
|
}
|
|
|
|
return distance/2;
|
|
}
|
|
|
|
/**
|
|
* This function handles the the keyboard input
|
|
*/
|
|
void CallBackInterfaceFunc(unsigned char key, int x, int y) {
|
|
//call the interfacefunc. it deals with all our
|
|
//keyboard activities
|
|
InterfaceFunc(key);
|
|
}
|
|
|
|
void CallBackKeyboardUpFunc(unsigned char key, int x, int y) {
|
|
keymap[key] = false;
|
|
if (key >= 'A' && key <= 'Z') {
|
|
keymap[key+ ('a'-'A')] = false;
|
|
}
|
|
if (key >= 'a' && key <= 'z') {
|
|
keymap[key+ ('A'-'a')] = false;
|
|
}
|
|
|
|
for (unsigned int i = 0; i < 256; i++) {
|
|
if (keymap[i]) {
|
|
keypressed = true;
|
|
return;
|
|
}
|
|
}
|
|
keypressed = false;
|
|
}
|
|
|
|
void CallBackKeyboardFunc(unsigned char key, int x, int y) {
|
|
keymap[key] = true;
|
|
keypressed = true;
|
|
bool cmd,alt,shift;
|
|
cmd = glutGetModifiers() & GLUT_ACTIVE_CTRL;
|
|
alt = glutGetModifiers() & GLUT_ACTIVE_ALT;
|
|
shift = glutGetModifiers() & GLUT_ACTIVE_SHIFT;
|
|
if (cmd) {
|
|
key += 96;
|
|
}
|
|
KeyboardFunc(key, cmd, alt, shift);
|
|
}
|
|
|
|
void mapColorToValue(int dummy) {
|
|
switch (listboxColorVal) {
|
|
case 0:
|
|
cm->setCurrentType(PointType::USE_HEIGHT);
|
|
break;
|
|
case 1:
|
|
cm->setCurrentType(PointType::USE_REFLECTANCE);
|
|
break;
|
|
case 2:
|
|
cm->setCurrentType(PointType::USE_TEMPERATURE);
|
|
break;
|
|
case 3:
|
|
cm->setCurrentType(PointType::USE_AMPLITUDE);
|
|
break;
|
|
case 4:
|
|
cm->setCurrentType(PointType::USE_DEVIATION);
|
|
break;
|
|
case 5:
|
|
cm->setCurrentType(PointType::USE_TYPE);
|
|
break;
|
|
case 6:
|
|
cm->setCurrentType(PointType::USE_COLOR);
|
|
break;
|
|
default:
|
|
break;
|
|
};
|
|
resetMinMax(0);
|
|
}
|
|
|
|
void changeColorMap(int dummy) {
|
|
ColorMap c;
|
|
GreyMap gm;
|
|
HSVMap hsv;
|
|
SHSVMap shsv;
|
|
JetMap jm;
|
|
HotMap hot;
|
|
DiffMap diff;
|
|
TempMap temp;
|
|
|
|
switch (listboxColorMapVal) {
|
|
case 0:
|
|
// TODO implement no color map
|
|
cm->setColorMap(c);
|
|
break;
|
|
case 1:
|
|
cm->setColorMap(gm);
|
|
break;
|
|
case 2:
|
|
cm->setColorMap(hsv);
|
|
break;
|
|
case 3:
|
|
cm->setColorMap(jm);
|
|
break;
|
|
case 4:
|
|
cm->setColorMap(hot);
|
|
break;
|
|
case 5:
|
|
cm->setColorMap(diff);
|
|
break;
|
|
case 6:
|
|
cm->setColorMap(shsv);
|
|
break;
|
|
case 7:
|
|
cm->setColorMap(temp);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
void minmaxChanged(int dummy) {
|
|
cm->setMinMax(mincolor_value, maxcolor_value);
|
|
}
|
|
|
|
void resetMinMax(int dummy) {
|
|
mincolor_value = cm->getMin();
|
|
maxcolor_value = cm->getMax();
|
|
minmaxChanged(0);
|
|
}
|
|
|
|
void setScansColored(int dummy) {
|
|
switch(colorScanVal) {
|
|
case 0:
|
|
cm->setMode(ScanColorManager::MODE_STATIC);
|
|
break;
|
|
case 1:
|
|
cm->setMode(ScanColorManager::MODE_COLOR_SCAN);
|
|
break;
|
|
case 2:
|
|
cm->setMode(ScanColorManager::MODE_POINT_COLOR);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
void changePointMode(int dummy) {
|
|
if (dummy == 0) { // always display
|
|
if (pointmode != 1) { // standard mode
|
|
pointmode = 1;
|
|
//never_box->set_int_val(0);
|
|
} else {
|
|
pointmode = 0;
|
|
}
|
|
} else if (dummy == 1) { // never display
|
|
if (pointmode != -1) { // standard mode
|
|
pointmode = -1;
|
|
//always_box->set_int_val(0);
|
|
} else {
|
|
pointmode = 0;
|
|
}
|
|
}
|
|
updatePointModeControls();
|
|
}
|
|
|
|
|
|
void callCameraUpdate(int dummy) {
|
|
updateCamera();
|
|
}
|
|
|
|
void calcPointSequence(vector<int> &sequence, int frameNr) {
|
|
sequence.clear();
|
|
vector<pair<double, int> > dists;
|
|
double x,y,z;
|
|
|
|
for (unsigned int i = 0; i < octpts.size(); i++) {
|
|
// stop at scans that don't have any frames associated with them
|
|
if(i >= MetaMatrix.size()) break;
|
|
// set usable frame
|
|
double* frame;
|
|
if((unsigned int)frameNr >= MetaMatrix[i].size()) {
|
|
// use last possible frame
|
|
frame = MetaMatrix[i].back();
|
|
} else {
|
|
frame = MetaMatrix[i][frameNr];
|
|
}
|
|
x = frame[12];
|
|
y = frame[13];
|
|
z = frame[14];
|
|
dists.push_back( pair<double, int>(sqr(X + x) + sqr(Y + y) + sqr(Z + z), i) );
|
|
}
|
|
|
|
sort( dists.begin(), dists.end());
|
|
|
|
for (unsigned int i = 0; i < dists.size(); i++) {
|
|
sequence.push_back( dists[i].second);
|
|
}
|
|
}
|