三维视图控制

CSharpGL封装了多种控制器以操纵三维视图WinGLCanvas,包括第一人称视角(FirstPerspectiveManipulater)、卫星视角(SatelliteManipulater)、旋转控制器(ArcBallManipulater)和平移控制器(TranslateManipulater),第一人称和卫星视角常用于游戏,旋转和平移控制器常用于三维处理软件,比如CloudCompare、MeshLab等。

旋转

旋转控制器可以观察三维模型各个角度的局部特征,由于未改变模型的大小,所以被称作刚体变换。CSharpGL的原作者在这里详细阐述了ArcBall轨迹球的工作原理,大致是:将三维模型放在一个球中,将鼠标的水平移动轨迹转化为球上的弧段,再通过弧段计算出旋转轴和旋转角。CSharpGL可以直接用ArcBallManipulater类创建一个轨迹球,构造函数的参数为注册的鼠标按键:

ArcBallManipulater ball = new ArcBallManipulater(GLMouseButtons.Left);

为了让轨迹球适应到任意位置的相机上,需要将轨迹球和相机绑定到一起:

ball.Bind(scene.Camera, this.winGLCanvas1);

为了实时更新三维模型的旋转状态,还需要注册ArcBallManipulater 的Rotated事件:

ball.Rotated += manipulater_Rotated;

void manipulater_Rotated(object sender, CSharpGL.ArcBallManipulater.Rotation e)
{
    SceneNodeBase node = scene.RootNode;
    node.RotationAngle = e.angleInDegree;
    node.RotationAxis = e.axis;
}

旋转控制器的解绑直接调用Unbind方法:

ball.Unbind();

平移

平移控制器也属于刚体变换,主要作用是观察三维模型在同一个裁剪面内不同位置的特征。和旋转控制器类似,平移控制器也可以通过简单的构造方法进行创建,两个参数分别是模型结点和注册的鼠标按键:

TranslateManipulater tran = new TranslateManipulater(scene.RootNode, GLMouseButtons.Right);

平移控制器同样需要绑定到相机上:

tran.Bind(scene.Camera, this.winGLCanvas1);

平移控制器的解绑也很简单

tran.Unbind();

缩放

三维模型的缩放是为了观察模型的细节和全貌,虽然CSharpGL未提供相关控制器,但是相机类(Camera)内包含的MouseWheel方法可用于缩放。操作方法如下:首先注册WinGLCanvas的MouseWheel事件:

winGLCanvas1.MouseWheel += openGLControl1_MouseWheel;

然后实现openGLControl1_MouseWheel方法:

private void openGLControl1_MouseWheel(object sender, MouseEventArgs e)
{
    var scene = this.scene;
    if (scene != null)
    {
        scene.Camera.MouseWheel(e.Delta);
    }
}

缩放的解绑即取消openGLControl1_MouseWheel的注册:

winGLCanvas1.MouseWheel -= openGLControl1_MouseWheel;