Dandelion 1.1.1
A light-weight 3D builder for educational usage
载入中...
搜索中...
未找到
Controller类 参考

控制器管理所有的界面组件,并处理和预览视角操作(例如旋转、缩放或者平移)相关的输入。 更多...

#include <controller.h>

Public 成员函数

void on_mouse_dragged (bool initial)
 将鼠标拖动转换为旋转视角或平移视角操作。
 
void on_picking ()
 根据鼠标点击选取场景中的物体。
 
void on_wheel_scrolled ()
 将拨动鼠标滚轮的操作转换为视角拉进或远离。
 
void on_framebuffer_resized (float width, float height)
 在缩放窗口时调整轨迹球半径、预览视角(相机)Y 方向的 FoV,并更新自身记录的窗口尺寸。
 
void process_input ()
 处理关于场景操作的输入。
 
void render (const Shader &shader)
 
 Controller (Controller &other)=delete
 
Controlleroperator= (Controller &other)=delete
 

静态 Public 成员函数

static Controllercontroller ()
 获取 Controller 类的唯一实例。
 

Public 属性

float window_width
 
float window_height
 
float toolbar_width
 

Private 成员函数

void select (SelectableType element)
 选择一个元素。
 
void unselect ()
 取消选择。
 
void render_selected_element (const Shader &shader)
 渲染当前选中的元素。
 
void render_debug_helpers (const Shader &shader)
 渲染帮助调试的元素。
 
void pick_object (Ray &ray)
 拾取物体。
 
void pick_element (Ray &ray)
 拾取半边、顶点、边或面片。
 
void select_object (Object *object)
 
void select_halfedge (const Halfedge *halfedge)
 
void select_vertex (Vertex *vertex)
 
void select_edge (Edge *edge)
 
void select_face (Face *face)
 
void select_light (Light *light)
 
void on_rotating (bool initial)
 将鼠标拖动转换为轨迹球 (Trackball) 操作,用于旋转预览视角。
 
void on_translating (bool initial)
 将鼠标拖动转换为视角平移。
 
 Controller ()
 

Private 属性

WorkingMode mode
 全局工作模式。
 
UI::DebugOptions debug_options
 
std::unique_ptr< UI::Menubarmenubar
 
std::unique_ptr< UI::Toolbartoolbar
 
std::unique_ptr< Scenescene
 
SelectableType selected_element
 当前被选中的元素。
 
std::unique_ptr< Cameramain_camera
 
std::shared_ptr< spdlog::logger > logger
 
float trackball_radius
 
GL::Mesh highlighted_element
 
GL::LineSet highlighted_halfedge
 
GL::LineSet picking_ray
 

静态 Private 属性

static constexpr float wheel_scroll_factor = 0.8f
 
static constexpr float mouse_translation_factor = 0.001f
 

详细描述

控制器管理所有的界面组件,并处理和预览视角操作(例如旋转、缩放或者平移)相关的输入。

控制器的生命周期就是整个程序 GUI 的生命周期,因此这是一个单例的类。其唯一一个实例可以通过 controller() 这个静态方法访问,访问操作是线程安全的(但访问后的修改不是)。 控制器创建并持有所有与图形界面相关的资源:

  • 界面元素(菜单栏和工具栏)
  • 场景(包含所有物体、坐标轴等)

界面元素本身不存储场景,也不保存指向场景的引用等。控制器在每一帧将场景的引用传递给 Toolbar::renderMenubar::render 函数,从而允许这些界面元素访问场景。 与 MenubarToolbar 保存引用相比,这种设计当前并没有额外有点,它只是参考 Scotty3D 思路的结果,将来有可能为引入全局撤销 (Undo) 和重做 (Redo) 操作提供方便。

构造及析构函数说明

◆ Controller() [1/2]

Controller::Controller ( Controller & other)
delete

禁止复制构造。

◆ Controller() [2/2]

Controller::Controller ( )
private

构造函数是私有的。

成员函数说明

◆ controller()

Controller & Controller::controller ( )
static

获取 Controller 类的唯一实例。

唯一的实例被定义成函数内的静态变量,在 C++ 11 及之后的标准中,这种定义方式是线程安全的。

