osgkeyboard例子

本文介绍了一个基于OSG的键盘交互示例程序,详细解释了如何通过添加事件处理器实现键盘输入反馈,并更新屏幕上的文本内容。示例展示了如何创建键盘模型、设置按键样式以及处理按键事件。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

osgkeyboard例子中包含的内容:

(1)显示osgText.

(2)在viewer中添加事件处理:GUIEventHandler.

解析如下:

class KeyboardModel : public osg::Referenced
{
public:

KeyboardModel() { createKeyboard(); }
       
        osg::Group* getScene() { return _scene.get(); }
       
        void keyChange(int key,int value);//每当用户按下或松开按钮时调用
       
protected:
       
        ~KeyboardModel() {}

        osg::Switch* addKey(osg::Vec3& pos, int key,const std::string& text,float width, float height);
        osg::Switch* addKey(int key,osg::Switch* sw);

        void createKeyboard();//构造函数中调用

        typedef std::map<int, osg::ref_ptr<osg::Switch> > KeyModelMap;
       
       osg::ref_ptr<osg::Group>    _scene;//场景节点
        KeyModelMap                 _keyModelMap;//map(字符ID,开关节点),如_keyModelMap["P"] = switch
        osg::ref_ptr<osgText::Text> _inputText;//显示的文本(会随着按键而改变)

};

void KeyboardModel::keyChange(int key,int value)
{
 
  // toggle the keys graphical representation on or off via osg::Swithc
    KeyModelMap::iterator itr = _keyModelMap.find(key);
    if (itr!=_keyModelMap.end())
    {
       itr->second->setSingleChildOn(value);
  //itr->second即找到的switch,例_keyModelMap["P"] = switch,则switch只打开一个(setSingleChildOn()),
  //当按下"P"时,由于KeyboardEventHandler::handle()中_keyboardModel->keyChange(ea.getKey(),1);表示显示
  //的索引值是1(即第2个红色的),否则如果按键松开,则显示的索引值是0(第一个白色的).
    }
   
    if (value)//只有当用户按下某个键时,value=1.
    {
        // when a key is pressed add the new data to the text field
       
        if (key>0 && key<256)
        {
            // just add ascii characters right now...
            _inputText->getText().push_back(key);//直接将输入的字符添加,会显示出来
            _inputText->update();
        }
        else if (key==osgGA::GUIEventAdapter::KEY_Return)
        {
            _inputText->getText().push_back('/n');//换行
            _inputText->update();
        }
else if (key==osgGA::GUIEventAdapter::KEY_BackSpace || key==osgGA::GUIEventAdapter::KEY_Delete)
        {
            if (!_inputText->getText().empty())
            {
                _inputText->getText().pop_back();//删除
                _inputText->update();
            }
        }
       
    }
   
}

osg::Switch* KeyboardModel::addKey(osg::Vec3& pos, int key,const std::string& text,float width, float height)
{

    osg::Geode* geodeUp = new osg::Geode;//第1个字符(白色)
    {
        osgText::Text* textUp = new osgText::Text;
        textUp->setFont("fonts/arial.ttf");
        textUp->setColor(osg::Vec4(1.0f,1.0f,1.0f,1.0f));//(白色)
        textUp->setCharacterSize(height);
        textUp->setPosition(pos);
        textUp->setDrawMode(osgText::Text::TEXT/*|osgText::Text::BOUNDINGBOX*/);
        textUp->setAlignment(osgText::Text::LEFT_CENTER);
        textUp->setAxisAlignment(osgText::Text::XZ_PLANE);
        textUp->setText(text);
       
        geodeUp->addDrawable(textUp);
    }
   
   osg::Geode* geodeDown = new osg::Geode;//第2个字符(红色)
    {
        osgText::Text* textDown = new osgText::Text;
        textDown->setFont("fonts/arial.ttf");
        textDown->setColor(osg::Vec4(1.0f,0.0f,1.0f,1.0f));//(红色)
        textDown->setCharacterSize(height);
        textDown->setPosition(pos);
        textDown->setDrawMode(osgText::Text::TEXT/*||osgText::Text::BOUNDINGBOX*/);
        textDown->setAlignment(osgText::Text::LEFT_CENTER);
        textDown->setAxisAlignment(osgText::Text::XZ_PLANE);
        textDown->setText(text);
       
        geodeDown->addDrawable(textDown);
    }

    osg::Switch* model = new osg::Switch;//开关节点,添加2个Geode,且每次只能一个打开,即只显示一个
    model->addChild(geodeUp,true);
    model->addChild(geodeDown,false);
   
    _scene->addChild(model);//加入_scene

    _keyModelMap[key] = model;//例_keyModelMap["P"] = model
   
    pos.x() += width;
   
    return model;
   
}

