跳到主要内容

鼠标操纵视图

navigation类实现了通过操作鼠标,或者3D鼠标,触摸屏等操纵相机,包括Zooming, Panning, Rotating和Orbiting这几类。这里要求您安装Camera库,并且在程序中添加头文件cilcamera.h

在Camera库中定义了类Navigation,您可以通过下面的方式声明一个指向navigation类型的智能指针对象。它包含了几种鼠标操作函数,通过这些操作,可以操控相机的位置、朝向和远近。

auto navigation = std::make_shared<Navigation>(camera, windowSize, boundingBox);
Navigating函数描述
mouseDown(position, button)记录下鼠标被按下时光标的位置和按键类型,button是一个整型数据,可取值0,1,2
mouseDrag(position)当button值为0,执行orbiting;当button值为1,执行panning;当button值为2时,执行rotating
mouseUp(position)将button值置为-1
wheel(position, direction)执行zooming
onUpdate您可以为onUpdate定义回调函数。程序中每次执行了相机操纵(orbiting, panning等)之后,会执行onUpdate的回调函数.

下面给出一个案例,应用了上面所有的Navigation函数,您执行这段程序后,就可以在窗口中使用鼠标自由操纵相机了。

首先您在视图区中创建一个渲染单元,首先您可以通过来自于geometry库中的_teapot接口,创建一个我们提供的几何teapot。然后使用材料接口_phoneMaterial,创建一个光照材料,与teapot共同组成了这个案例的渲染单元primitive

    auto geometry = _teapot();
auto material = _phong(_clr3(0.5, 0.6, 0.8));
auto primitive = _primitive(geometry, material);

然后,我们组成渲染场景,详细说就是构造node,camera, pass和scene。我们使用home函数,自动将摄像机调整到一个合适的视角。


auto node = _node({ primitive });
auto camera = _camera();
auto pass = _pass(node, background, camera);
auto scene = _scene({ pass });

auto boundingBox = geometry->boundingBox;
*camera->orbitPoint = boundingBox->center();
home(camera, *boundingBox, *background->size);

在window.cpp文件中,我们定义了一系列鼠标事件MouseEvent,它可以用来保存在窗口中使用鼠标的一系列行为,那么我们可以利用这些鼠标事件,与navigation对象的一系列函数共同参与到GLWindow的执行函数中。

在程序的最开始,我们就定义了一个GLWindow类对象window,GLWindow类的定义在/common/window.cpp文件中,所以您需要在程序开头引入window.h头文件。

最后,我们为以下window函数定义它的实际执行程序。

    window.onMouseDown = [&](MouseEvent* event) -> void {
int button = 0;
switch (event->button)
{
case MouseButton::Left: button = 0; break;
case MouseButton::Middle: button = 1; break;
case MouseButton::Right: button = 2; break;
default: break;
}
// 执行mouseDown,记录下光标的位置,和button的值
navigation->mouseDown(vec2(event->x, event->y), button);
};

window.onMouseDrag = [&](MouseEvent* event) -> void {
// 执行mouseDrag,不同的button值对应不同的action,0:orbing, 1:panning, 2:rotating.
navigation->mouseDrag(vec2(event->x, event->y));
};

window.onMouseUp = [&](MouseEvent* event) -> void {
navigation->mouseUp(vec2(event->x, event->y));
};

window.onWheel = [&](WheelEvent* event) -> void {
navigation->wheel(vec2(event->x, event->y), event->direction == Direction::Down);
};

下面的动图中,给出了鼠标操作的效果:

navigation