00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include <GL/glew.h>
00018 #include "Pick.h"
00019 #include <algorithm>
00020 #include <iostream>
00021 #include <limits>
00022
00023 using namespace std;
00024
00025
00026
00027
00028 void Pick::startPickGL(double x, double y, double pickWin)
00029 {
00030 GLint viewport[4];
00031 glGetIntegerv(GL_VIEWPORT,viewport);
00032 GLfloat proj[16];
00033 glGetFloatv(GL_PROJECTION_MATRIX,proj);
00034
00035
00036 glMatrixMode(GL_PROJECTION);
00037 {
00038 glPushMatrix();
00039 glLoadIdentity();
00040 gluPickMatrix(x, y, pickWin, pickWin, viewport);
00041 glMultMatrixf(proj);
00042 }
00043 glMatrixMode(GL_MODELVIEW);
00044
00045
00046 glSelectBuffer(_pbSize, _pickBuffer);
00047 glRenderMode(GL_SELECT);
00048
00049
00050 glInitNames();
00051
00052 _picking = true;
00053 }
00054
00055
00056
00057 struct PBSortZ1 {
00058 bool operator() (const PickInfo &pi1, const PickInfo &pi2)
00059 {
00060 return pi1.z1 < pi2.z1;
00061 }
00062 };
00063
00064
00065
00066 PickInfoVec Pick::endPickGL()
00067 {
00068
00069
00070 if(!_picking)
00071 {
00072 cerr << "Pick::endPickGL(), you must call startPickGL() before endPickGL()" << endl;
00073 return PickInfoVec();
00074 }
00075 _picking = false;
00076
00077
00078 glMatrixMode(GL_PROJECTION);
00079 {
00080 glPopMatrix();
00081 }
00082 glMatrixMode(GL_MODELVIEW);
00083
00084
00085 GLint hits = glRenderMode(GL_RENDER);
00086
00087
00088 if(!hits) return PickInfoVec();
00089
00090
00091 PickInfoVec piv;
00092
00093
00094 for(int i=0, j=0; i<hits; ++i)
00095 {
00096
00097
00098
00099 if( j >= _pbSize )
00100 {
00101 cerr << "Pick::endPick(), pick-buffer overrun, try increasing the "
00102 << "size of the pick buffer." << endl;
00103 sort(piv.begin(), piv.end(), PBSortZ1());
00104 return piv;
00105 }
00106
00107
00108
00109 unsigned int nnames = _pickBuffer[j++];
00110
00111
00112
00113
00114 if( int(j+nnames+1) >= _pbSize )
00115 {
00116 cerr << "Pick::endPick(), pick-buffer overrun, try increasing the "
00117 << "size of the pick buffer.." << endl;
00118 sort(piv.begin(), piv.end(), PBSortZ1());
00119 return piv;
00120 }
00121
00122
00123
00124 piv.push_back(
00125 PickInfo(
00126 _pickBuffer[j ]/double(std::numeric_limits<unsigned int>::max()),
00127 _pickBuffer[j+1]/double(std::numeric_limits<unsigned int>::max()),
00128 &(_pickBuffer[j+2]), nnames
00129 )
00130 );
00131
00132
00133 j += nnames + 2;
00134
00135 }
00136
00137
00138 sort(piv.begin(),piv.end(),PBSortZ1());
00139 return piv;
00140 }