osg::Switch* KeyboardModel::addKey(int key,osg::Switch* sw)
{
    _keyModelMap[key] = sw;//例_keyModelMap["p"]= _keyModelMap["P"] = switch
    return sw;
}

void KeyboardModel::createKeyboard()
{
    _scene = new osg::Group;
   
    osg::Vec3 origin(0.0f,0.0f,0.0f);
    osg::Vec3 pos=origin;
   
    addKey(pos,osgGA::GUIEventAdapter::KEY_Control_L,"Ctrl",2.0f,0.5f);
    ......
    addKey('P',addKey(pos,'p',"P",1.0f,1.0f));
//括号里的addKey()表示,对于"p",显示为"P",然后括号外的addKey(),第二个参数使用同样的switch,
//即大小写P都用同一个switch,且_keyModelMap["p"]= _keyModelMap["P"] = switch
    ...
    pos.x() = 0.0f;
    pos.z() += 1.0f;
   
    ......
   
}


class KeyboardEventHandler : public osgGA::GUIEventHandler
{
public:
   
        KeyboardEventHandler(KeyboardModel* keyboardModel):
            _keyboardModel(keyboardModel) {}
   
       virtual bool handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter&)
        {

   ......
            switch(ea.getEventType())
            {
                case(osgGA::GUIEventAdapter::KEYDOWN):
                {
     //keyChange()第二个参数:0表示第一个显示字符(绿色),1表示第二个显示字符(红色).
     //switch开关使红色字符显示
                    _keyboardModel->keyChange(ea.getKey(),1);
                    return true;//返回true后,别的EventHandler不会处理了,该按键事件处理完毕
                }
                case(osgGA::GUIEventAdapter::KEYUP):
                {
                    _keyboardModel->keyChange(ea.getKey(),0);
                    return true;
                }

                default:
                    return false;
            }
        }
       
        osg::ref_ptr<KeyboardModel> _keyboardModel;//数据成员,以便处理按键时能找到对象指针()
       
};

int main(int , char **)
{
    osgViewer::Viewer viewer;

    osg::ref_ptr<KeyboardModel> keyboardModel = new KeyboardModel;

    ......
   viewer.addEventHandler(new KeyboardEventHandler(keyboardModel.get()));
    viewer.setSceneData( keyboardModel->getScene() );

    return viewer.run();
}

========================

========================

========================

========================

完整的osgkeyboard代码如下:

#include <osgViewer/Viewer>
#include <osgViewer/ViewerEventHandlers>
#include <osg/io_utils>

#include <osg/MatrixTransform>
#include <osg/Geode>
#include <osg/Group>
#include <osg/Switch>
#include <osg/Notify>
#include <osg/Geometry>

#include <osgText/Text>

#include <osgDB/Registry>
#include <osgDB/ReadFile>
#include <osgDB/WriteFile>


class KeyboardModel : public osg::Referenced
{
public:

        KeyboardModel() { createKeyboard(); }
       
        osg::Group* getScene() { return _scene.get(); }
       
        void keyChange(int key,int value);
       
protected:
       
        ~KeyboardModel() {}