◆ on_framebuffer_resized()

void Controller::on_framebuffer_resized ( float width,
float height )

在缩放窗口时调整轨迹球半径、预览视角(相机)Y 方向的 FoV,并更新自身记录的窗口尺寸。

虽然名字相同,但这个函数并非 GLFW 的窗口缩放回调函数。在缩放时它会被真正的回调函数 Platform::on_framebuffer_resized 调用。

参数
width缩放后的窗口宽度
height缩放后的窗口高度

◆ on_mouse_dragged()

void Controller::on_mouse_dragged ( bool initial)

将鼠标拖动转换为旋转视角或平移视角操作。

当按下鼠标中键(或 Alt+鼠标左键)拖动时旋转视角,按下 Ctrl+鼠标左键拖动时平移视角。 同时按下 Alt 和 Ctrl 的效果与只按下 Alt 相同(只旋转不平移)。

参数
initial为真表示开始拖动时调用,为假表示拖动过程中调用。

◆ on_picking()

void Controller::on_picking ( )

根据鼠标点击选取场景中的物体。

这个函数将鼠标点击的屏幕坐标 (screen space) 转换为观察坐标 (view space), 然后将观察坐标转换回世界坐标 (world space),从而构造一条从观察相机(主相机) 发出的射线,按这条射线与场景中物体的相交结果拾取(选中)场景中的可选中对象。 工作于布局模式和物理模拟模式下时,它调用 pick_object 函数,工作于建模模式下时, 它调用 pick_element 函数。

◆ on_rotating()

void Controller::on_rotating ( bool initial)
private

将鼠标拖动转换为轨迹球 (Trackball) 操作,用于旋转预览视角。

轨迹球曲面的推导参考 Object Mouse Trackball

参数
initial为真表示开始拖动时调用,为假表示拖动过程中调用。

◆ on_translating()

void Controller::on_translating ( bool initial)
private

将鼠标拖动转换为视角平移。

将鼠标拖动时屏幕坐标的变化量换算为观察空间 (view space) 中的坐标变化, 光标向右移动对应相机向左移动,光标向上移动对应相机向下移动。 相应的变化量会累加到主相机的 positiontarget 属性上,因此平移过程中视线方向不会改变。

视点到观察点的距离增大(减小)时,相同屏幕坐标变化量对应的观察坐标变化量也增大(减小), 平移量正比于视角远近,比例系数为 mouse_translation_factor

参数
initial为真表示开始拖动时调用,为假表示拖动过程中调用。

◆ on_wheel_scrolled()

void Controller::on_wheel_scrolled ( )

将拨动鼠标滚轮的操作转换为视角拉进或远离。

缩放视角的操作按指数规律执行:鼠标滚轮每滚动一个单位,观察相机到目标点的距离就乘上一个固定值 wheel_scroll_factor,即

\[ \mathbf{d}_\text{new}=\text{wheel_scroll_factor}^\text{wheel_delta}\cdot\mathbf{d} \]

◆ pick_element()

void Controller::pick_element ( Ray & ray)
private

拾取半边、顶点、边或面片。

在建模模式下,根据射线求交的结果选择半边网格上的基本元素。

参数
ray根据点击位置生成的射线(世界坐标系下)

◆ pick_object()

void Controller::pick_object ( Ray & ray)
private

拾取物体。

在布局或物理模拟模式下,根据射线求交的结果选择物体。

参数
ray根据点击位置生成的射线(世界坐标系下)

◆ process_input()

void Controller::process_input ( )

处理关于场景操作的输入。

这个函数判别鼠标操作是否对应于某种场景操作(调整视角、拾取物体等),并调用相应的处理函数 (例如 on_mouse_clickedon_picking)。与场景操作相对的是控件操作(例如点击按钮), 控件操作由相应的 ImGui 控件直接处理。

◆ render()

void Controller::render ( const Shader & shader)

渲染场景和各个 UI 组件。控制器本身不直接渲染任何内容,而是调用相应类的 render() 方法。

参数
shader当前渲染使用的 shader,用于设置 shader 中的全局变量。

◆ render_debug_helpers()

void Controller::render_debug_helpers ( const Shader & shader)
private

