ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

osg学习-6《显示三维矩阵》

2022-08-21 10:37:15  阅读:144  来源: 互联网

标签:ni color 矩阵 三维 back push quad osg


在三维空间显示三维矩阵,需要显示它的6个外表面。假设xyz三个方向的维数是ni,nj,nk,三个方向的顶点维数是ni+1,nj+1, nk+1。在每个面上分别绘制各自的四边形。每个四边形的颜色根据矩阵的值获取,这个例子采用了离散的数值。使用了之前创建的颜色模板类。

 

void DrawShape::drawDisModel3D(const IModel3D<int>& disM, float dx = 1.0, float dy = 1.0, float dz = 1.0)
{
    // 创建一个节点对象
        osg::ref_ptr<osg::Geode> geode = new osg::Geode();
    //创建一个集合对象
    osg::ref_ptr<osg::Geometry> geom = new osg::Geometry();

    int nk = disM.nk();
    int nj = disM.nj();
    int ni = disM.ni();

    
    //创建顶点数组
    osg::ref_ptr<osg::Vec3Array> vertx = new osg::Vec3Array();
    for (int k = 0; k <= nk; k++) {
        for (int j = 0; j <= nj; j++) {
            for (int i = 0; i <= ni; i++) {
                vertx->push_back(osg::Vec3(i * dx, j * dy, k * dz));
            }
        }
    }

    int vmin = INT32_MAX;
    int vmax = -vmin;
    disM.getMinMax(vmin, vmax);
    std::cout << "vmin: " << vmin << " vmax: " << vmax << std::endl;
    //_colors = ColorTemplate<float>("rainbow");
    _colors = ColorTemplate<float>();

    //设置顶点数据
    geom->setVertexArray(vertx.get());
    //创建颜色数组
    osg::ref_ptr<osg::Vec4Array> vcolor = new osg::Vec4Array();

    progressbar pbar(ni * nj * 2 + ni * nk * 2 + nj * nk * 2);
    int seq = 0;
    int k = 0;
    for (int j = 0; j < nj; j++) {
        for (int i = 0; i < ni; i++) {
            int index = k * (nj+1)*(ni+1) +  j * (ni + 1) + i;
            //创建四边形定点数组,指定绘图基元为四边形,注意添加顺序
            osg::ref_ptr<osg::DrawElementsUInt> quad =
                new osg::DrawElementsUInt(osg::PrimitiveSet::QUADS, 0);
            quad->push_back(index);
            quad->push_back(index + ni + 1);
            quad->push_back(index + ni + 2);
            quad->push_back(index + 1);
            //添加到几何体
            geom->addPrimitiveSet(quad.get());
            auto color = _colors.getColor(disM.getValue(j, i,k));
            vcolor->push_back(Vec4f(color.r, color.g, color.b, color.alpha));  //random color
            seq++;
            if (seq % 1000 == 0) {
                pbar.progress = seq;
                pbar.update();
            }
        }
       
    }
    k = nk-1;
    for (int j = 0; j < nj; j++) {
        for (int i = 0; i < ni; i++) {
            int index = k * (nj+1) * (ni+1) + j * (ni + 1) + i;
            //创建四边形定点数组,指定绘图基元为四边形,注意添加顺序
            osg::ref_ptr<osg::DrawElementsUInt> quad =
                new osg::DrawElementsUInt(osg::PrimitiveSet::QUADS, 0);
            quad->push_back(index);
            quad->push_back(index + 1);
            quad->push_back(index + ni + 2);
            quad->push_back(index + ni + 1);
            //添加到几何体
            geom->addPrimitiveSet(quad.get());
            auto color = _colors.getColor(disM.getValue(j, i, k));
            vcolor->push_back(Vec4f(color.r, color.g, color.b, color.alpha));  //random color
            seq++;
            if (seq % 1000 == 0) {
                pbar.progress = seq;
                pbar.update();
            }
        }
    }
    int i = 0;
    for (int j = 0; j < nj; j++) {
        for (int k = 0; k < nk; k++) {
            int index = k * (nj+1) * (ni+1) + j * (ni + 1) + i;
            //创建四边形定点数组,指定绘图基元为四边形,注意添加顺序
            osg::ref_ptr<osg::DrawElementsUInt> quad =
                new osg::DrawElementsUInt(osg::PrimitiveSet::QUADS, 0);
            quad->push_back(index);
            quad->push_back(index + (nj + 1) * (ni + 1) + 0);
            quad->push_back(index + (nj + 1) * (ni + 1) + ni + 1);
            quad->push_back(index + ni + 1);
            
            
            //添加到几何体
            geom->addPrimitiveSet(quad.get());
            auto color = _colors.getColor(disM.getValue(j, i, k));
            vcolor->push_back(Vec4f(color.r, color.g, color.b, color.alpha));  //random color
            seq++;
            if (seq % 1000 == 0) {
                pbar.progress = seq;
                pbar.update();
            }
        }
    }
    i = ni-1;
    for (int j = 0; j < nj; j++) {
        for (int k = 0; k < nk; k++) {
            int index = k * (nj + 1) * (ni + 1) + j * (ni + 1) + i;
            //创建四边形定点数组,指定绘图基元为四边形,注意添加顺序
            osg::ref_ptr<osg::DrawElementsUInt> quad =
                new osg::DrawElementsUInt(osg::PrimitiveSet::QUADS, 0);
            quad->push_back(index);
            quad->push_back(index + ni + 1);
            quad->push_back(index + (nj + 1) * (ni + 1) + ni + 1);
            quad->push_back(index + (nj + 1) * (ni + 1) + 0);
            //添加到几何体
            geom->addPrimitiveSet(quad.get());
            auto color = _colors.getColor(disM.getValue(j, i, k));
            vcolor->push_back(Vec4f(color.r, color.g, color.b, color.alpha));  //random color
            seq++;
            if (seq % 1000 == 0) {
                pbar.progress = seq;
                pbar.update();
            }
        }
    }
    int j = 0;
    for (int i = 0; i < ni; i++) {
        for (int k = 0; k < nk; k++) {
            int index = k * (nj + 1) * (ni + 1) + j * (ni + 1) + i;
            //创建四边形定点数组,指定绘图基元为四边形,注意添加顺序
            osg::ref_ptr<osg::DrawElementsUInt> quad =
                new osg::DrawElementsUInt(osg::PrimitiveSet::QUADS, 0);
            quad->push_back(index);
            quad->push_back(index + 1);
            quad->push_back(index + (nj + 1) * (ni + 1) + 1);
            quad->push_back(index + (nj + 1) * (ni + 1) + 0);
            //添加到几何体
            geom->addPrimitiveSet(quad.get());
            auto color = _colors.getColor(disM.getValue(j, i, k));
            vcolor->push_back(Vec4f(color.r, color.g, color.b, color.alpha));  //random color
            seq++;
            if (seq % 1000 == 0) {
                pbar.progress = seq;
                pbar.update();
            }
        }
    }
    j = nj-1;
    for (int i = 0; i < ni; i++) {
        for (int k = 0; k < nk; k++) {
            int index = k * (nj + 1) * (ni + 1) + j * (ni + 1) + i;
            //创建四边形定点数组,指定绘图基元为四边形,注意添加顺序
            osg::ref_ptr<osg::DrawElementsUInt> quad =
                new osg::DrawElementsUInt(osg::PrimitiveSet::QUADS, 0);
            quad->push_back(index);
            quad->push_back(index + (nj + 1) * (ni + 1) + 0);
            quad->push_back(index + (nj + 1) * (ni + 1) + 1);
            quad->push_back(index + 1);
                       
            //添加到几何体
            geom->addPrimitiveSet(quad.get());
            auto color = _colors.getColor(disM.getValue(j, i, k));
            vcolor->push_back(Vec4f(color.r, color.g, color.b, color.alpha));  //random color
            seq++;
            if (seq % 1000 == 0) {
                pbar.progress = seq;
                pbar.update();
            }
        }
    }

    //设置颜色数组
    geom->setColorArray(vcolor.get());

    //设置颜色的绑定方式为单个顶点
    //geom->setColorBinding(osg::Geometry::BIND_PER_VERTEX);
    geom->setColorBinding(osg::Geometry::BIND_PER_PRIMITIVE_SET);

    // 创建法线数组
    osg::ref_ptr<osg::Vec3Array>nc = new osg::Vec3Array();

    //添加法线
    nc->push_back(osg::Vec3(0.0f, -1.0f, 0.0f));
    nc->push_back(osg::Vec3(0.0f, 1.0f, 0.0f));
    nc->push_back(osg::Vec3(0.0f, 0.0f, 1.0f));
    nc->push_back(osg::Vec3(0.0f, 0.0f, -1.0f));
    nc->push_back(osg::Vec3(1.0f, 0.0f, 0.0f));
    nc->push_back(osg::Vec3(-1.0f, 0.0f, 0.0f));

    // 设置法线数组
    geom->setNormalArray(nc.get());
    //设置法线的绑定方式为全部顶点
    geom->setNormalBinding(osg::Geometry::BIND_OVERALL);

    //添加到叶节点
    geode->addDrawable(geom.get());


    osg::ref_ptr < osg::MatrixTransform> scale = new osg::MatrixTransform;
    //scale->setMatrix(osg::Matrix::scale(0.5, 0.5, 0.5) * osg::Matrix::translate(0, 0, -2));
    scale->setMatrix(osg::Matrix::scale(1, 1, 1));

    makeCoordinate(-10, -10, -10, 10,10,10,5);
    _root->addChild(geode);
    _root->addChild(scale);

    _viewer->run();
}

 

标签:ni,color,矩阵,三维,back,push,quad,osg
来源: https://www.cnblogs.com/oliver2022/p/16609416.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有