鼠标操纵视图
navigate是指通过操作鼠标,或者3D鼠标,触摸屏等实现对相机的操纵,包括Zooming, Panning, Rotating和Orbiting这几类。这里要求您安装manipulator库,并且在程序中添加头文件cilmanipulator.h。
在manipulator库中定义了类NavigationManipulator。它包含了几种鼠标操作函数,通过这些操作,可以操控相机的位置、朝向和远近。
auto navigation = std::make_shared<NavigationManipulator>(camera, windowSize, boundingBox);
| Navigating函数 | 描述 |
|---|---|
| mouseDown(coord, button, modifier) | 记录下鼠标被按下时光标的位置和按键类型,button可取值Left,Right,Middle, modifier可取值Shift,Ctrl,Alt |
| mouseMove(coord, button, modifier) | 当button值为Left,执行rotating;当button值为Middle,执行panning;当button值为Right时,执行rolling |
| mouseUp(coord, button, modifier) | 完成操作 |
| mouseWheel(coord, modifier, up) | 执行zooming |
您可以为定义回调函数。程序中每次执行了相机操纵(orbiting, panning等)之后,会执行该回调函数.
navigation->bind("triggered", [&](MouseAction* action) -> void {
renderer->render(scene);
widget->update();
});
下面给出一个案例,应用了上面所有的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);
在OpenGLWidget类中,我们定义了一系列鼠标事件MouseEvent,它可以用来保存在窗口中使用鼠标的一系列行为,那么我们可以利用这些鼠标事件,调用navigation提供的接口。
在程序的最开始,我们就定义了一个OpenGLWidget类对象widget,OpenGLWidget类的定义在/common/glfw/openglwidget.h文件中,所以您需要在程序开头引入cilglfw.h头文件。
widget->onMouseDown = [&](MouseEvent* event) -> void {
auto button = getButton(event->button);
auto modifier = getModifier(event->modifier);
navigation->mouseDown(ivec2(event->x, event->y), button, modifier);
};
widget->onMouseDrag = [&](MouseEvent* event) -> void {
auto button = getButton(event->button);
auto modifier = getModifier(event->modifier);
navigation->mouseMove(ivec2(event->x, event->y), button, modifier);
};
widget->onMouseUp = [&](MouseEvent* event) -> void {
auto button = getButton(event->button);
auto modifier = getModifier(event->modifier);
navigation->mouseUp(ivec2(event->x, event->y), button, modifier);
};
widget->onWheel = [&](WheelEvent* event) -> void {
auto modifier = getModifier(event->modifier);
navigation->mouseWheel(ivec2(event->x, event->y), modifier, event->up);
};
下面的动图中,给出了鼠标操作的效果:
