OSG 根据两点坐标绘制圆柱
前言:在绘制脑节点和节点间关系时,需要根据两点坐标绘制圆柱。本文暂时介绍简单的绘制方式,如有需求,读者可以自行添加回调。
思想:
- 首先绘制两个球,得到球心!
- 根据球心坐标aVec和bVec,通过(aVec+bVec)/2 得到柱心,通过(aVec+bVec).length() 得到长度,绘制出在坐标(0,0,0)点的圆柱。
- 设置旋转和平移矩阵,先旋转,后平移,得到最终圆柱。
代码:
/************************************************************************/
/* Author: Lcy
/* Mail: 164917669@qq.com
/* Bolg: http://blog.csdn.net/MissXy_
/* Describe: 根据两点坐标绘制圆柱
/* Date: 2018-4-9
/************************************************************************/
#include <osgViewer/Viewer>
#include <osg/Node>
#include <osg/Geode>
#include <osg/Group>
#include <osg/BlendColor>
#include <osg/BlendFunc>
#include <osg/ShapeDrawable>
#include <osg/MatrixTransform>
#include <osg/NodeCallback>
#include <osgDB/ReadFile>
#include <osgDB/WriteFile>
#include <osgUtil/Optimizer>
#include <osgViewer/ViewerEventHandlers>
#include <osgGA/TrackballManipulator>
#include <osgGA/StateSetManipulator>
/**
* 创建一个脑节点:节点信息
*/
osg::ref_ptr<osg::ShapeDrawable> createOneBNode(const osg::Vec3& center, float size)
{
osg::ref_ptr<osg::ShapeDrawable> oneShape = new osg::ShapeDrawable();
osg::ref_ptr<osg::TessellationHints> hints = new osg::TessellationHints();
hints->setDetailRatio(1.0f);
oneShape = new osg::ShapeDrawable(new osg::Sphere(center, size), hints.get());
oneShape->setColor(osg::Vec4(65.0/255,105.0/255,225.0/255, 1.0));
return oneShape.release();
}
/**
* 创建一个边信息
*/
osg::ref_ptr<osg::MatrixTransform> createCylinder(const osg::Vec3 &from, const osg::Vec3 &to, float radius)
{
osg::ref_ptr<osg::Geode> geode = new osg::Geode();
osg::ref_ptr<osg::MatrixTransform> mt = new osg::MatrixTransform();
osg::ref_ptr<osg::ShapeDrawable> cylinder = new osg::ShapeDrawable();
osg::ref_ptr<osg::TessellationHints> hints = new osg::TessellationHints();
hints->setDetailRatio(0.8f);
osg::Vec3 cylCenter = (to + from)/2; //得到柱心
float height = (to - from).length(); //得到长度
cylinder = new osg::ShapeDrawable(new osg::Cylinder(osg::Vec3(0.0, 0.0, 0.0), radius, height),hints.get());
cylinder->setColor(osg::Vec4(255.0/255, 228.0/255, 181.0/255, 1.0f)); //鹿皮鞋色
geode->addDrawable(cylinder.get());
osg::Matrix mRotate, mTrans;
mRotate.makeRotate(osg::Vec3f(0.0f, 0.0f, 1.0f), to - from);
mTrans.makeTranslate(cylCenter);
mt->setMatrix(mRotate*mTrans);
mt->addChild(geode.get());
return mt.get();
}
int main()
{
osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer();
viewer->setUpViewInWindow(100, 100, 1080, 960);
viewer->addEventHandler(new osgViewer::StatsHandler());
viewer->setCameraManipulator(new osgGA::TrackballManipulator());
osg::ref_ptr<osg::Group> root = new osg::Group();
osg::ref_ptr<osg::Group> group = new osg::Group();
osg::ref_ptr<osg::Geode> geode = new osg::Geode();
osg::Vec3 aVec(osg::Vec3(0.0f, 0.0f, 0.0f));
osg::Vec3 bVec(osg::Vec3(10.0f, 0.0f, 0.0f));
geode->addDrawable(createOneBNode(aVec, 2.f));
geode->addDrawable(createOneBNode(bVec, 2.f));
osg::ref_ptr<osg::MatrixTransform> mt = createCylinder(aVec, bVec, 0.5f);
group->addChild(mt.get());
root->addChild(geode.get());
root->addChild(group.get());
viewer->setSceneData(root.get());
viewer->realize();
viewer->run();
return 0;
}
效果截图: