OSG之自动对齐节点

467 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 21 天

1 自动对齐节点

自动对齐节点(osg::AutoTransform)也继承自osg::Transform,它的主要作用是使节点自动对齐于摄像机或者屏幕。在实际应用中,通常可以用来显示一些不变化的文字或者其他的标识。

osg::AutoTransform 有如下3种对齐模式:

enum AutoRotateMode

{

NO_ROTATION, // 无旋转

ROTATE_TO_SCREEN, // 自动朝向屏幕

ROTATE_TO_CAMERA //自动朝向相机

}

osg::AutoTransform的继承关系图如下所示。

osg::Referenced <-- osg::Object <-- osg::Node <-- osg::Group <-- osg::Transform <-- osg::AutoTransofrm

2 自动对齐节点示例

自动对齐节点(osg::AutoTransform)的示例代码如程序清单所示(这里用到了文字的显示,后面还有详细的讲解)。

#include <osgViewer/Viewer>

#include <osg/Node>
#include <osg/Geode>
#include <osg/Group>
#include <osg/AutoTransform>

#include <osgText/Text>

#include <osgDB/ReadFile>
#include <osgDB/WriteFile>

#include <osgUtil/Optimizer>

#include "utility.h"


osg::ref_ptr<osg::Node> createAutoTransform(osg::Vec3& position, float size, std::string& label,
	osg::AutoTransform::AutoRotateMode autoMode, osgText::Text::AxisAlignment axisAlignment)
{
	osg::ref_ptr<osg::Geode> geode = new osg::Geode();

	// 字体
	std::string font(GetCurrentPath() + "\\Data\\font\\cour.ttf");

	// 创建Text对象
	osg::ref_ptr<osgText::Text> text = new osgText::Text;
	geode->addDrawable(text);

	// 设置字体
	text->setFont(font);
	// 设置字体分辨率,默认为32*32
	text->setFontResolution(128.0f, 128.0f);
	// 设置字体大小
	text->setCharacterSize(size);
	// 设置对齐方式
	text->setAlignment(osgText::Text::CENTER_CENTER);
	// 设置方向
	text->setAxisAlignment(axisAlignment);
	// 设置文字
	text->setText(label);

	// 关闭光照
	geode->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF);

	// 创建自动变换节点
	osg::ref_ptr<osg::AutoTransform> at = new osg::AutoTransform();
	// 添加子节点
	at->addChild(geode.get());
	// 设置自动变换方式
	at->setAutoRotateMode(autoMode);
	// 根据屏幕大小来缩放节点,默认为false,设置为true时,节点无法缩放
	at->setAutoScaleToScreen(false);
	// at->setAutoScaleToScreen(true);
	// 设置缩放最大最小比率
	at->setMaximumScale(5.0f);
	at->setMinimumScale(0.0f);
	// 设置位置
	at->setPosition(position);
	return at.get();
}

int main()
{
	// 创建Viewer对象,场景浏览器
	osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer();

	// 创建场景组根节点
	osg::ref_ptr<osg::Group> root = new osg::Group();

	std::string text("Fly To Sky");
	
	/**
	3 种变换模式
	ROTATE_TO_SCREEN	自动朝向屏幕
	ROTATE_TO_CAMERA	自动朝向相机
	NO_ROTATION			无
	**/

	//// 添加ROTATE_TO_SCREEN模式变换节点
	//root->addChild(createAutoTransform(osg::Vec3(0.0f, 0.0f, 0.0f), 60.0F, text,
	//	osg::AutoTransform::ROTATE_TO_SCREEN, osgText::Text::XY_PLANE));

	//// 添加NO_ROATTION模式变换节点
	//root->addChild(createAutoTransform(osg::Vec3(0.0f, 0.0f, 0.0f), 60.0F, text,
	//	osg::AutoTransform::NO_ROTATION, osgText::Text::YZ_PLANE));

	// 添加ROTATE_TO_CAMERA模式变换节点
	root->addChild(createAutoTransform(osg::Vec3(0.0f, 0.0f, 0.0f), 60.0F, text,
		osg::AutoTransform::ROTATE_TO_CAMERA, osgText::Text::XY_PLANE));

	// 优化场景数据
	osgUtil::Optimizer optimizer;
	optimizer.optimize(root.get());

	// 设置窗口大小
	setWindowSize(viewer.get(), 600, 400, "AutoTransform");

	// 设置场景数据
	viewer->setSceneData(root.get());
	// 初始化并创建窗口
	viewer->realize();
	// 开始渲染
	viewer->run();

	return 0;
}

运行程序,截图如下所示。

1.PNG

动态效果图

1.gif

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 21 天