没有合适的资源?快使用搜索试试~ 我知道了~
Ogre求射线到面的交点函数分析 我收藏很好的教程
4星 · 超过85%的资源 需积分: 13 22 下载量 176 浏览量
2010-12-23
14:45:08
上传
评论
收藏 404KB DOC 举报
温馨提示
试读
64页
学习ogre非常好的资料,本人从网上搜集下来,特贡献出来供大家分享,此文章对我的学习帮助很大,希望对大家有所帮助.
资源推荐
资源详情
资源评论
Ogre 求射线到面的交点函数分析 收藏
昨天,看了 Ogre 的代码,关于取射线到面的交点坐标的函数,研究了半天,怪自己立体几
何没学好啊
代码如下:
//-----------------------------------------------------------------------
std::pair<bool, Real> Math::intersects(const Ray& ray, const Plane& plane)
{
Real denom = plane.normal.dotProduct(ray.getDirection());
if (Math::Abs(denom) < std::numeric_limits<Real>::epsilon())
{
// Parallel
return std::pair<bool, Real>(false, 0);
}
else
{
Real nom = plane.normal.dotProduct(ray.getOrigin()) + plane.d;
Real t = -(nom/denom);
return std::pair<bool, Real>(t >= 0, t);
}
}
//-----------------------------------------------------------------------
分析如下:
Plane.normal 是取平面的法向量
ray.getDirection()是取射线的方向向量
函数 dotProduct()是用来做向量的点乘,函数结构如下:
inline Real dotProduct(const Vector3& vec) const
{
return x * vec.x + y * vec.y + z * vec.z;
}
把返回的点乘的值赋予 demon,通过这个值可以来判断射线与平面是否平行。
//-----------------------------------------邪恶的分割线------------------------------------------
数学原理:两个向量相乘 a*b = |a|*|b|cosθ , 因为 a 和 b 向量都是方向向量,标量值不为
0,θ 就是两个方向向量之间的角度,当 cosθ 趋近于 0 时,θ 角度趋近于 90°,由此可以说
明 a 和 b 垂直。(高中的知识啊。。。)
//-----------------------------------------邪恶的分割线------------------------------------------
函数中把点成的值在用 Math::Abs(denom) 其实就是 fabs()函数,取其绝对值,在跟
std::numeric_limits<Real>::epsilon()比较,这里的 epslion 是一个趋近于 0 的数,形如:
#define FLT_EPSILON 1.192092896e-07F /* smallest such that 1.0+FLT_EPSILON != 1.0
*/
当 demon 的值比其还小的时候,就可以近似的认为两个向量点乘的值为 0,即两个向量垂
直。
由于两个都是方向向量,所以,射线和平面就平行了。返回一个 bool 类型为 false 的值,和
一个 real 值为 0(也就是下面说的 t 值)。
//-----------------------------------------邪恶的分割线------------------------------------------
下面就是重点部分了,如果不平行,先恶补一下数学的知识
一条射线可以表示为:p(t) = p1+tu ;其中,p1 为起点坐标,u 为射线的方向向量,t 为参数。
如果 t = 0,得到的是起点的坐标。
一个平面可以表示为:np+d = 0;其中,n 为平面的法向量,p 为平面上任意一点,d 为参
数。
如果射线与平面相交,把两个表达式合并,即:n*(p1+tu)+d = 0;经过变化以后得:t = -
((d+n*p1)/(nu))
//-----------------------------------------邪恶的分割线------------------------------------------
现在,在把公式和代码比较就很好理解了。
Real nom = plane.normal.dotProduct(ray.getOrigin()) + plane.d; // 求 的 就 是 d+n*p1 的 值 ,
ray.getOrigin()得到的就是起点的坐标,plane.d 得到的就是平面的 d 值。
Real t = -(nom/denom); //denom 上 面 已 将 求 过 了 , 就 是 n*u, 此 代 码 就 实 现 了 t =
-((d+n*p1)/(nu))
函数返回 bool 值,且 t 要大于等于 0 为真,如果 t 小于 0,就得到了一条三维空间的直线(就
不是射线了 ) ,然后在返回 t 值。
然后利用 p(t) = p1+tu 就可以很容易的求出交点坐标了
经过这次教训,要好好恶补一下数学了。
本 文 来 自 CSDN 博 客 , 转 载 请 标 明 出 处 : http://blog.csdn.net/pizi0475/archive/
2010/03/25/5414544.aspx
射线使用-碰撞检测 收藏
射线使用-碰撞检测
我们首先实现对鼠标右键的响应是他能够自由查看
然后实现摄像机不能穿越地面
最后单击左键增加实体,并能在单机状态下移动实体
首先,一如既往,提供程序运行的代码框架
#include <CEGUI/CEGUISystem.h>
#include <CEGUI/CEGUISchemeManager.h>
#include <OgreCEGUIRenderer.h>
#include "ExampleApplication.h"
class MouseQueryListener : public ExampleFrameListener, public OIS::MouseListener
{
public:
MouseQueryListener(RenderWindow* win, Camera* cam, SceneManager *sceneManager,
CEGUI::Renderer *renderer)
: ExampleFrameListener(win, cam, false, true), mGUIRenderer(renderer)
{
} // MouseQueryListener
~MouseQueryListener()
{
}
bool frameStarted(const FrameEvent &evt)
{
return ExampleFrameListener::frameStarted(evt);
}
bool mouseMoved(const OIS::MouseEvent &arg)
{
return true;
}
bool mousePressed(const OIS::MouseEvent &arg, OIS::MouseButtonID id)
{
return true;
}
bool mouseReleased(const OIS::MouseEvent &arg, OIS::MouseButtonID id)
{
return true;
}
protected:
RaySceneQuery *mRaySceneQuery; // The ray scene query pointer
bool mLMouseDown, mRMouseDown; // True if the mouse buttons are down
int mCount; // The number of robots on the screen
SceneManager *mSceneMgr; // A pointer to the scene manager
SceneNode *mCurrentObject; // The newly created object
CEGUI::Renderer *mGUIRenderer; // CEGUI renderer
};
class MouseQueryApplication : public ExampleApplication
{
protected:
CEGUI::OgreCEGUIRenderer *mGUIRenderer;
CEGUI::System *mGUISystem; // cegui system
public:
MouseQueryApplication()
{
}
~MouseQueryApplication()
{
}
protected:
void chooseSceneManager(void)
{
// Use the terrain scene manager.
mSceneMgr = mRoot->createSceneManager(ST_EXTERIOR_CLOSE);
}
void createScene(void)
{
}
void createFrameListener(void)
{
mFrameListener = new MouseQueryListener(mWindow, mCamera, mSceneMgr,
mGUIRenderer);
mFrameListener->showDebugOverlay(true);
mRoot->addFrameListener(mFrameListener);
}
};
#if OGRE_PLATFORM == PLATFORM_WIN32 || OGRE_PLATFORM ==
OGRE_PLATFORM_WIN32
#define WIN32_LEAN_AND_MEAN
#include "windows.h"
INT WINAPI WinMain(HINSTANCE hInst, HINSTANCE, LPSTR strCmdLine, INT)
#else
int main(int argc, char **argv)
#endif
{
// Create application object
MouseQueryApplication app;
try {
app.go();
} catch(Exception& e) {
#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
MessageBox(NULL, e.getFullDescription().c_str(), "An exception has occurred!", MB_OK |
MB_ICONERROR | MB_TASKMODAL);
#else
fprintf(stderr, "An exception has occurred: %s\n",
e.getFullDescription().c_str());
剩余63页未读,继续阅读
资源评论
- wunan198908142013-03-11还不错,对于Ogre源码的分析
- JJLee10232013-06-18不错,讲到一些原理性的东西
- 潇林2012-07-01是有帮助,但是不是很大,而且分数弄的太多了,,
BAYI132337
- 粉丝: 35
- 资源: 16
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功