当前位置: 首页 > article >正文

五、OSG学习笔记-矩阵变换

前一章节:

四、OSG学习笔记-基础图元-CSDN博客

一、矩阵变换的三种方式

二、

示例代码:

#include<windows.h>
#include<osg/Node>
#include<osgViewer/Viewer>
#include<osgViewer/ViewerEventHandlers>
#include<osgDB/ReadFile>
#include<osgGA/TrackballManipulator>

// 图元库
#include<osg/Geode>
#include<osg/ShapeDrawable>

#include<osg/MatrixTransform>

// 回调
#include<osg/AnimationPath>

osg::ref_ptr<osg::Node> MatrixOperation()
{
    osg::ref_ptr<osg::Group> pGroup = new osg::Group;
    osg::ref_ptr<osg::MatrixTransform> pMax = new osg::MatrixTransform;
    osg::ref_ptr<osg::MatrixTransform> pMax1 = new osg::MatrixTransform;
    osg::ref_ptr<osg::MatrixTransform> pMax2 = new osg::MatrixTransform;
    osg::ref_ptr<osg::MatrixTransform> pMax3 = new osg::MatrixTransform;
    osg::ref_ptr<osg::Node> pNode = osgDB::readNodeFile("glider.osg");

    // 将模型中图元X轴平移 5 这个点
    pMax1->addChild(pNode.get());
    pMax1->setMatrix(osg::Matrix::translate(5.0, 0.0, 0.0));
    //围绕中心点osg::Vec3(5.0, 0.0, 0.0)旋转,绕着z轴
    pMax->setUpdateCallback(new osg::AnimationPathCallback(osg::Vec3(5.0, 0.0, 0.0), osg::Z_AXIS, 1.0));
    pMax->addChild(pMax1.get());


    // 将模型中图元X轴平移 -5 这个点
    pMax2->addChild(pNode.get());
    pMax2->setMatrix(osg::Matrix::translate(-5.0, 0.0, 0.0));
    //围绕中心点osg::Vec3(-5.0, 0.0, 0.0)旋转,绕着z轴
    pMax3->setUpdateCallback(new osg::AnimationPathCallback(osg::Vec3(-5.0, 0.0, 0.0), osg::Z_AXIS, 1.0));
    pMax3->addChild(pMax2.get());

    pGroup->addChild(pNode.get());
    pGroup->addChild(pMax.get());
    pGroup->addChild(pMax3.get());
    return pGroup;
}

int main()
{
    osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer;
    viewer->setUpViewInWindow(100, 100, 1500, 1000);

    viewer->setSceneData(MatrixOperation().get());
    return viewer->run();
}

代码运行效果:

三、矩阵变换节点

写模型代码实例:

// output A Node
void ExportANode()
{
    osg::ref_ptr<osg::Node> node = osgDB::readNodeFile("cow.osg");
    osg::ref_ptr<osg::MatrixTransform> max = new osg::MatrixTransform;
    max->addChild(node.get());
    max->setMatrix(osg::Matrix::translate(50.0, 0.0, 0.0));

    // 写模型
    osgDB::ReaderWriter::WriteResult result = osgDB::Registry::instance()->writeNode(*max.get(), 
"TrCow.osg",
 osgDB::Registry::instance()->getOptions());

    if (result.success())
    {
        osg::notify(osg::NOTICE) << "Write Node Success" << std::endl;
    }
}

这里偏移,可以通过 osg::PositionAttitudeTransform恢复,代码如下:

osg::ref_ptr<osg::PositionAttitudeTransform> pat = new osg::PositionAttitudeTransform;

    osg::ref_ptr<osg::Group> group = new osg::Group;
    group->addChild(osgDB::readNodeFile("glider.osg"));
    pat->addChild(osgDB::readNodeFile("TrCow.osg"));// 这里x正方向偏移了五十
    pat->setPosition(osg::Vec3d(-50.0, 0.0, 0.0));
    group->addChild(pat.get());

