| | 96 | #if 1 |
| | 97 | |
| | 98 | class RayFollowsMouseCallback : public osg::Drawable::EventCallback |
| | 99 | { |
| | 100 | RayFollowsMouseCallback() {} |
| | 101 | |
| | 102 | /** do customized Event code. */ |
| | 103 | virtual void event(osg::NodeVisitor* nv, osg::Drawable* drawable) |
| | 104 | { |
| | 105 | osg::Geometry* geometry = drawable->asGeometry(); |
| | 106 | osgGA::EventVisitor* ev = dynamic_cast<osgGA::EventVisitor*>(nv); |
| | 107 | |
| | 108 | if (!ev || !geometry) return; |
| | 109 | |
| | 110 | osgGA::GUIActionAdapter* aa = ev->getActionAdapter(); |
| | 111 | osgViewer::View* view = dynamic_cast<osgViewer::View*>(aa); |
| | 112 | if (!view) return; |
| | 113 | |
| | 114 | osg::Vec3Array* vertices = dynamic_cast<osg::Vec3Array*>(geometry->getVertexArray()); |
| | 115 | if (!vertices) return; |
| | 116 | |
| | 117 | osg::Camera* camera = view->getCamera(); |
| | 118 | osg::Matrix VP = camera->getViewMatrix() * camera->getProjectionMatrix(); |
| | 119 | |
| | 120 | osg::Matrix inverse_VP; |
| | 121 | inverse_VP.invert(VP); |
| | 122 | |
| | 123 | osgGA::EventQueue::Events& events = ev->getEvents(); |
| | 124 | for(osgGA::EventQueue::Events::iterator itr = events.begin(); |
| | 125 | itr != events.end(); |
| | 126 | ++itr) |
| | 127 | { |
| | 128 | handle(inverse_VP, *(*itr), vertices); |
| | 129 | } |
| | 130 | |
| | 131 | } |
| | 132 | |
| | 133 | void handle(const osg::Matrix& inverse_VP, osgGA::GUIEventAdapter& ea, osg::Vec3Array* vertices) |
| | 134 | { |
| | 135 | osg::Vec3d start_eye(ea.getXnormalized(), ea.getYnormalized(), 0.0); |
| | 136 | osg::Vec3d end_eye(ea.getXnormalized(), ea.getYnormalized(), 1.0); |
| | 137 | |
| | 138 | osg::Vec3d start_world = start_eye * inverse_VP; |
| | 139 | osg::Vec3d end_world = start_eye * inverse_VP; |
| | 140 | |
| | 141 | osg::notify(osg::NOTICE)<<"start_world="<<start_world<<std::endl; |
| | 142 | osg::notify(osg::NOTICE)<<"end_world="<<end_world<<std::endl; |
| | 143 | |
| | 144 | (*vertices)[0] = start_world; |
| | 145 | (*vertices)[1] = end_world; |
| | 146 | } |
| | 147 | }; |
| | 148 | |
| | 149 | class FollowMouseCallback: public osgGA::GUIEventHandler |
| | 150 | { |
| | 151 | public: |
| | 152 | |
| | 153 | virtual bool handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter& aa, osg::Object* object, osg::NodeVisitor* nv) |
| | 154 | { |
| | 155 | osg::AutoTransform* transform = dynamic_cast<osg::AutoTransform*>(object); |
| | 156 | if (!transform) return false; |
| | 157 | |
| | 158 | switch(ea.getEventType()) |
| | 159 | { |
| | 160 | case(osgGA::GUIEventAdapter::FRAME): |
| | 161 | //case(osgGA::GUIEventAdapter::MOVE): |
| | 162 | //case(osgGA::GUIEventAdapter::DRAG): |
| | 163 | { |
| | 164 | osgViewer::View* view = dynamic_cast<osgViewer::View*>(&aa); |
| | 165 | |
| | 166 | transform->setNodeMask(0x0); |
| | 167 | |
| | 168 | osg::notify(osg::NOTICE)<<std::endl<<"ea.getGraphicsContext()="<<ea.getGraphicsContext()<<std::endl; |
| | 169 | osg::notify(osg::NOTICE)<<"ea.getWindowWidth()="<<ea.getWindowWidth()<<std::endl; |
| | 170 | osg::notify(osg::NOTICE)<<"ea.getWindowHeight()="<<ea.getWindowHeight()<<std::endl; |
| | 171 | osg::notify(osg::NOTICE)<<"ea.getX()="<<ea.getX()<<std::endl; |
| | 172 | osg::notify(osg::NOTICE)<<"ea.getXin()="<<ea.getXmin()<<std::endl; |
| | 173 | osg::notify(osg::NOTICE)<<"ea.getXmax()="<<ea.getXmax()<<std::endl; |
| | 174 | osg::notify(osg::NOTICE)<<"ea.getY()="<<ea.getY()<<std::endl; |
| | 175 | osg::notify(osg::NOTICE)<<"ea.getYin()="<<ea.getYmin()<<std::endl; |
| | 176 | osg::notify(osg::NOTICE)<<"ea.getYmax()="<<ea.getYmax()<<std::endl; |
| | 177 | |
| | 178 | osg::Camera* camera = view->getCamera(); |
| | 179 | osg::Matrix VP = camera->getViewMatrix() * camera->getProjectionMatrix(); |
| | 180 | |
| | 181 | osg::Matrix inverse_VP; |
| | 182 | inverse_VP.invert(VP); |
| | 183 | |
| | 184 | osg::Vec3d start_eye(ea.getXnormalized(), ea.getYnormalized(), 0.0); |
| | 185 | osg::Vec3d end_eye(ea.getXnormalized(), ea.getYnormalized(), 1.0); |
| | 186 | |
| | 187 | osg::Vec3d start_world = start_eye * inverse_VP; |
| | 188 | osg::Vec3d end_world = start_eye * inverse_VP; |
| | 189 | |
| | 190 | osg::notify(osg::NOTICE)<<"start_world="<<start_world<<std::endl; |
| | 191 | osg::notify(osg::NOTICE)<<"end_world="<<end_world<<std::endl; |
| | 192 | |
| | 193 | transform->setPosition(end_world); |
| | 194 | |
| | 195 | transform->setNodeMask(0xffffffff); |
| | 196 | |
| | 197 | break; |
| | 198 | } |
| | 199 | case(osgGA::GUIEventAdapter::KEYDOWN): |
| | 200 | { |
| | 201 | if (ea.getKey()=='c') |
| | 202 | { |
| | 203 | for(unsigned int i=0; i< transform->getNumChildren(); ++i) |
| | 204 | { |
| | 205 | osg::Node* node = transform->getChild(i); |
| | 206 | node->setNodeMask( |
| | 207 | node->getNodeMask()!=0 ? |
| | 208 | 0 : |
| | 209 | 0xffffff); |
| | 210 | } |
| | 211 | } |
| | 212 | break; |
| | 213 | } |
| | 214 | default: |
| | 215 | break; |
| | 216 | } |
| | 217 | return false; |
| | 218 | } |
| | 219 | |
| | 220 | virtual void accept(osgGA::GUIEventHandlerVisitor& v) |
| | 221 | { |
| | 222 | v.visit(*this); |
| | 223 | } |
| | 224 | |
| | 225 | }; |
| | 226 | |
| | 227 | osg::Node* createCursorSubgraph(const std::string& filename, float size) |
| | 228 | { |
| | 229 | osg::Geode* geode = new osg::Geode; |
| | 230 | |
| | 231 | size = 20.0f; |
| | 232 | |
| | 233 | osg::Geometry* geom = osg::createTexturedQuadGeometry(osg::Vec3(-size*0.5f,-size*0.5f,0.0f),osg::Vec3(size,0.0f,0.0f),osg::Vec3(0.0f,size,0.0f)); |
| | 234 | |
| | 235 | osg::Image* image = osgDB::readImageFile(osgDB::findDataFile(filename)); |
| | 236 | if (image) |
| | 237 | { |
| | 238 | osg::StateSet* stateset = geom->getOrCreateStateSet(); |
| | 239 | stateset->setTextureAttributeAndModes(0, new osg::Texture2D(image),osg::StateAttribute::ON); |
| | 240 | stateset->setMode(GL_BLEND,osg::StateAttribute::ON); |
| | 241 | // stateset->setMode(GL_DEPTH_TEST,osg::StateAttribute::OFF); |
| | 242 | stateset->setRenderBinDetails(1000, "DepthSortedBin"); |
| | 243 | } |
| | 244 | |
| | 245 | geode->addDrawable(geom); |
| | 246 | |
| | 247 | osg::AutoTransform* transform = new osg::AutoTransform; |
| | 248 | transform->setAutoRotateMode(osg::AutoTransform::ROTATE_TO_CAMERA); |
| | 249 | transform->setAutoScaleToScreen(true); |
| | 250 | |
| | 251 | transform->addChild(geode); |
| | 252 | |
| | 253 | transform->setEventCallback(new FollowMouseCallback()); |
| | 254 | |
| | 255 | return transform; |
| | 256 | |
| | 257 | } |
| | 258 | #else |