//----------------------------------------------------------------------------- // findSelected() -- find the selected graphic from the 'select buffer'. // // 1) When item == 0, returns nearest (by depth buffer) entry. // 2) When item < 0, returns furthest (by depth buffer) entry. // 3) When item > 0, returns the item'th selected entry or the first entry if // there are less than 'item' entries // 4) Returns zero(0) when there are no entries in the select buffer or if the // Graphic for the select ID is not found. //----------------------------------------------------------------------------- BasicGL::Graphic* FoxDisplay::findSelected(const GLuint sbuff[], const int size, const int item) { BasicGL::Graphic* sel = nullptr; GLuint id = 0; GLuint dmin = 0; GLuint dmax = 0; int cnt = 0; int idx = 0; while (idx < size && sbuff[idx] > 0) { int n = sbuff[idx++]; // Number of select names GLuint xmin = sbuff[idx++]; // Min Depth GLuint xmax = sbuff[idx++]; // Max Depth // First select name only GLuint xId = sbuff[idx++]; for (int i = 1; i < n; i++) { idx++; } if (cnt == 0) { // First item id = xId; dmin = xmin; dmax = xmax; } else if (item == 0 && xmin < dmin) { // Nearest -- dmin = xmin; id = xId; } else if (item < 0 && xmax > dmax) { // Nearest -- dmax = xmax; id = xId; } else if (item == (cnt+1)) { id = xId; } cnt++; } // Find the Graphic with this id if (id > 0) { //std::cout << "selected id = " << id << std::endl; Basic::Pair* pair = findBySelectName(id); if (pair != nullptr) { sel = dynamic_cast<BasicGL::Graphic*>(pair->object()); if (sel != nullptr) { return sel; } } } return sel; }
//----------------------------------------------------------------------------- // findSelected() -- find the selected graphic from the 'select buffer'. // // 1) When item == 0, returns nearest (by depth buffer) entry. // 2) When item < 0, returns furthest (by depth buffer) entry. // 3) When item > 0, returns the item'th selected entry or the first entry if // there are less than 'item' entries // 4) Returns zero(0) when there are no entries in the select buffer or if the // Graphic for the select ID is not found. //----------------------------------------------------------------------------- BasicGL::Graphic* GlutDisplay::findSelected(const GLint hits, const GLuint sbuff[], const int item) { Graphic* sel = nullptr; GLuint id = 0; // --- // Build a list of hit names with their z values // --- static const unsigned int MAX_HITS = 64; GLuint hitList[MAX_HITS]; GLuint zminList[MAX_HITS]; GLuint zmaxList[MAX_HITS]; unsigned int hitCnt = 0; unsigned int idx = 0; for (GLint hit = 1; hit <= hits && hitCnt < MAX_HITS; hit++) { GLuint n = sbuff[idx++]; // Number of select names GLuint zmin = sbuff[idx++]; // Min Depth GLuint zmax = sbuff[idx++]; // Max Depth if (n > 0) { hitList[hitCnt] = sbuff[idx]; zminList[hitCnt] = zmin; zmaxList[hitCnt] = zmax; hitCnt++; } for (GLuint i = 0; i < n; i++) idx++; // move past the stack } // --- // We have at least one hit // --- if (hitCnt > 0) { // Select this item (if it exists) if (item > 0 && item <= static_cast<int>(hitCnt)) { id = hitList[item-1]; } // Or look for the nearest else if (item == 0) { // (find the smallest zmin) GLuint h = hitList[0]; GLuint zmin = zminList[0]; for (unsigned int i = 1; i < hitCnt; i++) { if (zminList[i] < zmin) { h = hitList[i]; zmin = zminList[i]; } } id = h; } // Or look for the furthest else if (item < 0) { // (find the largest zmax) GLuint h = hitList[0]; GLuint zmax = zmaxList[0]; for (unsigned int i = 1; i < hitCnt; i++) { if (zmaxList[i] > zmax) { h = hitList[i]; zmax = zmaxList[i]; } } id = h; } } // --- // Find the Graphic with this id // --- if (id > 0) { Basic::Pair* pair = findBySelectName(id); if (pair != nullptr) { sel = static_cast<Graphic*>(pair->object()); } } return sel; }