| 169 | } |
| 170 | else if (ea.getKey()=='p') |
| 171 | { |
| 172 | _usePolytopeIntersector = !_usePolytopeIntersector; |
| 173 | if (_usePolytopeIntersector) |
| 174 | { |
| 175 | osg::notify(osg::NOTICE)<<"Using PolytopeIntersector"<<std::endl; |
| 176 | } else { |
| 177 | osg::notify(osg::NOTICE)<<"Using LineSegmentIntersector"<<std::endl; |
| 178 | } |
| 179 | } |
| 180 | else if (ea.getKey()=='c') |
| 181 | { |
| 182 | _useWindowCoordinates = !_useWindowCoordinates; |
| 183 | if (_useWindowCoordinates) |
| 184 | { |
| 185 | osg::notify(osg::NOTICE)<<"Using window coordinates for picking"<<std::endl; |
| 186 | } else { |
| 187 | osg::notify(osg::NOTICE)<<"Using projection coordiates for picking"<<std::endl; |
| 188 | } |
209 | | bool usePolytopePicking = false; |
210 | | if (usePolytopePicking) |
211 | | { |
212 | | |
213 | | #if 0 |
214 | | // use window coordinates |
215 | | // remap the mouse x,y into viewport coordinates. |
216 | | osg::Viewport* viewport = viewer->getCamera()->getViewport(); |
217 | | double mx = viewport->x() + (int)((double )viewport->width()*(ea.getXnormalized()*0.5+0.5)); |
218 | | double my = viewport->y() + (int)((double )viewport->height()*(ea.getYnormalized()*0.5+0.5)); |
219 | | |
220 | | // half width, height. |
221 | | double w = 5.0f; |
222 | | double h = 5.0f; |
223 | | osgUtil::PolytopeIntersector* picker = new osgUtil::PolytopeIntersector( osgUtil::Intersector::WINDOW, mx-w, my-h, mx+w, my+h ); |
224 | | #else |
225 | | double mx = ea.getXnormalized(); |
226 | | double my = ea.getYnormalized(); |
227 | | double w = 0.05; |
228 | | double h = 0.05; |
229 | | osgUtil::PolytopeIntersector* picker = new osgUtil::PolytopeIntersector( osgUtil::Intersector::PROJECTION, mx-w, my-h, mx+w, my+h ); |
230 | | #endif |
| 231 | if (_usePolytopeIntersector) |
| 232 | { |
| 233 | osgUtil::PolytopeIntersector* picker; |
| 234 | if (_useWindowCoordinates) |
| 235 | { |
| 236 | // use window coordinates |
| 237 | // remap the mouse x,y into viewport coordinates. |
| 238 | osg::Viewport* viewport = viewer->getCamera()->getViewport(); |
| 239 | double mx = viewport->x() + (int)((double )viewport->width()*(ea.getXnormalized()*0.5+0.5)); |
| 240 | double my = viewport->y() + (int)((double )viewport->height()*(ea.getYnormalized()*0.5+0.5)); |
| 241 | |
| 242 | // half width, height. |
| 243 | double w = 5.0f; |
| 244 | double h = 5.0f; |
| 245 | picker = new osgUtil::PolytopeIntersector( osgUtil::Intersector::WINDOW, mx-w, my-h, mx+w, my+h ); |
| 246 | } else { |
| 247 | double mx = ea.getXnormalized(); |
| 248 | double my = ea.getYnormalized(); |
| 249 | double w = 0.05; |
| 250 | double h = 0.05; |
| 251 | picker = new osgUtil::PolytopeIntersector( osgUtil::Intersector::PROJECTION, mx-w, my-h, mx+w, my+h ); |
| 252 | } |
237 | | osgUtil::PolytopeIntersector::Intersection intersection = picker->getFirstIntersection(); |
| 259 | osgUtil::PolytopeIntersector::Intersections& intersections = picker->getIntersections(); |
| 260 | |
| 261 | for (osgUtil::PolytopeIntersector::Intersections::iterator it=intersections.begin(); |
| 262 | it!=intersections.end(); ++it) { |
| 263 | osgUtil::PolytopeIntersector::Intersection intersection=*it; |
| 264 | |
| 265 | osg::NodePath& nodePath = intersection.nodePath; |
| 266 | node = (nodePath.size()>=1)?nodePath[nodePath.size()-1]:0; |
| 267 | parent = (nodePath.size()>=2)?dynamic_cast<osg::Group*>(nodePath[nodePath.size()-2]):0; |
| 268 | |
| 269 | if (node) std::cout<<" Hits "<<node->className()<<" nodePath size"<<nodePath.size()<<std::endl; |
| 270 | toggleScribe(parent, node); |
| 271 | } |
| 272 | |
| 273 | } |
| 274 | |
| 275 | } |
| 276 | else |
| 277 | { |
| 278 | osgUtil::LineSegmentIntersector* picker; |
| 279 | if (!_useWindowCoordinates) |
| 280 | { |
| 281 | // use non dimensional coordinates - in projection/clip space |
| 282 | picker = new osgUtil::LineSegmentIntersector( osgUtil::Intersector::PROJECTION, ea.getXnormalized(),ea.getYnormalized() ); |
| 283 | } else { |
| 284 | // use window coordinates |
| 285 | // remap the mouse x,y into viewport coordinates. |
| 286 | osg::Viewport* viewport = viewer->getCamera()->getViewport(); |
| 287 | float mx = viewport->x() + (int)((float)viewport->width()*(ea.getXnormalized()*0.5f+0.5f)); |
| 288 | float my = viewport->y() + (int)((float)viewport->height()*(ea.getYnormalized()*0.5f+0.5f)); |
| 289 | picker = new osgUtil::LineSegmentIntersector( osgUtil::Intersector::WINDOW, mx, my ); |
| 290 | } |
| 291 | osgUtil::IntersectionVisitor iv(picker); |
| 292 | |
| 293 | viewer->getCamera()->accept(iv); |
| 294 | |
| 295 | if (picker->containsIntersections()) |
| 296 | { |
| 297 | osgUtil::LineSegmentIntersector::Intersection intersection = picker->getFirstIntersection(); |
| 298 | osg::notify(osg::NOTICE)<<"Picked "<<intersection.localIntersectionPoint<<std::endl; |
244 | | |
245 | | } |
246 | | |
| 305 | toggleScribe(parent, node); |
| 306 | } |
| 307 | } |
| 308 | |
| 309 | // now we try to decorate the hit node by the osgFX::Scribe to show that its been "picked" |
| 310 | } |
| 311 | |
| 312 | void toggleScribe(osg::Group* parent, osg::Node* node) { |
| 313 | if (!parent || !node) return; |
| 314 | |
| 315 | std::cout<<" parent "<<parent->className()<<std::endl; |
| 316 | |
| 317 | osgFX::Scribe* parentAsScribe = dynamic_cast<osgFX::Scribe*>(parent); |
| 318 | if (!parentAsScribe) |
| 319 | { |
| 320 | // node not already picked, so highlight it with an osgFX::Scribe |
| 321 | osgFX::Scribe* scribe = new osgFX::Scribe(); |
| 322 | scribe->addChild(node); |
| 323 | parent->replaceChild(node,scribe); |
250 | | |
251 | | #if 0 |
252 | | // use non dimensional coordinates - in projection/clip space |
253 | | osgUtil::LineSegmentIntersector* picker = new osgUtil::LineSegmentIntersector( osgUtil::Intersector::PROJECTION, ea.getXnormalized(),ea.getYnormalized() ); |
254 | | #else |
255 | | // use window coordinates |
256 | | // remap the mouse x,y into viewport coordinates. |
257 | | osg::Viewport* viewport = viewer->getCamera()->getViewport(); |
258 | | float mx = viewport->x() + (int)((float)viewport->width()*(ea.getXnormalized()*0.5f+0.5f)); |
259 | | float my = viewport->y() + (int)((float)viewport->height()*(ea.getYnormalized()*0.5f+0.5f)); |
260 | | osgUtil::LineSegmentIntersector* picker = new osgUtil::LineSegmentIntersector( osgUtil::Intersector::WINDOW, mx, my ); |
261 | | #endif |
262 | | |
263 | | osgUtil::IntersectionVisitor iv(picker); |
264 | | |
265 | | viewer->getCamera()->accept(iv); |
266 | | |
267 | | if (picker->containsIntersections()) |
268 | | { |
269 | | osgUtil::LineSegmentIntersector::Intersection intersection = picker->getFirstIntersection(); |
270 | | osg::notify(osg::NOTICE)<<"Picked "<<intersection.localIntersectionPoint<<std::endl; |
271 | | |
272 | | osg::NodePath& nodePath = intersection.nodePath; |
273 | | node = (nodePath.size()>=1)?nodePath[nodePath.size()-1]:0; |
274 | | parent = (nodePath.size()>=2)?dynamic_cast<osg::Group*>(nodePath[nodePath.size()-2]):0; |
275 | | |
276 | | if (node) std::cout<<" Hits "<<node->className()<<" nodePath size"<<nodePath.size()<<std::endl; |
277 | | |
278 | | } |
279 | | } |
280 | | |
281 | | // now we try to decorate the hit node by the osgFX::Scribe to show that its been "picked" |
282 | | if (parent && node) |
283 | | { |
284 | | |
285 | | std::cout<<" parent "<<parent->className()<<std::endl; |
286 | | |
287 | | osgFX::Scribe* parentAsScribe = dynamic_cast<osgFX::Scribe*>(parent); |
288 | | if (!parentAsScribe) |
289 | | { |
290 | | // node not already picked, so highlight it with an osgFX::Scribe |
291 | | osgFX::Scribe* scribe = new osgFX::Scribe(); |
292 | | scribe->addChild(node); |
293 | | parent->replaceChild(node,scribe); |
294 | | } |
295 | | else |
296 | | { |
297 | | // node already picked so we want to remove scribe to unpick it. |
298 | | osg::Node::ParentList parentList = parentAsScribe->getParents(); |
299 | | for(osg::Node::ParentList::iterator itr=parentList.begin(); |
300 | | itr!=parentList.end(); |
301 | | ++itr) |
302 | | { |
303 | | (*itr)->replaceChild(parentAsScribe,node); |
304 | | } |
305 | | } |
306 | | } |
| 327 | // node already picked so we want to remove scribe to unpick it. |
| 328 | osg::Node::ParentList parentList = parentAsScribe->getParents(); |
| 329 | for(osg::Node::ParentList::iterator itr=parentList.begin(); |
| 330 | itr!=parentList.end(); |
| 331 | ++itr) |
| 332 | { |
| 333 | (*itr)->replaceChild(parentAsScribe,node); |
| 334 | } |
| 335 | } |
| 336 | |