MVE 中获取鼠标点击位置在三维场景中坐标
前言
项目基于MVE实现三维场景显示,记录下在MVE中获取鼠标点击位置在三维场景中的坐标方法
二、使用步骤
1.修改Event 添加自定义鼠标操作
代码如下(示例):
/** Mouse event. */
struct MouseEvent
{
MouseEventType type; ///< Type of event
MouseButton button; ///< Button that caused the event
int button_mask; ///< Button state when event was generated
int x; ///< Mouse X-position
int y; ///< Mouse Y-position
int iProc;//<-1 :nothing 0:save Point 1: > add
};
2.AddinManager::mouse_event处理自定义鼠标操作
代码如下(示例):
bool
AddinManager::mouse_event (const ogl::MouseEvent &event)
{
for (std::size_t i = 0; i < this->addins.size(); ++i)
if (this->addins[i]->mouse_event(event))
return true;
if ((event.iProc == 3 || event.iProc == 2 || event.iProc == 4 || event.iProc == 5 || event.iProc == 6) && event.type == ogl::MOUSE_EVENT_PRESS && event.button == ogl::MOUSE_BUTTON_LEFT )
{
pickClickPoint(event.x, event.y, event.iProc);
}
return ogl::CameraTrackballContext::mouse_event(event);
}
3.位置获取
代码如下(示例):
/* Try to find a valid depth value in a spiral around the click point. */
float depth = 1.0f;
{
/* Patchsize should be odd and larger than one. */
int const patch_size = 9;
int const patch_halfsize = patch_size / 2;
int const screen_width = this->camera.width;
int const screen_height = this->camera.height;
int const center_x = x;
int const center_y = y;
int dx = 1;
int dy = 0;
int radius = 0;
while (radius <= patch_halfsize)
{
if (x >= 0 && x < screen_width && y > 0 && y < screen_height)
glReadPixels(x, screen_height - y - 1, 1, 1,
GL_DEPTH_COMPONENT, GL_FLOAT, &depth);
if (depth != 1.0f)
break;
x += dx;
y += dy;
if (x > center_x + radius)
{
radius += 1;
dx = 0;
dy = -1;
}
if (y <= center_y - radius)
{
dx = -1;
dy = 0;
}
if (x <= center_x - radius)
{
dx = 0;
dy = 1;
}
if (y >= center_y + radius)
{
dx = 1;
dy = 0;
}
}
}
/* Exit if depth value is not set. */
//if (depth == 1.0f)
// return /*math::Vec3f(0.0f)*/; // TODO: Better "error" reporting
float const fx = static_cast<float>(x);
float const fy = static_cast<float>(y);
float const fw = static_cast<float>(this->camera.width);
float const fh = static_cast<float>(this->camera.height);
/* Calculate camera-to-surface distance (orthographic). */
float dist = (this->camera.z_far * this->camera.z_near)
/ ((this->camera.z_near - this->camera.z_far) * depth + this->camera.z_far);
/* Fix distance value caused by projection. */
{
/* Create point on near plane corresponding to click coords. */
math::Vec3f pnp((2.0f * fx / (fw - 1.0f) - 1.0f) * this->camera.right,
(1.0f - 2.0f * fy / (fh - 1.0f)) * this->camera.top,
this->camera.z_near);
float cosangle = pnp.normalized()[2];
dist /= cosangle;
}
/* Create a point in unit cube corresponding to the click coords. */
math::Vec3f ray(2.0f * fx / (fw - 1.0f) - 1.0f,
1.0f - 2.0f * fy / (fh - 1.0f), 0.0f);
/* Convert cube click coords to ray in camera corrds. */
ray = this->camera.inv_proj.mult(ray, 1.0f);
/* Ray to new camera center in camera coords. */
ray = ray.normalized() * dist;
/* Ray to new camera center in world coords. */
ray = this->camera.inv_view.mult(ray, 0.0f);
std::cout << "----------->ray" << ray[0] << ray[1] << ray[2] << std::endl;
math::Vec3f res= this->camera.pos + ray;
总结
MVE中有鼠标位置x.y 转换成场景坐标代码,找了好久才发现的,必须记录下!!!!!!