osg学习-6《显示三维矩阵》
在三维空间显示三维矩阵,需要显示它的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();
}