标签:
下面的代码将可以实现场景模型的导入,然后在里面任意行走,于此同时还实现了碰撞检测。
源代码下载地址:
1 /* 2 * File : Travel.cpp 3 * Description : 4 * Author : GuoShaoHao 5 * E-mail : gsh0913@qq.com 6 * Date : 2011/01/08 7 * 8 * CopyRight @ South China Institute of Software Engineering,.GZU 9 * 10 */ 11 12 #include <iostream> 13 #include <osgViewer/Viewer> 14 #include <osg/Node> 15 #include <osg/Geode> 16 #include <osg/Group> 17 18 #include <osgDB/ReadFile> 19 #include <osgDB/WriteFile> 20 21 #include <osgUtil/Optimizer> 22 23 #include <osg/MatrixTransform> 24 #include <osgViewer/ViewerEventHandlers> 25 #include <osgGA/StateSetManipulator> 26 27 #include "TravelManipulator.h" 28 29 using namespace std; 30 31 32 int main() 33 { 34 //创建Viewer对象 35 osg::ref_ptr<osgViewer::Viewer>viewer = new osgViewer::Viewer(); 36 37 //添加状态事件 38 //viewer.get()->addEventHandler( new osgGA::StateSetManipulator(viewer.getCamera()->getOrCreateStateSet()) ); 39 //窗口大小变化事件 40 viewer.get()->addEventHandler(new osgViewer::WindowSizeHandler); 41 //添加一些常用状态设置 42 viewer.get()->addEventHandler(new osgViewer::StatsHandler); 43 44 // 把漫游器加入到场景中 45 TravelManipulator::TravelToScence(viewer.get()); 46 47 osg::ref_ptr<osg::Group>root = new osg::Group(); 48 49 // 读取地形 50 osg::ref_ptr<osg::Node>node = osgDB::readNodeFile("D://OSG//data//lz.osg"); 51 52 // 读取飞机 53 //osg::ref_ptr<osg::Node>tank = osgDB::readNodeFile("F://Models//Amx30//Amx30.IVE"); 54 osg::ref_ptr<osg::Node>B25 = osgDB::readNodeFile("Models//B25//B25.IVE"); 55 56 osg::ref_ptr < osg::MatrixTransform> scale = new osg::MatrixTransform ; 57 scale ->setMatrix(osg::Matrix::scale(0.1, 0.1, 0.1)*osg::Matrix::translate(-10.0f, -250.0f, 99.0f)) ; 58 scale ->addChild(B25.get()) ; 59 60 // 添加到场景 61 root->addChild(node.get()); 62 root->addChild(scale.get()); 63 //root->addChild(B25.get()); 64 65 // 优化场景数据 66 osgUtil::Optimizer optimizer; 67 optimizer.optimize(root.get()); 68 69 viewer->setSceneData(root.get()); 70 71 viewer->realize(); 72 73 viewer->run(); 74 75 return 0; 76 77 }
1 #pragma once 2 3 #include <osgViewer/Viewer> 4 5 #include <osg/LineSegment> 6 #include <osg/Point> 7 #include <osg/Geometry> 8 #include <osg/Node> 9 #include <osg/Geode> 10 #include <osg/Group> 11 12 #include <osgGA/MatrixManipulator> 13 14 #include <osgUtil/IntersectVisitor> 15 16 #include <vector> 17 18 class TravelManipulator:public osgGA::MatrixManipulator 19 { 20 21 public: 22 23 TravelManipulator(void); 24 ~TravelManipulator(void); 25 26 // 把漫游器添加到场景中 27 static TravelManipulator * TravelToScence(osg::ref_ptr<osgViewer::Viewer>viewer); 28 29 private: 30 31 osg::ref_ptr<osgViewer::Viewer>m_pHostViewer; 32 33 // 移动速度 34 float m_fMoveSpeed; 35 36 // 当前位置 37 osg::Vec3 m_vPosition; 38 39 // 旋转角度 40 osg::Vec3 m_vRotation; 41 42 public: 43 44 // 鼠标左键状态 45 bool m_bLeftButtonDown; 46 47 // 鼠标位置 48 float m_fpushX; 49 float m_fpushY; 50 51 // 设置矩阵 52 virtual void setByMatrix(const osg::Matrix &matrix); 53 54 // 设置逆矩阵 55 virtual void setByInverseMatrix(const osg::Matrix &matrix); 56 57 // 获取矩阵 58 virtual osg::Matrixd getMatrix() const; 59 60 // 获取逆矩阵 61 virtual osg::Matrixd getInverseMatrix() const; 62 63 // 事件处理函数 64 virtual bool handle(const osgGA::GUIEventAdapter &ea, osgGA::GUIActionAdapter &us); 65 66 // 屏幕角度 67 float m_fAngle; 68 69 // 位置变换 70 void ChangePosition(osg::Vec3 &delta); 71 72 // 碰撞检测状态 73 bool m_bPeng; 74 75 // 设置速度 76 float getSpeed(); 77 78 void setSpeed(float &); 79 80 // 设置初始位置 81 void SetPosition(osg::Vec3 &position); 82 83 osg::Vec3 GetPosition(); 84 85 86 };
1 #include "TravelManipulator.h" 2 3 // 构造函数 4 TravelManipulator::TravelManipulator():m_fMoveSpeed(1.0f), 5 m_bLeftButtonDown(false), 6 m_fpushX(0), 7 m_fAngle(2.5), 8 m_bPeng(true), 9 m_fpushY(0) 10 { 11 m_vPosition = osg::Vec3(-22.0f, -274.0f, 100.0f); 12 m_vRotation = osg::Vec3(osg::PI_2, 0.0f, 0.0f); 13 } 14 15 TravelManipulator::~TravelManipulator(void) 16 { 17 } 18 19 // 把漫游器添加到场景中 20 TravelManipulator *TravelManipulator::TravelToScence(osg::ref_ptr<osgViewer::Viewer> viewer) 21 { 22 TravelManipulator* camera = new TravelManipulator; 23 24 viewer->setCameraManipulator(camera); 25 26 camera->m_pHostViewer = viewer; 27 28 return camera; 29 } 30 31 // 设置矩阵 32 void TravelManipulator::setByMatrix(const osg::Matrix &matrix) 33 { 34 35 } 36 37 // 设置逆矩阵 38 void TravelManipulator::setByInverseMatrix(const osg::Matrix &matrix) 39 { 40 41 } 42 43 // 得到矩阵 44 osg::Matrixd TravelManipulator::getMatrix(void)const 45 { 46 osg::Matrixd mat; 47 48 mat.makeRotate(m_vRotation._v[0], osg::Vec3(1.0f, 0.0f, 0.0f), 49 m_vRotation._v[1], osg::Vec3(0.0f, 1.0f, 0.0f), 50 m_vRotation._v[2], osg::Vec3(0.0f, 0.0f, 1.0f)); 51 52 return mat * osg::Matrixd::translate(m_vPosition); 53 54 } 55 56 // 得到逆矩阵 57 osg::Matrixd TravelManipulator::getInverseMatrix(void) const 58 { 59 osg::Matrixd mat; 60 61 mat.makeRotate(m_vRotation._v[0], osg::Vec3(1.0f, 0.0f, 0.0f), 62 m_vRotation._v[1], osg::Vec3(0.0f, 1.0f, 0.0f), 63 m_vRotation._v[2], osg::Vec3(0.0f, 0.0f, 1.0f)); 64 65 return osg::Matrixd::inverse(mat * osg::Matrixd::translate(m_vPosition)); 66 } 67 68 // 事件处理函数 69 bool TravelManipulator::handle(const osgGA::GUIEventAdapter &ea, osgGA::GUIActionAdapter &us) 70 { 71 // 获取鼠标位置 72 float mouseX = ea.getX(); 73 float mouseY = ea.getY(); 74 75 switch(ea.getEventType()) 76 { 77 case(osgGA::GUIEventAdapter::KEYDOWN): 78 { 79 // 空格键 80 if(ea.getKey() == 0x20) 81 { 82 us.requestRedraw(); 83 us.requestContinuousUpdate(false); 84 85 return true; 86 87 } 88 89 // 上移键 90 if (ea.getKey() == 0xFF50) 91 { 92 ChangePosition(osg::Vec3(0, 0, m_fMoveSpeed)); 93 94 return true; 95 } 96 97 // 下移键 98 if (ea.getKey() == 0xFF57) 99 { 100 ChangePosition(osg::Vec3(0, 0, -m_fMoveSpeed)); 101 102 return true; 103 } 104 105 // 加速 106 if (ea.getKey() == 0x2B) 107 { 108 m_fMoveSpeed += 1.0f; 109 110 return true; 111 } 112 113 // 减少速度 114 if (ea.getKey() == 0x2D) 115 { 116 m_fMoveSpeed -= 0.1f; 117 118 if(m_fMoveSpeed < 1.0f) 119 { 120 m_fMoveSpeed = 1.0f; 121 } 122 123 return true; 124 } 125 126 // 前进 127 if (ea.getKey() == 0xFF52 || ea.getKey() == 0x57 || ea.getKey() == 0x77) 128 { 129 ChangePosition(osg::Vec3(0, m_fMoveSpeed * sinf(osg::PI_2 + m_vRotation._v[2]), 0)); 130 ChangePosition(osg::Vec3(m_fMoveSpeed * cosf(osg::PI_2 + m_vRotation._v[2]),0,0)); 131 132 return true; 133 } 134 135 // 后退 136 if (ea.getKey() == 0xFF54 || ea.getKey() == 0x53 || ea.getKey() == 0x73) 137 { 138 ChangePosition(osg::Vec3(0, -m_fMoveSpeed * sinf(osg::PI_2 + m_vRotation._v[2]), 0)); 139 ChangePosition(osg::Vec3(-m_fMoveSpeed * cosf(osg::PI_2 + m_vRotation._v[2]),0,0)); 140 141 return true; 142 } 143 144 // 向左 145 if (ea.getKey() == 0x41 || ea.getKey() == 0x61) 146 { 147 ChangePosition(osg::Vec3(0, m_fMoveSpeed * cosf(osg::PI_2 + m_vRotation._v[2]),0)); 148 ChangePosition(osg::Vec3(-m_fMoveSpeed * sinf(osg::PI_2 + m_vRotation._v[2]),0,0)); 149 150 return true; 151 } 152 153 // 向右 154 if (ea.getKey() == 0x44 || ea.getKey() == 0x64) 155 { 156 ChangePosition(osg::Vec3(0, -m_fMoveSpeed * cosf(osg::PI_2 + m_vRotation._v[2]),0)); 157 ChangePosition(osg::Vec3(m_fMoveSpeed * sinf(osg::PI_2 + m_vRotation._v[2]),0,0)); 158 159 return true; 160 } 161 162 // 向右转 163 if (ea.getKey() == 0xFF53) 164 { 165 m_vRotation._v[2] -= osg::DegreesToRadians(m_fAngle); 166 } 167 168 // 向左转 169 if (ea.getKey() == 0xFF51) 170 { 171 m_vRotation._v[2] += osg::DegreesToRadians(m_fAngle); 172 } 173 174 // 改变屏幕角度F键 175 if (ea.getKey() == 0x46 || ea.getKey() == 0x66) 176 { 177 m_fAngle -= 0.2; 178 179 return true; 180 } 181 182 //G键 183 if (ea.getKey() == 0x47 || ea.getKey() == 0x66) 184 { 185 m_fAngle += 0.2; 186 187 return true; 188 } 189 190 return true; 191 } 192 case(osgGA::GUIEventAdapter::PUSH): 193 194 if (ea.getButton() == 1) 195 { 196 m_fpushX = mouseX; 197 m_fpushY = mouseY; 198 199 m_bLeftButtonDown = true; 200 } 201 202 return true; 203 204 // 拖动 205 case(osgGA::GUIEventAdapter::DRAG): 206 207 if (m_bLeftButtonDown) 208 { 209 m_vRotation._v[2] -= osg::DegreesToRadians(m_fAngle * (mouseX - m_fpushX)) / 200; 210 m_vRotation._v[0] += osg::DegreesToRadians(1.1 * (mouseY - m_fpushY)) / 200; 211 212 if (m_vRotation._v[0] >= 3.14) 213 { 214 m_vRotation._v[0] = 3.14; 215 } 216 217 if (m_vRotation._v[0] <= 0) 218 { 219 m_vRotation._v[0] = 0; 220 } 221 } 222 223 return false; 224 225 // 鼠标释放 226 case(osgGA::GUIEventAdapter::RELEASE): 227 228 if (ea.getButton() == 1) 229 { 230 m_bLeftButtonDown = false; 231 } 232 233 return false; 234 235 default: 236 237 return false; 238 } 239 240 } 241 242 // 位置变换函数 243 void TravelManipulator::ChangePosition(osg::Vec3 &delta) 244 { 245 // 碰撞检测 246 if (m_bPeng) 247 { 248 // 得到新的位置 249 osg::Vec3 newPos1 = m_vPosition + delta; 250 251 osgUtil::IntersectVisitor ivXY; 252 253 // 根据新的位置得到两条线段检测 254 osg::ref_ptr<osg::LineSegment>lineXY = new osg::LineSegment(newPos1, m_vPosition); 255 256 osg::ref_ptr<osg::LineSegment>lineZ = new osg::LineSegment(newPos1 + osg::Vec3(0.0f, 0.0f, 10.0f), newPos1 - osg::Vec3(0.0f, 0.0f, -10.0f)); 257 258 ivXY.addLineSegment(lineZ.get()); 259 ivXY.addLineSegment(lineXY.get()); 260 261 // 结构交集检测 262 m_pHostViewer->getSceneData()->accept(ivXY); 263 264 // 如果没有碰撞 265 if (!ivXY.hits()) 266 { 267 m_vPosition += delta; 268 } 269 270 } 271 else 272 { 273 m_vPosition += delta; 274 } 275 } 276 277 // 设置速度 278 void TravelManipulator::setSpeed(float &sp) 279 { 280 m_fMoveSpeed = sp; 281 } 282 283 // 获得当前速度 284 float TravelManipulator::getSpeed() 285 { 286 return m_fMoveSpeed; 287 } 288 289 // 设置起始的位置 290 void TravelManipulator::SetPosition(osg::Vec3 &position) 291 { 292 m_vPosition = position; 293 } 294 295 // 得到当前所在位置 296 osg::Vec3 TravelManipulator::GetPosition() 297 { 298 return m_vPosition; 299 }
标签:
原文地址:http://www.cnblogs.com/Vae1990Silence/p/5782175.html