您的位置:首页 > 其它

DOF和MultiSwitch的使用

2012-02-26 12:10 127 查看
利用前一篇博客的场景,添加两个坦克结点,一个结点是报废的坦克,一个是旋转炮塔的坦克,需要用到DOF和MultSwitch。

1.坦克模型由许多的其他模型结点组成,这里就包括炮塔结点和炮筒结点,本文只用了炮塔。

2.需要一个能找到炮塔结点的方法,这里我们定义了一个类myFindNodeVisitor.

myFindNodeVisitor.h

//By smells2 At Lab 2012-02-24

#include <osg/NodeVisitor>
#include <osgSim/DOFTransform>
#include <iostream>
#include <vector>

#ifdef _DEBUG
#pragma comment(lib,"osgSimd.lib")
#else
#pragma comment(lib,"osgSim.lib")
#endif
class myFindNodeVisitor :public osg::NodeVisitor
{
public:
//构造函数,两种,一种无参,一种有参,参数为欲查询结点的名字
myFindNodeVisitor();
myFindNodeVisitor(const std::string &searchNmae);

//更改所要查询的结点名字
void setNameToFind(const std::string &searchName);

//重载apply函数,主要的查询代码在这里实现
virtual void apply(osg::Node& node);
virtual void apply(osg::Transform& node);

//获取查询结果列表的第一个结点
osg::Node* getFirst();

//获取结点列表
typedef std::vector<osg::Node*> NodeListType;
NodeListType& getNodeList(){return m_nodeList;}

protected:

std::string m_searchName;
NodeListType m_nodeList;

};


myFindNodeVisitor.cpp

#include "myFindNodeVisitor.h"

myFindNodeVisitor::myFindNodeVisitor():osg::NodeVisitor(TRAVERSE_ALL_CHILDREN),m_searchName()
{

}

myFindNodeVisitor::myFindNodeVisitor(const std::string &searchNmae):osg::NodeVisitor(TRAVERSE_ALL_CHILDREN),
m_searchName(searchNmae)
{

}

void myFindNodeVisitor::setNameToFind(const std::string &searchName)
{
m_searchName = searchName;
m_nodeList.clear();
}

osg::Node* myFindNodeVisitor::getFirst()
{
return *(m_nodeList.begin());
}

void myFindNodeVisitor::apply(osg::Node& node)
{
if (node.getName() == m_searchName)
{
m_nodeList.push_back(&node);
}
traverse(node);
}

void myFindNodeVisitor::apply(osg::Transform &searchNode)
{
osgSim::DOFTransform* dofNode =
dynamic_cast<osgSim::DOFTransform*> (&searchNode);
if (dofNode)
{
dofNode->setAnimationOn(false);
}
apply ( (osg::Node&) searchNode);
traverse(searchNode);
}


准备好上述代码,我们来做炮塔的旋转和报废的坦克。

#include "myFindNodeVisitor.h"
#include <osgDB/readfile>
#include <osgDB/WriteFile>
#include <osgViewer/Viewer>
#include <osg/Group>
#include <osg/Node>
#include <osg/PositionAttitudeTransform>
#include <osgSim/MultiSwitch>
#include <iostream>
#ifdef _DEBUG
#pragma comment(lib,"osgd.lib")
#pragma comment(lib,"osgDBd.lib")
#pragma comment(lib,"osgViewerd.lib")
#pragma comment(lib,"osgSimd.lib")
#else
#pragma comment(lib,"osg.lib")
#pragma comment(lib,"osgDB.lib")
#pragma comment(lib,"osgViewer.lib")
#pragma comment(lib,"osgSim.lib")
#endif

int main()
{
osg::ref_ptr<osg::Group> root = new osg::Group;
//载入三个坦克模型,并按照一定的顺序摆放,摆放的位置和角度是一次一次运行测试出来的。
osg::ref_ptr<osg::Node> normalTank = osgDB::readNodeFile("t72-tank/t72-tank_des.flt");
osg::ref_ptr<osg::Node> brokenTank = osgDB::readNodeFile("t72-tank/t72-tank_des.flt");
osg::ref_ptr<osg::Node> atteckTank = osgDB::readNodeFile("t72-tank/t72-tank_des.flt");
osg::ref_ptr<osg::Node> landDust = osgDB::readNodeFile("t72-tank/JoeDirt.flt");
root->addChild(landDust.get());

osg::ref_ptr<osg::PositionAttitudeTransform> normalTankPAT = new osg::PositionAttitudeTransform;
normalTankPAT->addChild(normalTank.get());
normalTankPAT->setPosition(osg::Vec3(0,20,7));
root->addChild(normalTankPAT.get());

osg::ref_ptr<osg::PositionAttitudeTransform> brokenTankPAT = new osg::PositionAttitudeTransform;
brokenTankPAT->addChild(brokenTank.get());
brokenTankPAT->setPosition(osg::Vec3(20,10,8));
brokenTankPAT->setAttitude(osg::Quat(osg::DegreesToRadians(22.5f),osg::Vec3(0.0f,0.0f,1.0f)));
root->addChild(brokenTankPAT.get());

osg::ref_ptr<osg::PositionAttitudeTransform> atteckTankPAT = new osg::PositionAttitudeTransform;
atteckTankPAT->addChild(atteckTank.get());
atteckTankPAT->setPosition(osg::Vec3(-20,50,5));
atteckTankPAT->setAttitude(osg::Quat(osg::DegreesToRadians(45.0f),osg::Vec3(0.0f,0.0f,1.0f)));
root->addChild(atteckTankPAT.get());

//声明myFindNodeVisitor对象,并用“sw1”字符串初始化
myFindNodeVisitor findNodeVisitor;
findNodeVisitor.setNameToFind("sw1");

//开始执行访问器实例的遍历过程,起点是brokenTank,搜索它所有的子节点并创建一个列表,用于保存所有符合搜索条件的节点
brokenTank->accept(findNodeVisitor);
osgSim::MultiSwitch* brokenTankSwitch = dynamic_cast<osgSim::MultiSwitch*>(findNodeVisitor.getFirst());
if (!brokenTankSwitch)
{
std::cout<<"Finding 'sw1' node failed !"<<std::endl;
return -1;
}
brokenTankSwitch->setSingleChildOn(0,true);
//搜索炮塔结点,找到后将炮塔旋转一个角度
myFindNodeVisitor findDOF;
findDOF.setNameToFind("turret");

atteckTankPAT->accept(findDOF);
osgSim::DOFTransform* thirdTankDOFTurret = dynamic_cast<osgSim::DOFTransform*>(findDOF.getFirst());
if (!thirdTankDOFTurret)
{
std::cout<<"Finding 'sw1' node failed !"<<std::endl;
return -1;
}
thirdTankDOFTurret->setCurrentHPR(osg::Vec3(-3.14159/4.0,0.0,0.0));

osgDB::writeNodeFile(*(normalTank.get()),"/tank.osg");
osgViewer::Viewer myViewer;
myViewer.setSceneData(root.get());
myViewer.realize();
myViewer.run();

}


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: