本文通过上节的人机交互形式获取模型拍照区域,采用添加Slave相机的形式实现框选区域拍照出图。
目录
- 添加Slave相机,框选区域拍照出图
内容
在上期的RegionSelect中,将SlaveCamera初始化并添加到视图(viewer)中,在交互动作的最后,根据绘制的多边形调整SalveCamera的姿态,最后添加相机回调用于保存拍照后的纹理。
- 1 SalveCamera 初始化
RegionSelect(osgViewer::Viewer* viewer, osgEarth::MapNode* mapNode)
{
....
....
....
_slaveCamera = new osg::Camera;
{
_slaveCamera->setReferenceFrame(osg::Camera::ABSOLUTE_RF);
_slaveCamera->setClearColor(osg::Vec4d(0, 0, 0, 0));
_slaveCamera->setComputeNearFarMode(osg::Camera::DO_NOT_COMPUTE_NEAR_FAR);
_slaveCamera->setClearMask(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
_slaveCamera->setRenderOrder(osg::Camera::PRE_RENDER);
_slaveCamera->setRenderTargetImplementation(osg::Camera::FRAME_BUFFER_OBJECT);
//_imageGeneratorCamera->setImplicitBufferAttachmentMask(0, 0);
_slaveCamera->dirtyAttachmentMap();
_slaveCamera->attach(osg::Camera::COLOR_BUFFER0, _image.get());
_slaveCamera->setSmallFeatureCullingPixelSize(-1.0f);
_slaveCamera->setCullMask(~0u);
double distance = 10;
// set up a StateSet for the RTT camera.
osg::StateSet* rttStateSet = _slaveCamera->getOrCreateStateSet();
//rttStateSet->setAttributeAndModes(new osg::CullFace(osg::CullFace::BACK), osg::StateAttribute::ON | osg::StateAttribute::PROTECTED);
osg::StateAttribute::OverrideValue forceOff =
osg::StateAttribute::OFF | osg::StateAttribute::PROTECTED | osg::StateAttribute::OVERRIDE;
rttStateSet->setMode(GL_DEPTH_TEST, osg::StateAttribute::ON | osg::StateAttribute::PROTECTED | osg::StateAttribute::OVERRIDE);
rttStateSet->setRenderBinDetails(1003, "DepthSortedBin", osg::StateSet::OVERRIDE_RENDERBIN_DETAILS);
//rttStateSet->setAttribute(new osg::Depth(osg::Depth::LEQUAL), osg::StateAttribute::ON | osg::StateAttribute::PROTECTED | osg::StateAttribute::OVERRIDE);
//rttStateSet->setRenderBinDetails(10, "DepthSortedBin", osg::StateSet::OVERRIDE_RENDERBIN_DETAILS);
//rttStateSet->setMode(GL_DEPTH_TEST, osg::StateAttribute::OFF);//关闭深度测试
rttStateSet->setDefine(OE_LIGHTING_DEFINE, forceOff);
//rttStateSet->addUniform( Registry::shaderFactory()->createUniformForGLMode(GL_LIGHTING, forceOff) );
rttStateSet->setMode(GL_LIGHTING, forceOff);
}
_slaveCamera->setViewport(0, 0, _width, _height);
viewer->addSlave(_slaveCamera);
}
- 2 修改SlaveCamera姿态
为了方便多边形框选工具的管理,可添加一个监视器实现多边形框选工具的装载与卸载。具体代码如下:
virtual void endhandle()
{
if (_feature->getGeometry()->size() < 3)
{
_feature->getGeometry()->clear();
_worldPts.clear();
_featureNode->dirty();
return;
}
osg::ref_ptr<osg::Image> image;
osg::Matrix world2TexMatrix;
//orthoImageGenerator->RenderToImage(_worldPts, 0.1, image, world2TexMatrix);
//osgDB::writeImageFile(*image, "C:/Users/CaiPing/Desktop/实体生成/test.jpg");
{
std::vector<osg::Vec3d> points;
osg::ref_ptr<osgEarth::Polygon> polygon = (osgEarth::Polygon*)_feature->getGeometry();
osg::Vec3d centerPoint;
for (int i = 0; i < polygon->size(); i++)
{
points.push_back(polygon->at(i));
centerPoint += (polygon->at(i) / polygon->size());
}
osg::Plane localPlane;
PlaneFit(points, localPlane);
double distance = 10;
osg::Vec3d localNormal = osg::Vec3d(localPlane.asVec4()[0], localPlane.asVec4()[1], localPlane.asVec4()[2]);
osg::Matrix toLocalPlaneMatrix = osg::Matrixd::translate(-points[0]) * osg::Matrix::rotate(localNormal, osg::Vec3d(0, 0, 1));
osg::Vec3d localNorth = osg::Vec3d(0, 1, 0) * osg::Matrix::rotate(osg::Vec3d(0, 0, 1), localNormal);
_slaveCamera->setViewMatrixAsLookAt(centerPoint + localNormal * distance, centerPoint, localNorth);
osg::BoundingBox localBox;
for (int i = 0; i < points.size(); i++)
{
osg::Vec3d tempPoint = points[i] * toLocalPlaneMatrix;
localBox.expandBy(tempPoint);
}
_slaveCamera->setProjectionMatrixAsOrtho(localBox.xMin(), localBox.xMax(), localBox.yMin(), localBox.yMax(), 1, 200); //投影矩阵视图范围
//_imageGeneratorCamera->setProjectionMatrixAsPerspective(45, 1.0*outImageWidth/ outImageHeight, 0, 500);
_world2TexMatrix = _slaveCamera->getViewMatrix() * _slaveCamera->getProjectionMatrix();
_slaveCamera->setPreDrawCallback(new Callback(this));
}
- 3 相机回调保存纹理
class Callback : public osg::Camera::DrawCallback
{
public:
Callback(RegionSelect* regionSelect)
{
_regionSelect = regionSelect;
}
virtual void operator () (osg::RenderInfo& renderInfo) const
{
_regionSelect->writeOut();
}
protected:
RegionSelect* _regionSelect;
};