渲染帮助调试的元素。

根据 debug_options 中的各项设置,渲染帮助调试的结构,如 BVH 的所有包围盒等。

◆ render_selected_element()

void Controller::render_selected_element ( const Shader & shader)
private

渲染当前选中的元素。

渲染选中元素时会禁用深度检测 GL_DEPTH_TEST ,直接在原先的绘制结果上叠加。 因此,即使将视角旋转到背面也会看到高亮出来的被选中元素。

◆ select()

void Controller::select ( SelectableType element)
private

选择一个元素。

这个函数修改控制器记录的选择状态。它包括两步动作:

  1. 调用 unselect 清除原先的选择状态及其副作用
  2. 修改被选中元素 selected_element,调用 select_[type] 函数执行具体操作
参数
element要选择的新元素

◆ select_edge()

void Controller::select_edge ( Edge * edge)
private

选择边并更新 highlighted_element

◆ select_face()

void Controller::select_face ( Face * face)
private

选择面片并更新 highlighted_element

◆ select_halfedge()

void Controller::select_halfedge ( const Halfedge * halfedge)
private

选择半边并更新 highlighted_halfedge

◆ select_light()

void Controller::select_light ( Light * light)
private

选择光源并更新 highlighted_element

◆ select_object()

void Controller::select_object ( Object * object)
private

选择物体并更新 Scene::selected_object

◆ select_vertex()

void Controller::select_vertex ( Vertex * vertex)
private

选择顶点并更新 highlighted_element

◆ unselect()

void Controller::unselect ( )
private

取消选择。

这个函数清楚当前的选择状态,将selected_element 重置为 std::monostate 并清空 highlighted_elementhighlighted_halfedge 这些高亮元素。 如果之前的被选中元素设置过 Scene 等对象的属性,它也会一并将其重置。

类成员变量说明

◆ debug_options

UI::DebugOptions Controller::debug_options
private

一些帮助调试的选项,详见 UI::DebugOptions 类型说明。

◆ highlighted_element

GL::Mesh Controller::highlighted_element
private

被选中元素类型为顶点、边、面片或光源时使用的绘制对象。

◆ highlighted_halfedge

GL::LineSet Controller::highlighted_halfedge
private

被选中元素类型为半边时使用的绘制对象。

◆ logger

std::shared_ptr<spdlog::logger> Controller::logger
private

日志记录器。

◆ main_camera

std::unique_ptr<Camera> Controller::main_camera
private

用于预览场景的观察相机(主相机)。

◆ menubar

std::unique_ptr<UI::Menubar> Controller::menubar
private

菜单栏。

◆ mode

WorkingMode Controller::mode
private

全局工作模式。

控制器维护着当前的工作模式,决定各种功能可用或禁用。其他的 GUI 组件持有对该变量的引用。

◆ mouse_translation_factor

float Controller::mouse_translation_factor = 0.001f
staticconstexprprivate

平移视角时屏幕坐标到观察坐标换算系数的固定部分。

◆ picking_ray

GL::LineSet Controller::picking_ray
private

显示拾取射线用的绘制对象,对应 UI::DebugOptions::show_picking_ray

◆ scene

std::unique_ptr<Scene> Controller::scene
private

包含所有三维数据的场景实例。

◆ selected_element

SelectableType Controller::selected_element
private

当前被选中的元素。

根据当前所处的模式,物体、各类几何基本元素、光源都可能被选中,详见 SelectableType 的类型说明。当 selected_element 持有 std::monostate 类型时, 当前的选择状态为空(没有任何元素被选中)。

◆ toolbar

std::unique_ptr<UI::Toolbar> Controller::toolbar
private

工具栏。

◆ trackball_radius

float Controller::trackball_radius
private

当前的轨迹球半径,决定轨迹球控制曲面上球面和双曲面部分的相切位置。

◆ wheel_scroll_factor

float Controller::wheel_scroll_factor = 0.8f
staticconstexprprivate

缩放视角的控制系数,详见 on_wheel_scrolled 方法。

◆ window_width

float Controller::window_width

由于 ImGui 使用浮点数表示尺寸,所有和布局相关的变量都是浮点型。


该类的文档由以下文件生成: