生活随笔
收集整理的這篇文章主要介紹了
OSG 之学习五:OSG 漫游
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
文章目錄
- 說明
- 1. 操作器
- 2. 碰撞檢測
- 3. 漫游實例
- 4. 制作路徑漫游
- 5. 在 MFC 中編輯路徑
- 6. 一些類參考,自行看之
說明
- OSG 入門看的,大佬繞道
- 示例來源于《OSG程序設計教程》
- 沒有此電子書的小伙伴們,我已上傳至CSDN
- 代碼錯誤之處我已改正
1. 操作器
2. 碰撞檢測
3. 漫游實例
#include <osgDB/ReadFile>
#include <osgViewer/Viewer>
#include <osg/Node>
#include "South.h"void main() {osgViewer
::Viewer viewer
;viewer
.setSceneData(osgDB
::readNodeFile("ceep.ive"));viewer
.setCameraManipulator(new
CSouth());viewer
.realize();viewer
.run();
}
#pragma once#include <osgViewer/Viewer>
#include <osgGA/CameraManipulator>
#include <osgUtil/IntersectVisitor>
#include <osg/LineSegment>class CSouth
: public osgGA
::CameraManipulator
{
public
:CSouth(void);~CSouth(void);private
:osg
::ref_ptr
<osg
::Node
> m_node
;unsigned int m_nID
;float m_fMoveSpeed
;osg
::Vec3 m_vPosition
;osg
::Vec3 m_vRotation
;bool m_bLeftButtonDown
;float m_fpushX
;bool m_bPeng
;float m_fpushY
;public
:void setPeng(bool peng
);bool
getPeng();void setFpeng();virtual
void setNode(osg
::Node
*);virtual
void setByMatrix(const osg
::Matrixd
&matrix
); virtual
void setByInverseMatrix(const osg
::Matrixd
&matrix
);virtual osg
::Matrixd
getMatrix(void) const; virtual osg
::Matrixd
getInverseMatrix(void)const; virtual bool
handle(const osgGA
::GUIEventAdapter
&ea
, osgGA
::GUIActionAdapter
&us
);float m_fAngle
;void ChangePosition(osg
::Vec3
&delta
);float getSpeed();void setSpeed(float);void SetPosition(osg
::Vec3
&position
);void SetPosition(double *);osg
::Vec3
GetPosition();void computeHomePosition();
};
#include "South.h"
CSouth
::CSouth(void) :m_fMoveSpeed(1.5f) , m_bLeftButtonDown(false
) , m_fpushX(0) , m_fAngle(2.5) , m_bPeng(false
) , m_fpushY(0) { m_vPosition
= osg
::Vec3(0.0f, 0.0f, 5.0f);m_vRotation
= osg
::Vec3(osg
::PI_2
, 0.0f, 0.0f);
}CSouth
::~CSouth(void) {}void CSouth
::setByMatrix(const osg
::Matrixd
&matrix
) {}void CSouth
::setByInverseMatrix(const osg
::Matrixd
&matrix
) {}
osg
::Matrixd CSouth
::getMatrix(void) const {osg
::Matrixd mat
;mat
.makeRotate(m_vRotation
._v
[0], osg
::Vec3(1.0f, 0.0f, 0.0f),m_vRotation
._v
[1], osg
::Vec3(0.0f, 1.0f, 0.0f),m_vRotation
._v
[2], osg
::Vec3(0.0f, 0.0f, 1.0f));return mat
* osg
::Matrixd
::translate(m_vPosition
);
}
osg
::Matrixd CSouth
::getInverseMatrix(void) const {osg
::Matrixd mat
;mat
.makeRotate(m_vRotation
._v
[0], osg
::Vec3(1.0f, 0.0f, 0.0f),m_vRotation
._v
[1], osg
::Vec3(0.0f, 1.0f, 0.0f),m_vRotation
._v
[2], osg
::Vec3(0.0f, 0.0f, 1.0f));return osg
::Matrixd
::inverse(mat
* osg
::Matrixd
::translate(m_vPosition
));
}
bool CSouth
::handle(const osgGA
::GUIEventAdapter
&ea
, osgGA
::GUIActionAdapter
&us
) {float mouseX
= ea
.getX();float mouseY
= ea
.getY();switch (ea
.getEventType()) {case osgGA
::GUIEventAdapter
::KEYDOWN
:if (ea
.getKey() == 0x20) {us
.requestRedraw();us
.requestContinuousUpdate(false
);return true
;}if (ea
.getKey() == 0xFF50) {ChangePosition(osg
::Vec3(0, 0, m_fMoveSpeed
));return true
;}if (ea
.getKey() == 0xFF57) {ChangePosition(osg
::Vec3(0, 0, -m_fMoveSpeed
));return true
;}if (ea
.getKey() == 0x2B) {m_fMoveSpeed
+= 1.0f;return true
;}if (ea
.getKey() == 0x2D) {m_fMoveSpeed
-= 1.0f;if (m_fMoveSpeed
< 1.0f) {m_fMoveSpeed
= 1.0f;}return true
;}if (ea
.getKey() == 0xFF52 || ea
.getKey() == 0x57 || ea
.getKey() == 0x77) {ChangePosition(osg
::Vec3(0, m_fMoveSpeed
* sinf(osg
::PI_2
+ m_vRotation
._v
[2]), 0));ChangePosition(osg
::Vec3(m_fMoveSpeed
* cosf(osg
::PI_2
+ m_vRotation
._v
[2]), 0, 0));return true
;}if (ea
.getKey() == 0xFF54 || ea
.getKey() == 0x53 || ea
.getKey() == 0x73) {ChangePosition(osg
::Vec3(0, -m_fMoveSpeed
* sinf(osg
::PI_2
+ m_vRotation
._v
[2]), 0));ChangePosition(osg
::Vec3(-m_fMoveSpeed
* cosf(osg
::PI_2
+ m_vRotation
._v
[2]), 0, 0));return true
;}if (ea
.getKey() == 0x41 || ea
.getKey() == 0x61) {ChangePosition(osg
::Vec3(0, m_fMoveSpeed
* cosf(osg
::PI_2
+ m_vRotation
._v
[2]), 0));ChangePosition(osg
::Vec3(-m_fMoveSpeed
* sinf(osg
::PI_2
+ m_vRotation
._v
[2]), 0, 0));return true
;}if (ea
.getKey() == 0x44 || ea
.getKey() == 0x64) {ChangePosition(osg
::Vec3(0, -m_fMoveSpeed
* cosf(osg
::PI_2
+ m_vRotation
._v
[2]), 0));ChangePosition(osg
::Vec3(m_fMoveSpeed
* sinf(osg
::PI_2
+ m_vRotation
._v
[2]), 0, 0));return true
;}if (ea
.getKey() == 0xFF53) {m_vRotation
._v
[2] -= osg
::DegreesToRadians(m_fAngle
);}if (ea
.getKey() == 0xFF51) {m_vRotation
._v
[2] += osg
::DegreesToRadians(m_fAngle
);}if (ea
.getKey() == 0x46 || ea
.getKey() == 0x66) {computeHomePosition();m_fAngle
-= 0.2;return true
;}if (ea
.getKey() == 0x47 || ea
.getKey() == 0x67) {m_fAngle
+= 0.2;return true
;}return false
;case osgGA
::GUIEventAdapter
::PUSH
:if (ea
.getButton() == 1) {m_fpushX
= mouseX
;m_fpushY
= mouseY
;m_bLeftButtonDown
= true
;}return false
;case osgGA
::GUIEventAdapter
::DRAG
:if (m_bLeftButtonDown
) {m_vRotation
._v
[2] -= osg
::DegreesToRadians(m_fAngle
* (mouseX
- m_fpushX
));m_vRotation
._v
[0] += osg
::DegreesToRadians(1.1 * (mouseY
- m_fpushY
)); if (m_vRotation
._v
[0] >= 3.14)m_vRotation
._v
[0] = 3.14;if (m_vRotation
._v
[0] <= 0)m_vRotation
._v
[0] = 0;}return false
;case (osgGA
::GUIEventAdapter
::RELEASE
) :if (ea
.getButton() == 1) {m_bLeftButtonDown
= false
;}return false
;default:return false
;}
}
void CSouth
::ChangePosition(osg
::Vec3
&delta
) {if (m_bPeng
) {osg
::Vec3 newPos
= m_vPosition
+ delta
;osgUtil
::IntersectVisitor iv
;osg
::ref_ptr
<osg
::LineSegment
> line
= new osg
::LineSegment(newPos
, m_vPosition
);osg
::ref_ptr
<osg
::LineSegment
> lineZ
= new osg
::LineSegment(newPos
+ osg
::Vec3(0.0f, 0.0f, m_fMoveSpeed
), newPos
- osg
::Vec3(0.0f, 0.0f, m_fMoveSpeed
));iv
.addLineSegment(lineZ
.get());iv
.addLineSegment(line
.get());m_node
->accept(iv
);if (!iv
.hits()) {m_vPosition
+= delta
;}} else m_vPosition
+= delta
;
}
float CSouth
::getSpeed() {return m_fMoveSpeed
;
}
void CSouth
::setSpeed(float sp
) {m_fMoveSpeed
= sp
;
}
void CSouth
::SetPosition(osg
::Vec3
&position
) {m_vPosition
= position
;
}void CSouth
::SetPosition(double *position
) {m_vPosition
._v
[0] = position
[0];m_vPosition
._v
[1] = position
[1];m_vPosition
._v
[2] = position
[2];
}
osg
::Vec3 CSouth
::GetPosition() {return m_vPosition
;
}
void CSouth
::setNode(osg
::Node
*node
) {m_node
= node
;
}
void CSouth
::computeHomePosition() {if (m_node
.get()) {const osg
::BoundingSphere
&boundingSphere
= m_node
->getBound();osg
::Vec3 bp
= boundingSphere
._center
;SetPosition(bp
);}
}
void CSouth
::setPeng(bool peng
) {m_bPeng
= peng
;
}
bool CSouth
::getPeng() {return m_bPeng
;
}
void CSouth
::setFpeng() {m_bPeng
= !m_bPeng
;
}
- 注意點一:新版本中 #include <osgGA/MatrixManipulator> 已經變成 #include <osgGA/CameraManipulator>
參考博客:OSG學習之示例遇到的問題三無法打開文件osgGA/MatrixManipulator錯誤
- 注意點二:ceep.ive 數據需要自行下載,見下面鏈接
資源:ceep.ive 模型
4. 制作路徑漫游
#include <osgDB/ReadFile>
#include <osgViewer/Viewer>
#include <osg/Node>
#include <osgGA/AnimationPathManipulator>void main() {osgViewer
::Viewer viewer
;viewer
.setSceneData(osgDB
::readNodeFile("glider.osg"));osg
::ref_ptr
<osgGA
::AnimationPathManipulator
> amp
= new osgGA
::AnimationPathManipulator("glider.path");viewer
.setCameraManipulator(amp
.get());viewer
.realize();viewer
.run();
}
5. 在 MFC 中編輯路徑
6. 一些類參考,自行看之
總結
以上是生活随笔為你收集整理的OSG 之学习五:OSG 漫游的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。