美文网首页
用CHAI3D做完毕设后的一点整理

用CHAI3D做完毕设后的一点整理

作者: StrongLi27 | 来源:发表于2017-06-09 16:07 被阅读0次
    图片转自360图片

    CHAI3D的学习

    • 一、CHAI3D 的一些介绍

      CHAI3D 是一个C++库,它本身就是一个C++项目,官网里有它详细的英文介绍CHAI3D官网,这里关于它的特点不做赘述。这里只是用直白的语言来帮助刚接触CAHI3D的人更快的了解,CHIA3D项目里面包含了18个模块(就是文件),

      图片来自CHAI3D官网

      每个模块里的包含一些.h和.cpp文件,上面封装了一个个类。最新的3.2.0版本将所有的相关类都放到名为chai3d 的命名域,格式如下:

      using namespace std;
      namespace chai3d {
          cAudioBuffer::cAudioBuffer()
          {
            public:...
          }
      }
      

      CHAI3D还包含了GEL形变模型),BULLET刚体模型),ODE也是刚体模型),OCULUSOculus Rift头戴式显示器)四个第三方模块,也是对CHAI3D基本项目的补充。

      CHAI3D配置非常简单,不用配置环境变量,主要是在新建项目的配置的链接器的附加依赖项里添加chai3d.libOpenGL32.libglu32.libglfw.lib四个静态链接库,并在附加库目录里添加对应的相对路径,如果添加第三方模块,也要添加相应的lib文件。

      当然,你也可以不用新建项目配置,直接在下载的例程上编写就好。

      官方提供的3.2.0版本的CHAI3D文件解压后如下图所示,

      原创 原创

      直接打开sln文件,

      原创

      CAHI3D文件加下有31个例程,GEL文件夹下有三个例程,BULLETOCULUSODE文件夹下有7个例程,每个例程已经提前配置好了,直接可以运行,同时可以通过研究这些例程来学习CHAI3D。在最下面还有一个EXTRA文件夹,里面是窗口管理的第三方库GLFW,窗口管理除了这个,CHAI3D中还有freeglutSDL2

    • 二、利用CAHI3D编写应用的一般结构

      一个CAHI3D程序,一般包括几个模块(模块这个词当然是我说的,只是因为看着高大上而已,实质你明白就是编写几个函数,然后依次放到main函数里),那么首先说必须有的几个函数吧。

      • 其一 初始化glfw库 ,就是调用glfw库(也可以是上面说的其他的库)创建窗口,这个每个例程里都一样,你直接拿过来用就可以了,注意设置一下窗口的一些参数就可以了。

      • 其二 创建虚拟世界,说的好像很高大上, 不懂,来,简单点告诉你,就是实例化几个类指针。在上文所说的18个模块(不懂,往上看)里,有一个World模块,里面封装了一个cWorld类,还有盒子、球、圆柱等基元(就是最基础的)形状模型和网格模型。还有Camera模块Lighting Properties模块,每个虚拟世界里都必须添加至少一个摄像头和一个灯光来渲染场景,当然,摄像头和灯光的有许多属性可以设置,下面只是简单添加:

        // a world that contains all objects of the virtual environment
        cWorld* world;
        // create a new world.
        world = new cWorld(); 
        // create a camera and insert it into the virtual world
        camera = new cCamera(world);
        world->addChild(camera);
        // create a directional light source
        light = new cDirectionalLight(world);
        // insert light source inside world
        world->addChild(light);
        
      • 其三 连接设备,这里,也有一点讲究, 18个模块里有一个Device模块 封装了CAHI3D支持的所有设备的信息,还有一个Handler模块调用Device模块里的信息,接下来有两种方式操作它,一种直接连接设备,输入输出设备信息,另一种是通过一个代理工具(18个模块里有一个Haptic Tools模块),

        // create a haptic device handler
        handler = new cHapticDeviceHandler();
        // get a handle to the first haptic device
        handler->getDevice(hapticDevice, 0);
        //(1)直接连接设备
        // open a connection to haptic device
        hapticDevice->open();
        // calibrate device (if necessary)
        hapticDevice->calibrate();
        //(2)通过tool工具连接,tool类直接内置了直接连接社别的程序
        // a virtual tool representing the haptic device in the scene
        cToolCursor* tool;
        // create a 3D tool and add it to the world
        tool = new cToolCursor(world);
        
      • 其四 创建物体,这一部分,其实可以算作创建虚拟世界里面,但是它又不是必须的, 没有它程序也可以运行,它又是最重要的,因为我们开发的时候就是在这块发挥所有的想象力。下面简单创建一个球体:

        // create a sphere 
        sphere = new cShapeSphere(0.01);
        // insert sphere inside world
        world->addChild(sphere);
        
      • 其五 图像渲染,渲染摄像头看到的场景,先渲染后层,再渲染前层。很多时候,我们也在摄像头上添加一些文本,图像等,然后在这里设置位置大小,这样可以实时动态显示一些值或者图像。

        // update position data
        labelHapticDevicePosition->setText(hapticDevicePosition.str(3));
        // update haptic and graphic rate data
        labelRates->setText(cStr(freqCounterGraphics.getFrequency(), 0) + " Hz / " +
        cStr(freqCounterHaptics.getFrequency(), 0) + " Hz");
        // update position of label
        labelRates->setLocalPos((int)(0.5 * (width - labelRates->getWidth())), 15);
        /////////////////////////////////////////////////////////////////////
        // RENDER SCENE
        /////////////////////////////////////////////////////////////////////
        // update shadow maps (if any)
        world->updateShadowMaps(false, mirroredDisplay);
        // render world
        camera->renderView(width, height);
        // wait until all OpenGL commands are completed
        glFinish();
        // check for any OpenGL errors
        GLenum err;
        err = glGetError();
            if (err != GL_NO_ERROR) cout << "Error:  %s\n" << gluErrorString(err);
        
      • 其六 触觉渲染,这一模块作为子进程,很重要的一部分,这里要与设备进行交互。如果是没有用tools工具的,需要自己写交互程序,反之,这块特别简单,tools工具早已内置了所有的算法和力的碰撞,它会自动计算你在创建物体模块里添加的所有力的属性。函数如下:

        void updateHaptics(void)
        {
            // simulation in now running
            simulationRunning  = true;
            simulationFinished = false;
        
            // main haptic simulation loop
            while(simulationRunning)
            {
                // compute global reference frames for each object
                world->computeGlobalPositions(true);
        
                // update position and orientation of tool
                tool->updateFromDevice();
        
                // compute interaction forces
                tool->computeInteractionForces();
        
                // send forces to haptic device
                tool->applyToDevice();
        
                // signal frequency counter
                freqCounterHaptics.signal(1);
            }
            
            // exit haptics thread
            simulationFinished = true;
        }
        
      • 其七 添加进程 ,当编写完图像渲染模块和触觉渲染模块后,需要把他们两个组合到一块,这里有一个System模块里的cThread类,将触觉触觉渲染模块添加到子进程,然后在一个循环里添加图像渲染模块,函数如下:

        // create a thread which starts the main haptics rendering loop
        hapticsThread = new cThread();
        hapticsThread->start(updateHaptics, CTHREAD_PRIORITY_HAPTICS);
        // setup callback when application exits
        atexit(close);
        //--------------------------------------------------------------------------
        // MAIN GRAPHIC LOOP
        //--------------------------------------------------------------------------
        // call window size callback at initialization
        windowSizeCallback(window, width, height);
        // main graphic loop
        while (!glfwWindowShouldClose(window))
        {
             // get width and height of window
             glfwGetWindowSize(window, &width, &height);
             // render graphics
             updateGraphics();
             // swap buffers
             glfwSwapBuffers(window);
             // process events
             glfwPollEvents();
             // signal frequency counter
             freqCounterGraphics.signal(1);
        }
        // close window
        glfwDestroyWindow(window);
        // terminate GLFW library
        glfwTerminate();
        
      • 其八 中断函数,基于GLFW的包括按键中断,鼠标中断,这个都是辅助功能,例程中都有模板,你可以直接在程序里面添加你想实现的功能,不多做介绍(懒得写了)。

      最后,把这些模块放到main函数里面就可以了,一个CHAI3D程序就写好了,看着多,其实大部分都是模板上的,如果想自己实现又高又大又上的功能,那得在模板之外自己再琢磨琢磨,CHAI3D提供的各种类,各种功能函数已经足够多,老实说那些例程真的只是用了很少一部分,骚年们(我也是)想要真正学好学精,个人感觉要除了精通例程,还要举一反三,多转几下定义,开动小脑筋,一直添加功能(与君共勉)。

    • 三、自定义类,实现多个界面转换

      这个是我的毕设就是这么搞的,太烦了,不想写了,等下次想写的时候再说吧

    相关文章

      网友评论

          本文标题:用CHAI3D做完毕设后的一点整理

          本文链接:https://www.haomeiwen.com/subject/sveofxtx.html