拾取摄线

所谓拾取,是根据你在屏幕上的一个点与你空间中的mesh是否相交。

而你的空间是三维的,屏幕上的点是二维的。这就需要一个逆投影的过程,也就涉及到了视口变换矩阵



三维空间中的点p(Px, Py, Pz)通过p视口变换后为s(Sx, Sy)

其中 Sx = Px * Width / 2 + X + Width / 2

         Sy = -Py * Height / 2 + Y + Height / 2;

而z的话不作为二维图像的一部分。

反过来也就可以得到

Px = (2 * Sx - 2 * X - Width) / Width

Py = (-2 * Sy + 2 * Y + Height) / Height;

而一般情况下X,Y的值为0;

Px = 2 * Sx / Width -1

Py = -2 * Sy / Height + 1

Pz = 1;

这是因为投影窗口与z = 1重合;

依国际贯例上代码:

Ray CalClickRay(int x, int y)
{
	float rx = 0.0f;
	float ry = 0.0f;

	D3DVIEWPORT9 view;
	m_device->GetViewport(&view);

	D3DXMATRIX proj;
	m_device->GetTransform(D3DTS_PROJECTION, &proj);

	rx = ((2.0f * x) / view.Width - 1.0f) * (1.0f / proj(0,0));
	ry = ((-2.0f * y) / view.Height + 1.0f) * (1.0f / proj(1, 1));

	Ray r;
	r.origin = D3DXVECTOR3(0.0f, 0.0f, 0.0f);
	r.direction = D3DXVECTOR3(rx, ry, 1.0f);

	return r;
}

其中Ray的定义为

struct Ray 
{
	D3DXVECTOR3 origin;
	D3DXVECTOR3 direction;
};

经上叙步骤后得到的摄线是在观察坐标系中的,仍需要进一步转换

void TranformRay(Ray* ray, D3DXMATRIX* T)
{
	D3DXVec3TransformCoord(&ray->origin, &ray->origin, T);
	D3DXVec3TransformNormal(&ray->direction, &ray->direction, T);

	D3DXVec3Normalize(&ray->direction, &ray->direction);
}

其中矩阵T为观察矩阵的逆矩阵。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值