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

六、OSG学习笔记-漫游(操作器)

一、实例代码操作器

 

Travel.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>

#include<osgGA/GUIEventAdapter>
#include <osgGA/StandardManipulator>
// 自定义操作器类

class TravelManipulator : public osgGA::CameraManipulator
{
public:
	TravelManipulator();
	~TravelManipulator();

public:
	// 实现得到和设置矩阵的接口
	/** 设置当前视口 using a 4x4 Matrix.*/
	void setByMatrix(const osg::Matrixd& matrix) override;

	/** 设置当前视口 using a 4x4 Matrix.*/
	void setByInverseMatrix(const osg::Matrixd& matrix) override;

	/** 得到当前矩阵 4x4 Matrix.*/
	osg::Matrixd getMatrix() const override;

	/** 得到当前逆矩阵 used as a model view matrix.*/
	osg::Matrixd getInverseMatrix() const override;

	// 响应事件
	bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& us )override;

private:
	// 视点
	osg::Vec3 m_vPosition;

	// 朝向
	osg::Vec3 m_vRotation;

	// 移动步长
	int m_vStep;

	// 旋转步长
	float m_vRotateStep;
};

Travel.cpp

#include "Travel.h"
#include <osgGA/GUIEventAdapter>

TravelManipulator::TravelManipulator()
{
	// 视点Z 值越小,模型文件越靠近放大,Z值越大,越缩小
	m_vPosition = osg::Vec3(0, 0, 1);
	m_vRotation = osg::Vec3(0, 0, 0);
	m_vStep = 0;
	m_vRotateStep = 0.0;
}

TravelManipulator::~TravelManipulator()
{
}

void TravelManipulator::setByMatrix(const osg::Matrixd& matrix)
{
}

void TravelManipulator::setByInverseMatrix(const osg::Matrixd& matrix)
{
}

osg::Matrixd TravelManipulator::getMatrix() const
{
	osg::Matrixd mat;
	mat.makeTranslate(m_vPosition);
	osg::Matrixd retMat = mat * osg::Matrixd::rotate(m_vRotation[0], osg::X_AXIS, m_vRotation[1],  osg::Y_AXIS, m_vRotation[2], osg::Z_AXIS);
	return retMat;
}

osg::Matrixd TravelManipulator::getInverseMatrix() const
{
	osg::Matrixd mat;
	mat.makeTranslate(m_vPosition);
	osg::Matrixd retMat = mat * osg::Matrixd::rotate(m_vRotation[0], osg::X_AXIS, m_vRotation[1], osg::Y_AXIS, m_vRotation[2], osg::Z_AXIS);
	return osg::Matrixd::inverse(retMat);
}

bool TravelManipulator::handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& us)
{
	switch (ea.getEventType())
	{
	case osgGA::GUIEventAdapter::KEYDOWN:
	{
		if (ea.getKey() == 'w')
		{
			m_vPosition[2] += 2; // 前进
		}
		else if (ea.getKey() == 's')
		{
			m_vPosition[2] -= 2; // 后退
		}
	}

	default:
		break;
	}
	return false;
}

main.cpp

#include "Travel.h"


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

	osg::ref_ptr<osg::Node> node = osgDB::readNodeFile("glider.osg");
	

	viewer->setSceneData(node.get());

	// 加入操作器
	osgGA::CameraManipulator* pCameraPlator = new TravelManipulator();
	viewer->setCameraManipulator(pCameraPlator);
    	return viewer->run();
}

二、漫游,操作器实例代码

代码:CuiQingCheng/OsgStudy - Gitee.com

Travel.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>

#include<osgGA/GUIEventAdapter>
#include <osgGA/StandardManipulator>
// 自定义操作器类

class TravelManipulator : public osgGA::CameraManipulator
{
public:
	TravelManipulator();
	~TravelManipulator();

public:
	// 实现得到和设置矩阵的接口
	/** 设置当前视口 using a 4x4 Matrix.*/
	void setByMatrix(const osg::Matrixd& matrix) override;

	/** 设置当前视口 using a 4x4 Matrix.*/
	void setByInverseMatrix(const osg::Matrixd& matrix) override;

	/** 得到当前矩阵 4x4 Matrix.*/
	osg::Matrixd getMatrix() const override;

	/** 得到当前逆矩阵 used as a model view matrix.*/
	osg::Matrixd getInverseMatrix() const override;

