void GLControl_MouseWheel(object sender, System.Windows.Forms.MouseEventArgs e) { if (!KeyboardHelper.CtrlDown()) { if (e.Delta < 0) { if (!Camera.IsOrthogonal) { Camera.Distance *= 1.25f; } else { Camera.OrthogonalSize *= 1.25f; } } else if (e.Delta > 0) { if (!Camera.IsOrthogonal) { Camera.Distance /= 1.25f; } else { Camera.OrthogonalSize *= 1f / 1.25f; } } } else { Vector2 NewPosition = new Vector2(e.X, e.Y); MouseWheel?.Invoke(_Camera.GetRayThroughPixel(NewPosition), e); } }
void GLControl_MouseMove(object sender, System.Windows.Forms.MouseEventArgs e) { Vector2 NewPosition = new Vector2(e.X, e.Y); Vector2 Delta = NewPosition - LastPosition; if (Delta.Length > 0f) { StartedClick = false; } if (!KeyboardHelper.CtrlDown() && !KeyboardHelper.ShiftDown() && !KeyboardHelper.AltDown()) { if (e.Button == System.Windows.Forms.MouseButtons.Left) { if (!IsRollOnly) { Vector2 Angles = new Vector2(-Delta.X, -Delta.Y); //Angles.Y = 0; Angles = Angles / 180f / 4f * (float)Math.PI; Camera.Orbit(Angles); } else { float Angle = -(Delta.X + Delta.Y) / 180f / 4f * (float)Math.PI; Camera.Roll(Angle); } } else if (e.Button == System.Windows.Forms.MouseButtons.Middle) { Camera.PanPixels(new Vector2(-Delta.X, Delta.Y)); } } if (!StartedClick) { MouseMove?.Invoke(Camera.GetRayThroughPixel(NewPosition), e); } LastPosition = NewPosition; }
public void Viewport_Paint() { if (SurfaceMesh != null) { Vector3[] Bounds = SurfaceMesh.BoundingBoxCorners; Matrix4 ViewMatrix = Viewport.Camera.GetView(); float MinDist = float.MaxValue; float MaxDist = -float.MaxValue; foreach (var corner in Bounds) { float Dist = -Vector3.Transform(corner, ViewMatrix).Z; MinDist = Math.Min(MinDist, Dist); MaxDist = Math.Max(MaxDist, Dist); } MainWindow.Options.Viewport.Camera.ClipNear = Math.Max(1f, MinDist / 2); MainWindow.Options.Viewport.Camera.ClipFar = Math.Max(2f, MaxDist * 2); } MeshProgram.Use(); { MeshProgram.SetUniform("worldViewProjMatrix", MainWindow.Options.Viewport.Camera.GetViewProj()); MeshProgram.SetUniform("surfaceOffset", (float)SurfaceOffset * MainWindow.Options.PixelScale.X); if (TomogramTexture != null) { MeshProgram.SetUniform("useVolume", 1f); MeshProgram.SetUniform("volScale", OpenGLHelper.Reciprocal(TomogramTexture.Scale)); MeshProgram.SetUniform("volOffset", TomogramTexture.Offset); MeshProgram.SetUniform("texSize", OpenGLHelper.Reciprocal(TomogramTexture.Size)); GL.ActiveTexture(TextureUnit.Texture0); GL.BindTexture(TextureTarget.Texture3D, TomogramTexture.Handle); } else { MeshProgram.SetUniform("useVolume", 0f); } GL.ActiveTexture(TextureUnit.Texture1); GL.BindTexture(TextureTarget.Texture2D, SelectionTexture.Handle); float TraceStart = TraceDepthOffset; float TraceLength = TraceDepth; MeshProgram.SetUniform("traceParams", new Vector2(TraceStart, TraceLength)); MeshProgram.SetUniform("traceSharpening", (float)TraceSharpening / 100f); float RangeMin = (float)Math.Min(OutputRangeMin, OutputRangeMax), RangeMax = (float)Math.Max(OutputRangeMin, OutputRangeMax); MeshProgram.SetUniform("normalizeParams", new Vector2(RangeMin, RangeMax - RangeMin)); Vector3 LightDirection = MainWindow.Options.Viewport.Camera.GetDirection(); MeshProgram.SetUniform("lightDirection", LightDirection); MeshProgram.SetUniform("lightIntensity", OutputLight / 100f); if (SurfaceMesh != null) { SurfaceMesh.Draw(); } } // Draw point groups. There are 3 options for depiction: // - Boxes with custom size // - Same mesh for every point in a group, e. g. protein map from EMDB // - Individual mesh for every point in a group, e. g. isosurface within its enclosed volume { List <PointGroup> AllGroups = new List <PointGroup>(PointGroups); AllGroups.Add(PreviewGroup); foreach (PointGroup group in AllGroups.Where(g => g.IsVisible && g.Points.Count > 0)) { if (group.Depiction == PointDepiction.Box) { // Draw orientation gizmos PointGizmoProgram.Use(); PointGizmoProgram.SetUniform("worldViewProjMatrix", MainWindow.Options.Viewport.Camera.GetViewProj()); GL.LineWidth(10f); PointGizmoProgram.SetUniform("cubeSize", (float)group.Size * MainWindow.Options.PixelScale.X); group.PointCloud.Draw(); // Draw boxes PointProgram.Use(); PointProgram.SetUniform("worldViewProjMatrix", MainWindow.Options.Viewport.Camera.GetViewProj()); // Draw back faces first, then front, to ensure correct transparency (locally) GL.Enable(EnableCap.CullFace); GL.CullFace(CullFaceMode.Front); PointProgram.SetUniform("cubeSize", (float)group.Size * MainWindow.Options.PixelScale.X); group.PointCloud.Draw(); GL.CullFace(CullFaceMode.Back); PointProgram.SetUniform("cubeSize", (float)group.Size * MainWindow.Options.PixelScale.X); group.PointCloud.Draw(); GL.Disable(EnableCap.CullFace); } else if (group.Depiction == PointDepiction.Mesh) { PointModelProgram.Use(); PointModelProgram.SetUniform("modelColor", ColorHelper.ColorToVector(group.Color, true)); PointModelProgram.SetUniform("cameraDirection", Viewport.Camera.GetDirection()); foreach (var point in group.Points) { PointModelProgram.SetUniform("isSelected", point.IsSelected ? 1f : 0f); Vector3 Offset = point.TransformedMatrix.Column2 * (float)group.DepictionMeshOffset; PointModelProgram.SetUniform("worldViewProjMatrix", Matrix4.CreateTranslation(point.Position + Offset) * MainWindow.Options.Viewport.Camera.GetViewProj()); PointModelProgram.SetUniform("rotationMatrix", Matrix3.Transpose(point.TransformedMatrix)); group.DepictionMesh?.Draw(); } } else if (group.Depiction == PointDepiction.LocalSurface) { PointModelProgram.Use(); PointModelProgram.SetUniform("modelColor", ColorHelper.ColorToVector(group.Color, true)); PointModelProgram.SetUniform("cameraDirection", Viewport.Camera.GetDirection()); foreach (var point in group.Points) { PointModelProgram.SetUniform("isSelected", point.IsSelected ? 1f : 0f); PointModelProgram.SetUniform("worldViewProjMatrix", Matrix4.CreateTranslation(point.Position) * MainWindow.Options.Viewport.Camera.GetViewProj()); PointModelProgram.SetUniform("rotationMatrix", Matrix3.Identity); point.DepictionMesh?.Draw(); } // Also draw the orientation stick if (KeyboardHelper.CtrlDown()) { PointGizmoProgram.Use(); PointGizmoProgram.SetUniform("worldViewProjMatrix", MainWindow.Options.Viewport.Camera.GetViewProj()); GL.LineWidth(10f); PointGizmoProgram.SetUniform("cubeSize", (float)group.Size * MainWindow.Options.PixelScale.X); group.PointCloud.Draw(); } } } } }