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

一、矩阵变换的三种方式

二、

示例代码:

#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();
}

运行结果如图:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/966294.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

数据结构与算法-递归

单路递归 二分查找 /*** 主函数&#xff1a;执行二分查找。* * param a 要搜索的数组&#xff08;必须是已排序的&#xff09;* param target 目标值* return 返回目标值在数组中的索引&#xff1b;如果未找到&#xff0c;则返回 -1*/ public static int binarySearch(int[] …

使用python构建局域网HTTP服务进行文件共享

网上有很多参考&#xff0c;在此作为归纳和自己的笔记 首先确保python的目录在系统环境变量中&#xff0c;如果同时有python2.和python3.版本可以将python程序改名进行区分&#xff0c;譬如python2的解释器程序从python.exe改为python2.exe&#xff0c;python3改为python3c.ex…

深入理解小波变换:信号处理的强大工具

引言 在科学与工程领域&#xff0c;信号处理一直是关键环节&#xff0c;傅里叶变换与小波变换作为重要的分析工具&#xff0c;在其中发挥着重要作用。本文将深入探讨小波变换&#xff0c;阐述其原理、优势以及与傅里叶变换的对比&#xff0c;并通过具体案例展示其应用价值。 一…

洛谷P8681 [蓝桥杯 2019 省 AB] 完全二叉树的权值

虽然是简单题&#xff0c;就是log2的运用&#xff0c;然后对于同层的数据累加取最大值 #include<bits/stdc.h>using namespace std;const int N100010; int a[N];int main(){int n;cin>>n;int MAX-1;for( int i1;i<n;i){int j;cin>>j;// cout<<(in…

Java基础知识(七) -- 集合

1.概述 集合是 Java 中提供的一种容器&#xff0c;可以用来存储多个数据。集合主要分为两大系列&#xff1a;Collection和Map&#xff0c;Collection 表示一组对象&#xff0c;Map表示一组映射关系或键值对。集合和数组既然都是容器&#xff0c;它们有啥区别呢&#xff1f; 数…

C++Primer学习(2.1)

前言&#xff1a;与大多数编程语言一样&#xff0c;C的对象类型决定了能对该对象进行的操作&#xff0c;一条表达式是否合法依赖于其中参与运算的对象的类型。一些语言&#xff0c;如Smalltalk和Python 等&#xff0c;在程序运行时检查数据类型;与之相反&#xff0c;C是一种静态…

TensorFlow深度学习实战(7)——分类任务详解

TensorFlow深度学习实战&#xff08;7&#xff09;——分类任务详解 0. 前言1. 分类任务1.1 分类任务简介1.2 分类与回归的区别 2. 逻辑回归3. 使用 TensorFlow 实现逻辑回归小结系列链接 0. 前言 分类任务 (Classification Task) 是机器学习中的一种监督学习问题&#xff0c;…

国产编辑器EverEdit - 查找功能详解

1 查找功能详解 1.1 应用场景 查找关键词应该是整个文本编辑/阅读活动中&#xff0c;操作频度非常高的一项&#xff0c;用好查找功能&#xff0c;不仅可以可以搜索到关键字&#xff0c;还可以帮助用户高效完成一些特定操作。 1.2 基础功能 1.2.1 基础查找功能 选择主菜单查…

5分钟了解回归测试

1. 什么是回归测试&#xff08;Regression Testing&#xff09; 回归测试是一个系统的质量控制过程&#xff0c;用于验证最近对软件的更改或更新是否无意中引入了新错误或对以前的功能方面产生了负面影响&#xff08;比如你在家中安装了新的空调系统&#xff0c;发现虽然新的空…

【AI】卷积神经网络CNN

不定期更新&#xff0c;建议关注收藏点赞。 目录 零碎小组件经验总结早期的CNN 最重要的模型架构无非是cnn 或 transformer 零碎小组件 全连接神经网络 目前已经被替代。 每个神经元都有参与&#xff0c;但由于数据中的特征点变化大&#xff0c;全连接神经网络把所有数据特征都…

企业FTP替代升级,实现传输大文件提升100倍!

随着信息技术的飞速发展&#xff0c;网络安全环境也变得越来越复杂。在这种背景下&#xff0c;传统的FTP&#xff08;文件传输协议&#xff09;已经很难满足现代企业对文件传输的需求了。FTP虽然用起来简单&#xff0c;但它的局限性和安全漏洞让它在面对高效、安全的数据交换时…

LabVIEW铅酸蓄电池测试系统

本文介绍了基于LabVIEW的通用飞机铅酸蓄电池测试系统的设计与实现。系统通过模块化设计&#xff0c;利用多点传感器采集与高效的数据处理技术&#xff0c;显著提高了蓄电池测试的准确性和效率。 ​ 项目背景 随着通用航空的快速发展&#xff0c;对飞机铅酸蓄电池的测试需求也…

Lecture8 | LPV VXGI SSAO SSDO

Review: Lecture 7 | Lecture 8 LPV (Light Propagation Volumes) Light Propagation Volumes(LPV)-孤岛惊魂CryEngine引进的技术 LPV做GI快|好 大体步骤&#xff1a; Step1.Generation of Radiance Point Set Scene Representation 生成辐射点集的场景表示&#xff1a;辐射…

0012—数组

存取一组数据&#xff0c;使用数组。 数组是一组相同类型元素的集合。 要存储1-10的数字&#xff0c;怎么存储&#xff1f; C语言中给了数组的定义&#xff1a;一组相同类型元素的集合。 创建一个空间创建一组数&#xff1a; 一、数组的定义 int arr[10] {1,2,3,4,5,6,7,8,…

AI绘画社区:解锁艺术共创的无限可能(9/10)

AI 绘画&#xff1a;不只是技术&#xff0c;更是社交新潮流 在科技飞速发展的今天&#xff0c;AI 绘画早已不再仅仅是一项孤立的技术&#xff0c;它正以惊人的速度融入我们的社交生活&#xff0c;成为艺术爱好者们交流互动的全新方式&#xff0c;构建起一个充满活力与创意的社…

让office集成deepseek,支持office和WPS办公软件!(体验感受)

导读 AIGC:AIGC是一种新的人工智能技术&#xff0c;它的全称是Artificial Intelligence Generative Content&#xff0c;即人工智能生成内容。 它是一种基于机器学习和自然语言处理的技术&#xff0c;能够自动产生文本、图像、音频等多种类型的内容。这些内容可以是新闻文章、…

c++ template-3

第 7 章 按值传递还是按引用传递 从一开始&#xff0c;C就提供了按值传递&#xff08;call-by-value&#xff09;和按引用传递&#xff08;call-by-reference&#xff09;两种参数传递方式&#xff0c;但是具体该怎么选择&#xff0c;有时并不容易确定&#xff1a;通常对复杂类…

使用springAI实现图片相识度搜索

类似的功能&#xff1a;淘宝拍照识别商品。图片相识度匹配 实现方式&#xff1a;其实很简单&#xff0c;用springai 将图片转换为向量数据&#xff0c;然后搜索就是先把需要搜索的图片转位向量再用向量数据去向量数据库搜索 但是springai现在不支持多模态嵌入数据库。做了一些…

私有化部署DeepSeek并SpringBoot集成使用(附UI界面使用教程-支持语音、图片)

私有化部署DeepSeek并SpringBoot集成使用&#xff08;附UI界面使用教程-支持语音、图片&#xff09; windows部署ollama Ollama 是一个开源框架&#xff0c;专为在本地机器上便捷部署和运行大型语言模型&#xff08;LLM&#xff09;而设计 下载ollama 下载地址&#xff08;…

半导体制造工艺讲解

目录 一、半导体制造工艺的概述 二、单晶硅片的制造 1.单晶硅的制造 2.晶棒的切割、研磨 3.晶棒的切片、倒角和打磨 4.晶圆的检测和清洗 三、晶圆制造 1.氧化与涂胶 2.光刻与显影 3.刻蚀与脱胶 4.掺杂与退火 5.薄膜沉积、金属化和晶圆减薄 6.MOSFET在晶圆表面的形…