DOF和MultiSwitch的使用

利用前一篇博客的场景,添加两个坦克结点,一个结点是报废的坦克,一个是旋转炮塔的坦克,需要用到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();

}


你可能感兴趣的:(String,测试)