        osg::Switch* addKey(osg::Vec3& pos, int key,const std::string& text,float width, float height);
        osg::Switch* addKey(int key,osg::Switch* sw);

        void createKeyboard();

        typedef std::map<int, osg::ref_ptr<osg::Switch> > KeyModelMap;
       
        osg::ref_ptr<osg::Group>    _scene;
        KeyModelMap                 _keyModelMap;
        osg::ref_ptr<osgText::Text> _inputText;

};

void KeyboardModel::keyChange(int key,int value)
{
    osg::notify(osg::INFO) << "key value change, code="<<std::hex << key << "/t value="<< value << std::dec  << std::endl;

    // toggle the keys graphical representation on or off via osg::Swithc
    KeyModelMap::iterator itr = _keyModelMap.find(key);
    if (itr!=_keyModelMap.end())
    {
        itr->second->setSingleChildOn(value);
    }
   
    if (value)
    {
        // when a key is pressed add the new data to the text field
       
        if (key>0 && key<256)
        {
            // just add ascii characters right now...
            _inputText->getText().push_back(key);
            _inputText->update();
        }
        else if (key==osgGA::GUIEventAdapter::KEY_Return)
        {
            _inputText->getText().push_back('/n');
            _inputText->update();
        }
        else if (key==osgGA::GUIEventAdapter::KEY_BackSpace || key==osgGA::GUIEventAdapter::KEY_Delete)
        {
            if (!_inputText->getText().empty())
            {
                _inputText->getText().pop_back();
                _inputText->update();
            }
        }
       
    }
   
}

osg::Switch* KeyboardModel::addKey(osg::Vec3& pos, int key,const std::string& text,float width, float height)
{

    osg::Geode* geodeUp = new osg::Geode;
    {
        osgText::Text* textUp = new osgText::Text;
        textUp->setFont("fonts/arial.ttf");
        textUp->setColor(osg::Vec4(1.0f,1.0f,1.0f,1.0f));
        textUp->setCharacterSize(height);
        textUp->setPosition(pos);
        textUp->setDrawMode(osgText::Text::TEXT/*|osgText::Text::BOUNDINGBOX*/);
        textUp->setAlignment(osgText::Text::LEFT_CENTER);
        textUp->setAxisAlignment(osgText::Text::XZ_PLANE);
        textUp->setText(text);
       
        geodeUp->addDrawable(textUp);
    }
   
    osg::Geode* geodeDown = new osg::Geode;
    {
        osgText::Text* textDown = new osgText::Text;
        textDown->setFont("fonts/arial.ttf");
        textDown->setColor(osg::Vec4(1.0f,0.0f,1.0f,1.0f));
        textDown->setCharacterSize(height);
        textDown->setPosition(pos);
        textDown->setDrawMode(osgText::Text::TEXT/*||osgText::Text::BOUNDINGBOX*/);
        textDown->setAlignment(osgText::Text::LEFT_CENTER);
        textDown->setAxisAlignment(osgText::Text::XZ_PLANE);
        textDown->setText(text);
       
        geodeDown->addDrawable(textDown);
    }

    osg::Switch* model = new osg::Switch;
    model->addChild(geodeUp,true);
    model->addChild(geodeDown,false);
   
    _scene->addChild(model);

    _keyModelMap[key] = model;
   
    pos.x() += width;
   
    return model;
   
}

osg::Switch* KeyboardModel::addKey(int key,osg::Switch* sw)
{
    _keyModelMap[key] = sw;
    return sw;
}

void KeyboardModel::createKeyboard()
{
    _scene = new osg::Group;
   
    osg::Vec3 origin(0.0f,0.0f,0.0f);
    osg::Vec3 pos=origin;
   
    addKey(pos,osgGA::GUIEventAdapter::KEY_Control_L,"Ctrl",2.0f,0.5f);
    addKey(pos,osgGA::GUIEventAdapter::KEY_Super_L,"Super",2.0f,0.5f);
    addKey(pos,osgGA::GUIEventAdapter::KEY_Alt_L,"Alt",2.0f,0.5f);
    addKey(pos,osgGA::GUIEventAdapter::KEY_Space,"Space",3.0f,1.0f);
    addKey(pos,osgGA::GUIEventAdapter::KEY_Mode_switch,"Switch",2.0f,0.5f);
    addKey(pos,osgGA::GUIEventAdapter::KEY_Super_R,"Super",2.0f,0.5f);
    addKey(pos,osgGA::GUIEventAdapter::KEY_Menu,"Menu",2.0f,0.5f);
    addKey(pos,osgGA::GUIEventAdapter::KEY_Control_R,"Ctrl",2.0f,0.5f);

    osg::Vec3 middle(pos.x()+1.0f,0.0f,0.0f);
   
    pos.x() = 0.0f;
    pos.z() += 1.0f;

    addKey(pos,osgGA::GUIEventAdapter::KEY_Shift_L,"Shift",2.0f,0.5f);
    addKey(pos,'//',"//",1.0f,1.0f);
    addKey('Z',addKey(pos,'z',"Z",1.0f,1.0f));
    addKey('X',addKey(pos,'x',"X",1.0f,1.0f));
    addKey('C',addKey(pos,'c',"C",1.0f,1.0f));
    addKey('V',addKey(pos,'v',"V",1.0f,1.0f));
    addKey('B',addKey(pos,'b',"B",1.0f,1.0f));
    addKey('N',addKey(pos,'n',"N",1.0f,1.0f));
    addKey('M',addKey(pos,'m',"M",1.0f,1.0f));
    addKey('<',addKey(pos,',',",",1.0f,1.0f));
    addKey('>',addKey(pos,'.',".",1.0f,1.0f));
    addKey('?',addKey(pos,'/',"/",1.0f,1.0f));
    addKey(pos,osgGA::GUIEventAdapter::KEY_Shift_R,"Shift",2.0f,0.5f);

    pos.x() = 0.0f;
    pos.z() += 1.0f;
   
    addKey(pos,osgGA::GUIEventAdapter::KEY_Caps_Lock,"Caps",2.0f,0.5f);
    addKey('A',addKey(pos,'a',"A",1.0f,1.0f));
    addKey('S',addKey(pos,'s',"S",1.0f,1.0f));
    addKey('D',addKey(pos,'d',"D",1.0f,1.0f));
    addKey('F',addKey(pos,'f',"F",1.0f,1.0f));
    addKey('G',addKey(pos,'g',"G",1.0f,1.0f));
    addKey('H',addKey(pos,'h',"H",1.0f,1.0f));
    addKey('J',addKey(pos,'j',"J",1.0f,1.0f));
    addKey('K',addKey(pos,'k',"K",1.0f,1.0f));
    addKey('L',addKey(pos,'l',"L",1.0f,1.0f));
    addKey(':',addKey(pos,';',";",1.0f,1.0f));
    addKey('@',addKey(pos,'/'',"'",1.0f,1.0f));
    addKey('~',addKey(pos,'#',"#",1.0f,1.0f));
    addKey(pos,osgGA::GUIEventAdapter::KEY_Return,"Return",4.0f,0.5f);

    pos.x() = 0.0f;
    pos.z() += 1.0f;
   
    addKey(pos,osgGA::GUIEventAdapter::KEY_Tab,"Tab",2.0f,0.5f);
    addKey('Q',addKey(pos,'q',"Q",1.0f,1.0f));
    addKey('W',addKey(pos,'w',"W",1.0f,1.0f));
    addKey('E',addKey(pos,'e',"E",1.0f,1.0f));
    addKey('R',addKey(pos,'r',"R",1.0f,1.0f));
    addKey('T',addKey(pos,'t',"T",1.0f,1.0f));
    addKey('Y',addKey(pos,'y',"Y",1.0f,1.0f));
    addKey('U',addKey(pos,'u',"U",1.0f,1.0f));
    addKey('I',addKey(pos,'i',"I",1.0f,1.0f));
    addKey('O',addKey(pos,'o',"O",1.0f,1.0f));
    addKey('P',addKey(pos,'p',"P",1.0f,1.0f));
    addKey('{',addKey(pos,'[',"[",1.0f,1.0f));
    addKey('}',addKey(pos,']',"]",1.0f,1.0f));

    pos.x() = 0.0f;
    pos.z() += 1.0f;
   
    addKey(pos,'`',"`",1.0f,1.0f);
    addKey(pos,'1',"1",1.0f,1.0f);
    addKey(pos,'2',"2",1.0f,1.0f);
    addKey(pos,'3',"3",1.0f,1.0f);
    addKey(pos,'4',"4",1.0f,1.0f);
    addKey(pos,'5',"5",1.0f,1.0f);
    addKey(pos,'6',"6",1.0f,1.0f);
    addKey(pos,'7',"7",1.0f,1.0f);
    addKey(pos,'8',"8",1.0f,1.0f);
    addKey(pos,'9',"9",1.0f,1.0f);
    addKey(pos,'0',"0",1.0f,1.0f);
    addKey(pos,'-',"-",1.0f,1.0f);
    addKey(pos,'=',"=",1.0f,1.0f);
    addKey(pos,osgGA::GUIEventAdapter::KEY_BackSpace,"Backspace",3.0f,0.5f);

    pos.x() = 0.0f;
    pos.z() += 1.5f;
   
    float F_height = 0.5f;
    addKey(pos,osgGA::GUIEventAdapter::KEY_Escape,"Esc",2.0f,F_height);
    addKey(pos,osgGA::GUIEventAdapter::KEY_F1,"F1",1.0f,F_height);
    addKey(pos,osgGA::GUIEventAdapter::KEY_F2,"F2",1.0f,F_height);
    addKey(pos,osgGA::GUIEventAdapter::KEY_F3,"F3",1.0f,F_height);
    addKey(pos,osgGA::GUIEventAdapter::KEY_F4,"F4",1.0f,F_height);
    addKey(pos,osgGA::GUIEventAdapter::KEY_F5,"F5",1.0f,F_height);
    addKey(pos,osgGA::GUIEventAdapter::KEY_F6,"F6",1.0f,F_height);
    addKey(pos,osgGA::GUIEventAdapter::KEY_F7,"F7",1.0f,F_height);
    addKey(pos,osgGA::GUIEventAdapter::KEY_F8,"F8",1.0f,F_height);
    addKey(pos,osgGA::GUIEventAdapter::KEY_F9,"F9",1.0f,F_height);
    addKey(pos,osgGA::GUIEventAdapter::KEY_F10,"F10",1.0f,F_height);
    addKey(pos,osgGA::GUIEventAdapter::KEY_F11,"F11",1.0f,F_height);
    addKey(pos,osgGA::GUIEventAdapter::KEY_F12,"F12",1.0f,F_height);


   
    float cursorMoveHeight=0.35f;

    pos = middle;   
    addKey(pos,osgGA::GUIEventAdapter::KEY_Left,"Left",1.0f,cursorMoveHeight);
    osg::Vec3 down = pos;
    addKey(pos,osgGA::GUIEventAdapter::KEY_Down,"Down",1.0f,cursorMoveHeight);
    addKey(pos,osgGA::GUIEventAdapter::KEY_Right,"Right",1.0f,cursorMoveHeight);
   
    osg::Vec3 keypad = pos;
    keypad.x()+=1.0f;

    pos = down;
    pos.z() += 1.0f;
   
    addKey(pos,osgGA::GUIEventAdapter::KEY_Up,"Up",1.0f,cursorMoveHeight);
   

    float homeHeight = 0.35f;
    pos = middle;
    pos.z() += 3.0;   
    addKey(pos,osgGA::GUIEventAdapter::KEY_Delete,"Delete",1.0f,homeHeight);
    addKey(pos,osgGA::GUIEventAdapter::KEY_End,"End",1.0f,homeHeight);
    addKey(pos,osgGA::GUIEventAdapter::KEY_Page_Down,"Page/nDown",1.0f,homeHeight);
   
    pos = middle;
    pos.z() += 4.0;   
    addKey(pos,osgGA::GUIEventAdapter::KEY_Insert,"Insert",1.0f,homeHeight);
    addKey(pos,osgGA::GUIEventAdapter::KEY_Home,"Home",1.0f,homeHeight);
    addKey(pos,osgGA::GUIEventAdapter::KEY_Page_Up,"Page/nUp",1.0f,homeHeight);

    pos = middle;
    pos.z() += 5.5;   
    addKey(pos,osgGA::GUIEventAdapter::KEY_Print,"PrtScrn/nSysRq",1.0f,homeHeight);
    addKey(pos,osgGA::GUIEventAdapter::KEY_Scroll_Lock,"ScrLk",1.0f,homeHeight);
    addKey(pos,osgGA::GUIEventAdapter::KEY_Pause,"Pause/nBreak",1.0f,homeHeight);
   
   

    pos = keypad;
    addKey(pos,osgGA::GUIEventAdapter::KEY_KP_Insert,"0",2.0f,1.0f);
    addKey(pos,osgGA::GUIEventAdapter::KEY_KP_Delete,".",1.0f,1.0f);
    addKey(pos,osgGA::GUIEventAdapter::KEY_KP_Enter,"Enter",1.0f,homeHeight);
   
    pos = keypad;
    pos.z() += 1.0f;
    addKey(pos,osgGA::GUIEventAdapter::KEY_KP_End,"1",1.0f,1.0f);
    addKey(pos,osgGA::GUIEventAdapter::KEY_KP_Down,"2",1.0f,1.0f);
    addKey(pos,osgGA::GUIEventAdapter::KEY_KP_Page_Down,"3",1.0f,1.0f);

    pos = keypad;
    pos.z() += 2.0f;
    addKey(pos,osgGA::GUIEventAdapter::KEY_KP_Left,"4",1.0f,1.0f);
    addKey(pos,osgGA::GUIEventAdapter::KEY_KP_Begin,"5",1.0f,1.0f);
    addKey(pos,osgGA::GUIEventAdapter::KEY_KP_Right,"6",1.0f,1.0f);
    addKey(pos,osgGA::GUIEventAdapter::KEY_KP_Add,"+",1.0f,1.0f);

    pos = keypad;
    pos.z() += 3.0f;
    addKey(pos,osgGA::GUIEventAdapter::KEY_KP_Home,"7",1.0f,1.0f);
    addKey(pos,osgGA::GUIEventAdapter::KEY_KP_Up,"8",1.0f,1.0f);
    addKey(pos,osgGA::GUIEventAdapter::KEY_KP_Page_Up,"9",1.0f,1.0f);

    pos = keypad;
    pos.z() += 4.0f;
    addKey(pos,osgGA::GUIEventAdapter::KEY_Num_Lock,"Num/nLock",1.0f,0.3f);
    addKey(pos,osgGA::GUIEventAdapter::KEY_KP_Divide,"/",1.0f,1.0f);
    addKey(pos,osgGA::GUIEventAdapter::KEY_KP_Multiply,"*",1.0f,1.0f);
    addKey(pos,osgGA::GUIEventAdapter::KEY_KP_Subtract,"-",1.0f,1.0f);
   
    float totalWidth = pos.x()-origin.x();
    pos = origin;
    pos.z() += -1.5f;

    osg::Geode* geodeInput = new osg::Geode;
    {
        _inputText = new osgText::Text;
        _inputText->setFont("fonts/arial.ttf");
        _inputText->setColor(osg::Vec4(1.0f,1.0f,0.0f,1.0f));
        _inputText->setCharacterSize(1.0f);
        _inputText->setMaximumWidth(totalWidth);
        _inputText->setPosition(pos);
        _inputText->setDrawMode(osgText::Text::TEXT/*||osgText::Text::BOUNDINGBOX*/);
        _inputText->setAlignment(osgText::Text::BASE_LINE);
        _inputText->setAxisAlignment(osgText::Text::XZ_PLANE);
        _inputText->setDataVariance(osg::Object::DYNAMIC);
        _inputText->setText("Press some keys...");
       
        geodeInput->addDrawable(_inputText.get());
       
        _scene->addChild(geodeInput);
    }

}


class KeyboardEventHandler : public osgGA::GUIEventHandler
{
public:
   
        KeyboardEventHandler(KeyboardModel* keyboardModel):
            _keyboardModel(keyboardModel) {}
   
        virtual bool handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter&)
        {

#if 1

//            osg::notify(osg::NOTICE)<<"Mouse "<<ea.getButtonMask()<<std::endl;

            #define PRINT(mask) osg::notify(osg::NOTICE)<<#mask<<" ="<<(ea.getModKeyMask() & mask)<<std::endl;
            switch(ea.getEventType())
            {
                case(osgGA::GUIEventAdapter::KEYDOWN):
                case(osgGA::GUIEventAdapter::KEYUP):
                {
                    osg::notify(osg::NOTICE)<<std::endl;
                    PRINT(osgGA::GUIEventAdapter::MODKEY_LEFT_SHIFT);
                    PRINT(osgGA::GUIEventAdapter::MODKEY_RIGHT_SHIFT);
                    PRINT(osgGA::GUIEventAdapter::MODKEY_LEFT_ALT);
                    PRINT(osgGA::GUIEventAdapter::MODKEY_RIGHT_ALT);
                    PRINT(osgGA::GUIEventAdapter::MODKEY_LEFT_CTRL);
                    PRINT(osgGA::GUIEventAdapter::MODKEY_RIGHT_CTRL);
                    PRINT(osgGA::GUIEventAdapter::MODKEY_LEFT_META);
                    PRINT(osgGA::GUIEventAdapter::MODKEY_RIGHT_META);
                    PRINT(osgGA::GUIEventAdapter::MODKEY_LEFT_SUPER);
                    PRINT(osgGA::GUIEventAdapter::MODKEY_RIGHT_SUPER);
                    PRINT(osgGA::GUIEventAdapter::MODKEY_LEFT_HYPER);
                    PRINT(osgGA::GUIEventAdapter::MODKEY_RIGHT_HYPER);
                    PRINT(osgGA::GUIEventAdapter::MODKEY_NUM_LOCK);
                    PRINT(osgGA::GUIEventAdapter::MODKEY_CAPS_LOCK);
                    break;
                }
                default:
                    break;
            }
#endif
            switch(ea.getEventType())
            {
                case(osgGA::GUIEventAdapter::KEYDOWN):
                {
                    _keyboardModel->keyChange(ea.getKey(),1);
                    return true;
                }
                case(osgGA::GUIEventAdapter::KEYUP):
                {
                    _keyboardModel->keyChange(ea.getKey(),0);
                    return true;
                }

                default:
                    return false;
            }
        }
       
        osg::ref_ptr<KeyboardModel> _keyboardModel;
       
};

int main(int , char **)
{
    osgViewer::Viewer viewer;

    osg::ref_ptr<KeyboardModel> keyboardModel = new KeyboardModel;

    viewer.addEventHandler(new osgViewer::StatsHandler);
    viewer.addEventHandler(new osgViewer::WindowSizeHandler());
    viewer.addEventHandler(new KeyboardEventHandler(keyboardModel.get()));
    viewer.setSceneData( keyboardModel->getScene() );

    return viewer.run();
}

 

 

转:http://blog.youkuaiyun.com/tmljs1988/article/details/6367961

基于数据挖掘的音乐推荐系统设计与实现 需要一个代码说明,不需要论文 采用python语言,django框架,mysql数据库开发 编程环境:pycharm,mysql8.0 系统分为前台+后台模式开发 网站前台: 用户注册, 登录 搜索音乐,音乐欣赏(可以在线进行播放) 用户登陆时选择相关感兴趣的音乐风格 音乐收藏 音乐推荐算法:(重点) 本课题需要大量用户行为(如播放记录、收藏列表)、音乐特征(如音频特征、歌曲元数据)等数据 (1)根据用户之间相似性或关联性,给一个用户推荐与其相似或有关联的其他用户所感兴趣的音乐; (2)根据音乐之间的相似性或关联性,给一个用户推荐与其感兴趣的音乐相似或有关联的其他音乐。 基于用户的推荐和基于物品的推荐 其中基于用户的推荐是基于用户的相似度找出相似相似用户,然后向目标用户推荐其相似用户喜欢的东西(和你类似的人也喜欢**东西); 而基于物品的推荐是基于物品的相似度找出相似的物品做推荐(喜欢该音乐的人还喜欢了**音乐); 管理员 管理员信息管理 注册用户管理,审核 音乐爬虫(爬虫方式爬取网站音乐数据) 音乐信息管理(上传歌曲MP3,以便前台播放) 音乐收藏管理 用户 用户资料修改 我的音乐收藏 完整前后端源码,部署后可正常运行! 环境说明 开发语言:python后端 python版本:3.7 数据库:mysql 5.7+ 数据库工具:Navicat11+ 开发软件:pycharm
MPU6050是一款广泛应用在无人机、机器人和运动设备中的六轴姿态传感器,它集成了三轴陀螺仪和三轴加速度计。这款传感器能够实时监测并提供设备的角速度和线性加速度数据,对于理解物体的动态运动状态至关重要。在Arduino平台上,通过特定的库文件可以方便地与MPU6050进行通信,获取并解析传感器数据。 `MPU6050.cpp`和`MPU6050.h`是Arduino库的关键组成部分。`MPU6050.h`是头文件,包含了定义传感器接口和函数声明。它定义了类`MPU6050`,该类包含了初始化传感器、读取数据等方法。例如,`begin()`函数用于设置传感器的工作模式和I2C地址,`getAcceleration()`和`getGyroscope()`则分别用于获取加速度和角速度数据。 在Arduino项目中,首先需要包含`MPU6050.h`头文件,然后创建`MPU6050`对象,并调用`begin()`函数初始化传感器。之后,可以通过循环调用`getAcceleration()`和`getGyroscope()`来不断更新传感器读数。为了处理这些原始数据,通常还需要进行校准和滤波,以消除噪声和漂移。 I2C通信协议是MPU6050与Arduino交互的基础,它是一种低引脚数的串行通信协议,允许多个设备共享一对数据线。Arduino板上的Wire库提供了I2C通信的底层支持,使得用户无需深入了解通信细节,就能方便地与MPU6050交互。 MPU6050传感器的数据包括加速度(X、Y、Z轴)和角速度(同样为X、Y、Z轴)。加速度数据可以用来计算物体的静态位置和动态运动,而角速度数据则能反映物体转动的速度。结合这两个数据,可以进一步计算出物体的姿态(如角度和角速度变化)。 在嵌入式开发领域,特别是使用STM32微控制器时,也可以找到类似的库来驱动MPU6050。STM32通常具有更强大的处理能力和更多的GPIO口,可以实现更复杂的控制算法。然而,基本的传感器操作流程和数据处理原理与Arduino平台相似。 在实际应用中,除了基本的传感器读取,还可能涉及到温度补偿、低功耗模式设置、DMP(数字运动处理器)功能的利用等高级特性。DMP可以帮助处理传感器数据,实现更高级的运动估计,减轻主控制器的计算负担。 MPU6050是一个强大的六轴传感器,广泛应用于各种需要实时运动追踪的项目中。通过 Arduino 或 STM32 的库文件,开发者可以轻松地与传感器交互,获取并处理数据,实现各种创新应用。博客和其他开源资源是学习和解决问题的重要途径,通过这些资源,开发者可以获得关于MPU6050的详细信息和实践指南
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值