	// 响应事件
	bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& us )override;

	// 设置步长
	void setStep(int iStep);

	// 获得步长
	int getStep() const;

	// 设置到某一点
	void setPosition(osg::Vec3d pos);

	// 得到当前坐标
	osg::Vec3d getPosition();

private:
	// 改变位置
	void ChangePosition(const osg::Vec3d& delta);

private:
	// 视点
	osg::Vec3 m_vPosition;

	// 朝向
	osg::Vec3 m_vRotation;

	// 移动步长
	int m_vStep;

	// 旋转步长
	float m_vRotateStep;

	// 记录坐标
	int m_iLeftX;
	int m_iLeftY;

	bool m_bLeftDown{false};
};

Travel.cpp

#include "Travel.h"
#include <osgGA/GUIEventAdapter>

TravelManipulator::TravelManipulator()
{
	m_vPosition = osg::Vec3(0, 0, 5);

	// 围绕X轴转转90度
	m_vRotation = osg::Vec3(osg::PI_2, 0, 0);
	m_vStep = 2;
	m_vRotateStep = 0.0;
}

TravelManipulator::~TravelManipulator()
{
}

void TravelManipulator::setByMatrix(const osg::Matrixd& matrix)
{
}

void TravelManipulator::setByInverseMatrix(const osg::Matrixd& matrix)
{
}

osg::Matrixd TravelManipulator::getMatrix() const
{
	osg::Matrixd mat;
	mat.makeTranslate(m_vPosition);
	osg::Matrixd retMat = osg::Matrixd::rotate(m_vRotation[0], osg::X_AXIS, m_vRotation[1],  osg::Y_AXIS, m_vRotation[2], osg::Z_AXIS) * mat;
	return retMat;
}

osg::Matrixd TravelManipulator::getInverseMatrix() const
{
	osg::Matrixd mat;
	mat.makeTranslate(m_vPosition);
	osg::Matrixd retMat = osg::Matrixd::rotate(m_vRotation[0], osg::X_AXIS, m_vRotation[1], osg::Y_AXIS, m_vRotation[2], osg::Z_AXIS) * mat;
	return osg::Matrixd::inverse(retMat);
}

bool TravelManipulator::handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& us)
{
	switch (ea.getEventType())
	{
	case osgGA::GUIEventAdapter::KEYDOWN:
	{
		if ((ea.getKey() == 'w') || (ea.getKey() == 'W') || (ea.getKey() == osgGA::GUIEventAdapter::KEY_Up))
		{
			osg::Vec3d delta = osg::Vec3d(m_vStep * cosf(osg::PI_2 + m_vRotation._v[2]), m_vStep * sinf(osg::PI_2 + m_vRotation._v[2]), 0);
			ChangePosition(delta);
			return true;
		}
		else if ((ea.getKey() == 's') || (ea.getKey() == 'S') || (ea.getKey() == osgGA::GUIEventAdapter::KEY_Down))
		{
			osg::Vec3d delta = osg::Vec3d(-m_vStep * cosf(osg::PI_2 + m_vRotation._v[2]), -m_vStep * sinf(osg::PI_2 + m_vRotation._v[2]), 0);
			ChangePosition(delta);
			return true;
		}
		else if ((ea.getKey() == 'a') || (ea.getKey() == 'A'))
		{
			osg::Vec3d delta = osg::Vec3d(m_vStep * sinf(osg::PI_2 + m_vRotation._v[2]), m_vStep * cosf(osg::PI_2 + m_vRotation._v[2]), 0);
			ChangePosition(delta);
			return true;
		}
		else if ((ea.getKey() == 'd') || (ea.getKey() == 'D'))
		{
			osg::Vec3d delta = osg::Vec3d(-m_vStep * sinf(osg::PI_2 + m_vRotation._v[2]), -m_vStep * cosf(osg::PI_2 + m_vRotation._v[2]), 0);
			ChangePosition(delta);
			return true;
		}
		else if (ea.getKey() ==  osgGA::GUIEventAdapter::KEY_Left)
		{
			m_vRotation[2] += 0.2;
			return true;
		}
		else if (ea.getKey() == osgGA::GUIEventAdapter::KEY_Right)
		{
			m_vRotation[2] -= 0.2;
			return true;
		}
		else if (ea.getKey() == osgGA::GUIEventAdapter::KEY_Home)
		{
			ChangePosition(osg::Vec3d(0, 0, m_vStep));
			return true;
		}
		else if (ea.getKey() == osgGA::GUIEventAdapter::KEY_End)
		{
			ChangePosition(osg::Vec3d(0, 0, -m_vStep));
			return true;
		}
	}
		break;
	case osgGA::GUIEventAdapter::PUSH: // 鼠标按下
	{
		if (ea.getButton() == osgGA::GUIEventAdapter::LEFT_MOUSE_BUTTON)
		{
			m_iLeftX = ea.getX();
			m_iLeftY = ea.getY();
			m_bLeftDown = true;
		}
		return false;
	}
		break;
	case osgGA::GUIEventAdapter::DRAG: // 鼠标拖动
	{
		if (m_bLeftDown)
		{
			int delX = ea.getX() - m_iLeftX;
			m_vRotation[2] -= osg::DegreesToRadians(0.005 * delX);
			int delY = ea.getY() - m_iLeftY;
			m_vRotation[0] -= osg::DegreesToRadians(0.005 * delY);
			if (m_vRotation[0] > osg::PI)
			{
				m_vRotation[0] = osg::PI;
			}
			else if (m_vRotation[0] < 0)
			{
				m_vRotation[0] = 0;
			}
		}
	}
		break;
	case osgGA::GUIEventAdapter::RELEASE: // 鼠标释放
	{
		if (ea.getButton() == osgGA::GUIEventAdapter::LEFT_MOUSE_BUTTON)
		{
			m_bLeftDown = false;
		}
	}
		break;
	default:
		break;
	}
	return false;
}

void TravelManipulator::setStep(int iStep)
{
	m_vStep = iStep;
}

int TravelManipulator::getStep() const
{
	return m_vStep;
}

void TravelManipulator::setPosition(osg::Vec3d pos)
{
	m_vPosition = pos;
}

osg::Vec3d TravelManipulator::getPosition()
{
	return m_vPosition;
}

void TravelManipulator::ChangePosition(const osg::Vec3d& delta)
{
	m_vPosition += delta;
}

main.cpp

#include "Travel.h"
#include "../NodeMatrix/NodeMatrix.h"

// 导入静态库
#ifdef _DEBUG
#pragma comment (lib, "../x64/Debug/NodeMatrix.lib")
#else
#pragma comment (lib, "../x64/Release/NodeMatrix.lib")
#endif // DEBUG


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

	osg::ref_ptr<NodeMatrix> nm = new NodeMatrix;
	nm->addsChild(osgDB::readNodeFile("ceep.ive"));
	//osg::ref_ptr<osg::Node> node = osgDB::readNodeFile("ceep.ive");
	

	viewer->setSceneData(nm.get());

	// 加入操作器
	osgGA::CameraManipulator* pCameraPlator = new TravelManipulator();
	viewer->setCameraManipulator(pCameraPlator);
	return viewer->run();
}

这里静态库为前一节中矩阵变换封装的静态库;

运行效果:


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

相关文章:

  • 海量表格文字识别、PHP表格识别接口:从传统到智能
  • 【AI-27】DPO和PPO的区别
  • verilog练习:i2c slave 模块设计
  • 线程上下文-ThreadLocal原理
  • 如何在Vscode中接入Deepseek
  • Android studio 创建aar包给Unity使用
  • ViewModel和LiveData
  • ES6中的模板字符串
  • 2025年2月9日(数据分析,在最高点和最低点添加注释,添加水印)
  • 面向对象设计在Java程序开发中的最佳实践研究
  • 【服务器知识】如何在linux系统上搭建一个nfs
  • springboot 事务管理
  • 植物神经紊乱:补充这些维生素,为健康 “充电”
  • Http 的响应码有哪些? 分别代表的是什么?
  • 算法基础之八大排序
  • C++设计模式 —— 工厂模式
  • Docker 部署 MinIO | 国内阿里镜像
  • vLLM V1 重磅升级:核心架构全面革新
  • DeepSeek结合Langchain的基本用法
  • 卷积神经网络CNN如何处理语音信号
  • 2025年物联网相关专业毕业论文选题参考,文末联系,选题相关资料提供
  • 学生管理系统
  • Qt元对象系统
  • C++排序算法的优劣及应用
  • 通过cad中块获取块的略缩图——cad c# 二次开发
  • C++ 继承(1)