一、矩阵变换的三种方式
二、
示例代码:
#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();
}
运行结果如图: