# 游戏开发基础(十五)

645人阅读 评论(0)

1 给定所点击的屏幕点s，求出它在投影窗口中的对应点p
2 计算拾取射线，即自坐标原点发出且通过点p的那条射线
3 将拾取射线和物体模型变换至同一坐标系中
4 进行物体/射线的相交判断，相交物体即为用户所拾取的屏幕对象

2/Width     0         0         0
0       -Height/2     0         0
[ 0           0       MaxZ-MinZ   0   ]
X+Width/2   Y+Height/2   MinZ       1

sx = px(Width/2) + X + Width/2
sy = py(Height/2) + Y + Height/2

px = (2sx -2X-Width)/Width
py = (-2sy + 2Y + Height)/Height

px = 2*sx/Width -1
py = 2*sy/Width +1
pz = 1

px = (2x/viewporWidth -1)(1/P00)
py = (2y/viewporHeight +1)(1/P11)
pz = 1

u = p-p0 = (px,py,1) - (0,0,0) = p

d3d::Ray CalcPickingRay(int x,int y)
{
float px = 0.0f;
float py = 0.0f;

D3DVIEWPORT9 vp;
Device->GetViewport(&vp);

D3DXMATRIX proj;
Device->GetTransfrom(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);

d3d::Ray ray;
ray._origin    = D3DXVECTOR3(0.0f,0.0f,0.0f);
ray._direction = D3DXVECTOR3(px,py,1.0f);

return ray;
}

Ray结构:
struct Ray
{
D3DXVECTOR3 _origin;
D3DXVECTOR3 _direction;
};

void TransformRay(d3d::Ray* ray,D3DXMATRIX * T)
{
//transform the ray's origin ,w = 1
D3DXVec3TransformCoord(
&ray->_origin,
&ray->_origin,
T);
// transfrom the ray's direction ,w = 0
D3DXVec3TransformNormal(
&ray->_direction,
&ray->_direction,
T);
// normalize the direction
D3DXVec3Normalize(&ray->_direction,&ray->_direction);
}

D3DXVec3TransformCoord和D3DXVec3TransformNormal均以3D向量作为其参数，注意，D3DXVec3TransformCoord参数第4个分量应理解为w = 1,而是用D3DXVec3TransformNormal时，参数第4个分量应理解为w = 0 ，所以，用D3DXVec3TransformCoord来实现点变换，用D3DXVec3TransformNormal实现向量变换

|| p -c || - r = 0

||p(t) -c|| -r = 0
||p0 + tu -c || -r = 0

At*t +Bt +C = 0;

t0 = (-B +squrt(B*B-4AC))/2A, t1 = (-B -squrt(B*B-4AC))/2A

bool RaySphereIntTest(d3d::Ray* ray,d3d::BoundingSphere* sphere)
{

D3DXVECTOR3 v = ray ->_origin-sphere->_center;
float b = 2.0f * D3DXVec3Dot(&ray->_direction,&v);

// find the discriminant
float discriminant = (b*b) - (4.0f*c);

// test for imaginary number
float discriminant = (b*b) - (4.0f*c);

// test for imaginary number
if(discriminant < 0.0f)
return false ;

discriminant = sqrtf(discriminant )

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

//if a solution is >= 0,then we intersected the sphere
if (s0 >= 0.0f || s1 >= 0.0f)
return true;

return false;
}

struct BoundingSphere
{
BoundingSphere();
D3DXVECTOR3 _center;
};

0
0

* 以上用户言论只代表其个人观点，不代表CSDN网站的观点或立场
个人资料
• 访问：215685次
• 积分：2795
• 等级：
• 排名：第13282名
• 原创：79篇
• 转载：0篇
• 译文：0篇
• 评论：10条
最新评论