下面一个矩阵变换类的实例,实现上述流程图中内容:

代码:OsgStudy/NodeMatrix · CuiQingCheng/OsgStudy - 码云 - 开源中国

NodeMatrix.h

#pragma once
#include<windows.h>
#include<osg/Node>
#include<osgViewer/Viewer>
#include<osgViewer/ViewerEventHandlers>
#include<osgDB/ReadFile>
#include<osgGA/TrackballManipulator>

// 图元库
#include<osg/Geode>
#include<osg/ShapeDrawable>

#include<osg/Matrix>
#include<osg/MatrixTransform>
#include<osg/PositionAttitudeTransform>

// 回调
#include<osg/AnimationPath>

class NodeMatrix : public osg::MatrixTransform
{
public:
	NodeMatrix(void);
	~NodeMatrix(void);

public:
	/**设置当前模型的旋转方式**/
	void  rotating(const osg::Vec3d& pivot, const osg::Vec3d& axis, float angularVelocity);

	/**旋转模型**/
	void toRotate(const osg::Matrix& mat);
	/**旋转模型**/
	void toRotate(float angle, const osg::Vec3f& axis);

	/**缩放模型**/
	void toScale(const osg::Matrix& mat);

	/**缩放模型**/
	void toScale(float& lel);

	/**addsChild方法**/
	void addsChild(osg::Node* node);

	/**将模型移动到目的点**/
	void toPosition(const osg::Vec3d& pos);

	/**限制模型大小**/
	void adapt(osg::BoundingSphere& sps);

	/**限制模型大小**/
	void adapt(osg::Node* node);
private:
	osg::ref_ptr<osg::MatrixTransform> m_pat{nullptr};
	osg::BoundingSphere m_ps;	// 包围盒
	osg::Node* m_pNode{ nullptr };
	float m_level{ 1.0 };
};

NodeMatrix.cpp

#include "NodeMatrix.h"


NodeMatrix::NodeMatrix(void) {
	m_pat = new osg::MatrixTransform;
	addChild(m_pat);
}

NodeMatrix::~NodeMatrix(void)
{
}

/**设置当前模型的旋转方式 float angularVelocity弧度 **/
void NodeMatrix::rotating(const osg::Vec3d& pivot, const osg::Vec3d& axis, float angularVelocity)
{
	setUpdateCallback(new osg::AnimationPathCallback(pivot, axis, angularVelocity));
}

/**旋转模型**/
void NodeMatrix::toRotate(const osg::Matrix& mat)
{
	m_pat->setMatrix(mat);
}

/**旋转模型**/
void NodeMatrix::toRotate(float angle, const osg::Vec3f& axis)
{
	m_pat->setMatrix(osg::Matrix::rotate(angle, axis));
}

/**缩放模型**/
void NodeMatrix::toScale(const osg::Matrix& mat)
{
	m_pat->setMatrix(mat);
}

/**缩放模型**/
void NodeMatrix::toScale(float& lel)
{
	m_pat->setMatrix(osg::Matrix::scale(lel, lel, lel));
}

void NodeMatrix::addsChild(osg::Node* node)
{
	m_pat->addChild(node);
	m_pNode = node;
	m_ps = node->getBound();
	osg::notify(osg::NOTICE) << m_ps.center().x() << "  " << m_ps.center().y() << "  " << m_ps.center().z() << std::endl;
}

/**将模型移动到目的点**/
void NodeMatrix::toPosition(const osg::Vec3d& pos)
{
	// 将模型移动到原点,在移动到指定点 pos
	osg::Vec3d cps;
	cps.set(-m_ps.center().x() * m_level, -m_ps.center().y() * m_level, -m_ps.center().z() * m_level);
	m_pat->setMatrix(osg::Matrix::translate(cps) * osg::Matrix::translate(pos));
}

