游戏开发论坛

 找回密码
 立即注册
搜索
查看: 2218|回复: 1

3D模型下的鼠标拣选和射线与圆的相交算法我错在那里?

[复制链接]

8

主题

44

帖子

115

积分

注册会员

Rank: 2

积分
115
发表于 2011-10-14 18:35:00 | 显示全部楼层 |阅读模式
定义如下结构:

struct ray

{

    D3DXVECTOR3 origin;//射线起点

    D3DXVECTOR3 derction;//射线方向   

};




//---------------------------------------------------------------------------------
// 根据当前鼠标的位置(x,y)计算在视坐标中的拾取光线
//---------------------------------------------------------------------------------
        Ray CalcPickingRay(LPDIRECT3DDEVICE9 s_pDevice,int x, int y)
{
        float px = 0.0f;
        float py = 0.0f;
        D3DVIEWPORT9 vp;
        s_pDevice->GetViewport(&vp);//得到视口大小
        D3DXMATRIX proj;
        s_pDevice->GetTransform(D3DTS_PROJECTION, &proj);//转换
//计算拾取射线
        px = ((( 2.0f*x) / vp.Width) - 1.0f) / proj(0, 0);
        py = (((-2.0f*y) / vp.Height) + 1.0f) / proj(1, 1);
        Ray ray;
        ray.origin = D3DXVECTOR3(0.0f, 0.0f, 0.0f);//3维空间中的向量
        ray.direction = D3DXVECTOR3(px, py, 1.0f);
        return ray;
}

//---------------------------------------------------------------------------------
// 对拾取光线进行从视坐标到世界坐标的转换
//---------------------------------------------------------------------------------
void TransformRay(Ray* ray, D3DXMATRIX* T)
{
        // 对原点进行变换
        D3DXVec3TransformCoord(&ray->origin, &ray->origin, T);
        // 对方向向量进行变换
        D3DXVec3TransformNormal(&ray->direction, &ray->direction, T);
    //返回3D向量的规格化向量
        D3DXVec3Normalize(&ray->direction, &ray->direction);
}
//---------------------------------------------------------------------------------
// 判断鼠标当前位置pt对应的拾取光线是否与某个物体的包围球*pSphere相交
//---------------------------------------------------------------------------------

  void PickSphere(LPDIRECT3DDEVICE9 s_pDevice,const POINT pt)
{
        Ray ray = CalcPickingRay(s_pDevice , pt.x, pt.y);// 根据当前鼠标的位置(x,y)计算在视坐标中的拾取光线
        D3DXMATRIX view;
        s_pDevice->GetTransform(D3DTS_VIEW, &view);//转换
        D3DXMATRIX viewInverse;
        D3DXMatrixInverse(&viewInverse, NULL, &view);//D3DXMatrixInverse通常用来求视图矩阵的逆阵
        TransformRay(&ray, &viewInverse);// 对拾取光线进行从视坐标到世界坐标的转换
    CUnit::_origin=ray.origin;//把结果传给静态变量目的是所有类对象共存结果因为射线每频只需计算一次
    CUnit::_direction=ray.direction;//把结果传给静态变量...........................................
       
}

//---------------------------------------------------------------------------------
// 判断拾取光线*pRay是否与某个物体的包围球*pSphere相交
//---------------------------------------------------------------------------------

bool RaySphereIntTest()
{
        D3DXVECTOR3 v = CUnit::_origin - m_vPos;//3维空间中的向量

        float b = 2.0f * D3DXVec3Dot(&CUnit::_direction, &v);
        float c = D3DXVec3Dot(&v, &v) - (500*500);//
        // 计算判别式的值
        float discriminant = (b * b) - (4.0f * c);

        if( discriminant < 0.0f )
        {
                return false;
        }

        discriminant = sqrtf(discriminant);

        float s0 = (-b + discriminant) / 2.0f;
        float s1 = (-b - discriminant) / 2.0f;

        // 如果某个根 >= 0, 说明光线与包围球相交
        if( s0 >= 0.0f || s1 >= 0.0f )
        {
                return true;
        }
        else
        {
                return false;
        }
}

执行结果我点模型没有反应,但是当我点到屏幕的某个位置模型就有反应了。

[em17]

0

主题

1

帖子

0

积分

新手上路

Rank: 1

积分
0
发表于 2011-10-21 02:20:00 | 显示全部楼层

Re:3D模型下的鼠标拣选和射线与圆的相交算法我错在那里?

这应该是龙书上的东西,就没怎么仔细看代码,但估计你的错应该是void TransformRay(Ray* ray, D3DXMATRIX* T)在调用的时候你的参数传错了,你的T传的是什么矩阵?
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

作品发布|文章投稿|广告合作|关于本站|游戏开发论坛 ( 闽ICP备17032699号-3 )

GMT+8, 2025-6-8 23:17

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表