鼠标操纵视图
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);
};
下面的动图中,给出了鼠标操作的效果:
