写在前面的话:目前学习碰撞检测的所有代码,供小白使用!
#include <osgViewer/Viewer>
#include <osgDb/ReadFile>
#include <osgGA/GUIEventAdapter>
#include <osgViewer/ViewerEventHandlers>
#include <osgGA/TrackballManipulator>
#include <osg/Geode>
#include <osg/ShapeDrawable>
#include <osg/Material>
#include <osg/StateSet>
#include <osg/Texture2D>
#include <osg/Image>
#include <osg/LineWidth>
#include <osgUtil/IntersectionVisitor>
#include <iostream>
// 画正方体
osg::ref_ptr<osg::Geode> CreatBox()
{
osg::ref_ptr<osg::Geode> geode = new osg::Geode;
geode->addDrawable(new osg::ShapeDrawable(new osg::Box(osg::Vec3(0, 0, 0), 10.0, 10.0, 10.0)));
//geode->addDrawable(new osg::ShapeDrawable(new osg::Box(osg::Vec3(0, 0, 0), 0.1, 0.1, 20)));
return geode;
}
// 画线
osg::ref_ptr<osg::Geode> CreateLine(const osg::Vec3 &start, const osg::Vec3 &end)
{
osg::ref_ptr<osg::Geode> geode = new osg::Geode;
osg::ref_ptr<osg::Geometry> gy = new osg::Geometry;
osg::ref_ptr<osg::Vec3Array> coords = new osg::Vec3Array;
// ===========================================================================
geode->addDrawable(gy);
gy->setVertexArray(coords);
coords->push_back(start);
coords->push_back(end);
gy->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::LINE_LOOP, 0, 2));
// ============================================================================
return geode;
}
// 画球
osg::ref_ptr<osg::Geode> CreateSphere(osg::Vec3d center)
{
osg::ref_ptr<osg::Geode> geode = new osg::Geode;
geode->addDrawable(new osg::ShapeDrawable(new osg::Sphere(center, 0.5)));
return geode;
}
int main()
{
osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer;
osg::ref_ptr<osg::Group> group = new osg::Group;
osg::Vec3 start = osg::Vec3(-10, 7, 15);
osg::Vec3 end = osg::Vec3(5, -4, -12);
viewer->addEventHandler(new osgViewer::StatsHandler);
viewer->addEventHandler(new osgViewer::WindowSizeHandler); // 窗口尺寸
// 碰撞检测
osgUtil::LineSegmentIntersector::Intersections intersections;
osg::ref_ptr<osgUtil::LineSegmentIntersector> ls = new osgUtil::LineSegmentIntersector(start, end);
osg::ref_ptr<osgUtil::IntersectionVisitor> iv = new osgUtil::IntersectionVisitor(ls);
osg::ref_ptr<osg::Geode> node = CreatBox();
group->addChild(node);
node->accept(*iv.get());
group->addChild(CreateLine(start, end));
// 如果有碰撞,则输出所有交点
if (ls->containsIntersections())
{
intersections = ls->getIntersections();
for (osgUtil::LineSegmentIntersector::Intersections::iterator iter = intersections.begin(); iter != intersections.end(); iter++)
{
std::cout << iter->getWorldIntersectPoint().x() << " " << iter->getWorldIntersectPoint().y() << " " << iter->getWorldIntersectPoint().z() << std::endl;
group->addChild(CreateSphere(iter->getWorldIntersectPoint()));
}
}
viewer->setSceneData(group);
return viewer->run();
}