/// <summary> /// Synchronizes the camera to the controller's current state</summary> /// <param name="camera">Camera</param> protected override void ControllerToCamera(Camera camera) { Vec3F lookAt = Camera.LookAt; Vec3F up = Camera.Up; if (camera.ViewType == ViewTypes.Perspective) { Camera.PerspectiveNearZ = CalculatePerspectiveNearZ(); QuatF rotation = m_rotation * m_currentRotation; rotation = rotation.Inverse; Matrix4F transform = new Matrix4F(rotation); lookAt = new Vec3F(0, 0, -1); up = new Vec3F(0, 1, 0); transform.Transform(ref lookAt); transform.Transform(ref up); } float eyeOffset = m_distanceFromLookAt; float lookAtOffset = 0; if (m_distanceFromLookAt < m_dollyThreshold) // do we need to start dollying? { eyeOffset = m_distanceFromLookAt; lookAtOffset = m_distanceFromLookAt - m_dollyThreshold; } Camera.Set( m_lookAtPoint - (eyeOffset * lookAt), // eye m_lookAtPoint - (lookAtOffset * lookAt), // lookAt up); // up base.ControllerToCamera(camera); }
/// <summary> /// Handles key-down events</summary> /// <param name="sender">Control that raised original event</param> /// <param name="e">Event args</param> /// <returns>True if controller handled the event</returns> public override bool KeyDown(object sender, KeyEventArgs e) { m_keyMap[e.KeyValue] = true; // W A S D for forward, strafe left, backward, strafe right, is the default Vec3F dir = new Vec3F(); if (m_keyMap[(int)CanvasControl3D.ControlScheme.Left1] || m_keyMap[(int)CanvasControl3D.ControlScheme.Left2]) { dir = dir - Camera.Right; } if (m_keyMap[(int)CanvasControl3D.ControlScheme.Right1] || m_keyMap[(int)CanvasControl3D.ControlScheme.Right2]) { dir = dir + Camera.Right; } if (m_keyMap[(int)CanvasControl3D.ControlScheme.Forward1] || m_keyMap[(int)CanvasControl3D.ControlScheme.Forward2]) { dir = dir + Camera.LookAt; } if (m_keyMap[(int)CanvasControl3D.ControlScheme.Back1] || m_keyMap[(int)CanvasControl3D.ControlScheme.Back2]) { dir = dir - Camera.LookAt; } bool handled = CanvasControl3D.ControlScheme.IsControllingCamera(Control.ModifierKeys, e); if (handled) { dir.Normalize(); Vec3F p = Camera.Eye; float y = p.Y; p += dir * m_scale; p.Y = y; Camera.Set(p); } return(handled); }
/// <summary> /// Handles mouse-move events</summary> /// <param name="sender">Control that raised original event</param> /// <param name="e">Event args</param> /// <returns>True if controller handled the event</returns> public override bool MouseMove(object sender, MouseEventArgs e) { if (m_dragging && CanvasControl3D.ControlScheme.IsControllingCamera(Control.ModifierKeys, e)) { float dx = (float)(e.X - m_lastMousePoint.X) / 150.0f; float dy = (float)(e.Y - m_lastMousePoint.Y) / 150.0f; if (CanvasControl3D.ControlScheme.IsElevating(Control.ModifierKeys, e)) { // move camera up/down Vec3F p = Camera.Eye; p.Y += (dy < 0) ? m_scale : -m_scale; Camera.Set(p); } else if (CanvasControl3D.ControlScheme.IsTurning(Control.ModifierKeys, e)) { // pitch and yaw camera Matrix4F mat = Matrix4F.RotAxisRH(Camera.Right, -dy); // pitch along camera right Matrix4F yaw = new Matrix4F(); yaw.RotY(-dx); mat.Mul(yaw, mat); Vec3F lookAt = Camera.LookAt; Vec3F up = Camera.Up; mat.Transform(ref lookAt); mat.Transform(ref up); Vec3F position = Camera.Eye; float d = Camera.DistanceFromLookAt; Camera.Set(position, position + lookAt * d, up); } m_lastMousePoint = e.Location; return(true); } return(base.MouseMove(sender, e)); }
/// <summary> /// Synchronizes the camera to the controller's current state</summary> /// <param name="camera">Camera</param> protected override void ControllerToCamera(Camera camera) { Vec3F lookAt = camera.LookAt; Vec3F right = camera.Right; Vec3F up = camera.Up; if (camera.ViewType == ViewTypes.Perspective) { Camera.PerspectiveNearZ = CalculatePerspectiveNearZ(); // override the camera's frame of reference float sinPhi = (float)Math.Sin(m_elevation); float cosPhi = (float)Math.Cos(m_elevation); float sinTheta = (float)Math.Sin(m_azimuth); float cosTheta = (float)Math.Cos(m_azimuth); lookAt = new Vec3F(-cosPhi * sinTheta, -sinPhi, -cosPhi * cosTheta); right = new Vec3F(cosTheta, 0, -sinTheta); up = Vec3F.Cross(right, lookAt); // TODO compute from sin/cos values } float lookAtOffset = 0; if (m_distanceFromLookAt < m_dollyThreshold) // do we need to start dollying? { lookAtOffset = m_distanceFromLookAt - m_dollyThreshold; } float eyeOffset = m_distanceFromLookAt; Camera.Set( m_lookAtPoint - (eyeOffset * lookAt), // eye point m_lookAtPoint - (lookAtOffset * lookAt), // look-at point up); // up vector base.ControllerToCamera(camera); }