예제 #1
0
 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);
     }
 }
예제 #2
0
        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;
        }
예제 #3
0
        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();
                        }
                    }
                }
            }
        }