OSG之矩阵变换节点

298 阅读1分钟

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

1 矩阵变换节点

矩阵变换节点(osg::MatrixTransform)同样继承自 osg::Transform,其主要作用是负责场景中的矩阵变换、矩阵的运算及坐标系的变换。后面要讲的动画更新也是用MatrixTransform来设置移动和旋转。

通过使用矩阵变换节点(osg::MatrixTransform)可以对场景中的模型进行旋转、平移等操作。

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

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

osg::MatrixTransform的常用主要成员函数如下:

void setMatrix(const Matrix& mat) // 设置矩阵

const Matrix& getMatrix()const // 得到矩阵

void preMult(const Matrix &mat) // 递乘,比较类似于++a

a void postMult(const Matrix& mat) // 递乘,比较类似于a++

const Matrix& getlnverseMatrix() const // 得到逆矩阵

2 矩阵变换节点示例

矩阵变换节点(osg::MatrixTransform)示例的代码如程序清单所示。

#include <osgViewer/Viewer>

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

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

#include <osgUtil/Optimizer>

#include "utility.h"


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

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

	// 创建一个节点,读取牛模型
	osg::ref_ptr<osg::Node> node1 = osgDB::readNodeFile(GetCurrentPath() + "\\Data\\cow.osg");

	// 创建矩阵变换节点mt1
	osg::ref_ptr<osg::MatrixTransform> mt1 = new osg::MatrixTransform();
	// 创建一个矩阵
	osg::Matrix m1;
	// 在X方向平移10个单位
	m1.makeTranslate(osg::Vec3(10.0f, 0.0f, 0.0f));
	// 绕X轴旋转45度
	m1.makeRotate(45.0f, 1.0f, 0.0f, 0.0f);
	// 设置矩阵
	mt1->setMatrix(m1);
	mt1->addChild(node1);


	osg::ref_ptr<osg::Node> node2 = osgDB::readNodeFile("E:\\model\\gvv1e7u547-Borderlands 2 - Maya\\Borderlands 2 - Maya\\maya.obj");
	// 创建矩阵变换节点mt2
	osg::ref_ptr<osg::MatrixTransform> mt2 = new osg::MatrixTransform();
	osg::Matrix m2;
	m2.makeTranslate(osg::Vec3(-10.0f, 0.0f, 0.0f));
	mt2->setMatrix(m2);
	mt2->addChild(node2);

	// 添加到场景
	root->addChild(mt1.get());
	root->addChild(mt2.get());


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

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

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

	return 0;
}

运行程序,效果图如下。

2.PNG

动态图

1.gif

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