/**限制模型大小, 由包围盒决定**/
void NodeMatrix::adapt(osg::BoundingSphere& sps)
{
	m_level = sps.radius() / m_ps.radius();
	m_pat->setMatrix(osg::Matrix::scale(m_level, m_level, m_level));
}

/**限制模型大小, 由参考模型决定**/
void NodeMatrix::adapt(osg::Node* node)
{
	osg::BoundingSphere sps = node->getBound();
	m_level = sps.radius() / m_ps.radius();
	m_pat->setMatrix(osg::Matrix::scale(m_level, m_level, m_level));
}

main.cpp

#include "NodeMatrix.h"

int main()
{
	osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer;
	viewer->setUpViewInWindow(100, 100, 1500, 1000);
	
	// NodeMatrix 这个派生自osg
	osg::ref_ptr<NodeMatrix> nm = new NodeMatrix ;
	osg::ref_ptr<osg::Group> group = new osg::Group;
	osg::ref_ptr<osg::Node> node = osgDB::readNodeFile("glider.osg");
	osg::ref_ptr<osg::Node> cowNode = osgDB::readNodeFile("TrCow.osg");

	//nm->addsChild(node.get());
	//nm->rotating(osg::Vec3d(5.0, 0.0, 0.0), osg::Z_AXIS, 1.0); // 围绕原点一直旋转
	//nm->toRotate(osg::Matrix::translate(10.0, 0.0, 0.0)); // 按照矩阵,旋转指定角度
	//nm->toRotate(1, osg::Y_AXIS); // 围绕y轴旋转指定角度

	nm->addsChild(cowNode.get());
	nm->toPosition(osg::Vec3d(5.0, 0.0, 0.0));
	nm->adapt(node.get());// 将 牛模型,缩放到跟飞机模型一样大;

	group->addChild(nm.get());
	group->addChild(node.get());

	viewer->setSceneData(group.get());
	return viewer->run();
}

运行结果如图:

后一章节:

六、OSG学习笔记-漫游(操作器)-CSDN博客https://blog.csdn.net/weixin_36323170/article/details/145515189


http://www.kler.cn/a/542463.html

相关文章:

  • Vue3.5 企业级管理系统实战(六):Vue3中defineProps用法
  • 如何设置爬虫的IP代理?
  • .Net使用EF Core框架如何连接Oracle
  • QT实现多线程的方法
  • PHP 完整表单实例
  • INFINI Labs 产品更新 - Easysearch 增强 Rollup 能力,Console 完善 TopN 指标等
  • 25考研材料复试面试常见核心问题真题汇总,材料考研复试面试有哪些经典问题?材料考研复试过程最看重什么内容?
  • python C# 内存共享互传 图像 以及字符串
  • 蓝桥杯 Java B 组 - 第 1 周复习总结
  • 3、k8s项目的生命周期和yaml文件
  • uniapp商城之登录模块
  • 《深度学习》——CNN卷积神经网络模型及项目实例
  • 【Prometheus】MySQL主从搭建,以及如何通过prometheus监控MySQL运行状态
  • FTP(File Transfer Protocol)-文件传输协议
  • C++引用深度详解
  • Unity做2D小游戏5------多个动画互相转换
  • docker配置国内源
  • 【unity实战】实现摄像机跟随效果
  • 【AI知识点】大模型开源的各种级别和 deepseek 的开源级别
  • Java 大视界 -- 5G 与 Java 大数据融合的行业应用与发展趋势(82)
  • ArcGIS Pro SDK (二十六)自定义配置
  • 基于 PyTorch 的树叶分类任务:从数据准备到模型训练与测试
  • 25考研电子信息复试面试常见核心问题真题汇总,电子信息考研复试没有项目怎么办?电子信息考研复试到底该如何准备?
  • 进阶版MATLAB 3D柱状图
  • 【系统架构设计师】操作系统 - 进程管理 ① ( 进程概念 | 进程组成 | 进程 与 程序 | 进程 与 线程 | 线程 可共享的资源 - ☆考点 )
  • 工具模块新增JSON格式化打印工具类