Пример #1
0
        private void CameraResized()
        {
            OpenGL gl = sceneControl.OpenGL;
            var    h  = this.sceneControl.Height;
            var    w  = this.sceneControl.Width;

            if (h == 0)
            {
                h = 1;
            }

            {
                IPerspectiveCamera camera = this.camera;
                camera.AspectRatio = (double)w / (double)h;
            }

            {
                IOrthoCamera camera = this.camera;
                if (w < h)
                {
                    camera.Bottom = camera.Left * h / w;
                    camera.Top    = camera.Right * h / w;
                }
                else
                {
                    camera.Left  = camera.Bottom * w / h;
                    camera.Right = camera.Top * w / h;
                }
            }
            gl.Viewport(0, 0, w, h);
            this.camera.Project(gl);
        }
Пример #2
0
        ///// <summary>
        ///// 默认目标为vec3(0, 0, -1)
        ///// </summary>
        //public static readonly vec3 defaultTarget = new vec3(0, 0, -1);

        ///// <summary>
        ///// 默认位置为vec3(0, 0, 0)
        ///// </summary>
        //public static readonly vec3 defaultPosition = new vec3(0, 0, 0);

        ///// <summary>
        ///// 默认上方为vec3(0, 1, 0)
        ///// </summary>
        //public static readonly vec3 defaultUpVector = new vec3(0, 1, 0);

        /// <summary>
        /// Camera.
        /// </summary>
        /// <param name="position">position in world space</param>
        /// <param name="target">target in world space.</param>
        /// <param name="up">up in world space.</param>
        /// <param name="cameraType">perspective or ortho?</param>
        /// <param name="width">canvas' width.</param>
        /// <param name="height">canvas' height.</param>
        public Camera(vec3 position, vec3 target, vec3 up, CameraType cameraType, double width, double height)
        {
            this.Position = position;
            this.Target   = target;
            this.UpVector = up;

            IPerspectiveCamera perspectiveCamera = this;

            perspectiveCamera.FieldOfView = 60.0f;
            perspectiveCamera.AspectRatio = width / height;
            perspectiveCamera.Near        = 0.1;
            perspectiveCamera.Far         = 10000;

            const int    factor      = 100;
            IOrthoCamera orthoCamera = this;

            orthoCamera.Left   = -width / 2 / factor;
            orthoCamera.Right  = width / 2 / factor;
            orthoCamera.Bottom = -height / 2 / factor;
            orthoCamera.Top    = height / 2 / factor;
            orthoCamera.Near   = -10000;
            orthoCamera.Far    = 10000;

            this.CameraType = cameraType;
        }
Пример #3
0
        /// <summary>
        /// Apply specifed viewType to camera according to bounding box's size and position.
        /// <para>    +-------+    </para>
        /// <para>   /|      /|    </para>
        /// <para>  +-------+ |    </para>
        /// <para>  | |     | |    </para>
        /// <para>  | O-----|-+---X</para>
        /// <para>  |/      |/     </para>
        /// <para>  +-------+      </para>
        /// <para> /  |            </para>
        /// <para>Y   Z            </para>
        /// <para>其边长为(2 * Math.Sqrt(3)), 所在的坐标系如下</para>
        /// <para>   O---X</para>
        /// <para>  /|    </para>
        /// <para> Y |    </para>
        /// <para>   Z    </para>
        /// </summary>
        /// <param name="camera"></param>
        /// <param name="boundingBox"></param>
        /// <param name="viewType"></param>
        public static void ApplyViewType(this IPerspectiveViewCamera camera, IBoundingBox boundingBox,
                                         ViewTypes viewType)
        {
            vec3  length = boundingBox.MaxPosition - boundingBox.MinPosition;
            float size   = Math.Max(Math.Max(length.x, length.y), length.z);

            {
                vec3 target = boundingBox.MaxPosition / 2 + boundingBox.MinPosition / 2;

                vec3 target2Position;
                vec3 upVector;
                GetBackAndUp(out target2Position, out upVector, viewType);

                vec3 position = target + target2Position * (size * 2 + 1);

                camera.Position = position;
                camera.Target   = target;
                camera.UpVector = upVector;
            }

            {
                int[] viewport = new int[4];
                OpenGL.GetInteger(GetTarget.Viewport, viewport);
                int width = viewport[2]; int height = viewport[3];

                IPerspectiveCamera perspectiveCamera = camera;
                perspectiveCamera.FieldOfView = 60;
                perspectiveCamera.AspectRatio = (double)width / (double)height;
                perspectiveCamera.Near        = 0.01;
                perspectiveCamera.Far         = size * 3 + 1;// double.MaxValue;
            }
        }
Пример #4
0
        public FormFontElement()
        {
            InitializeComponent();

            //if (CameraDictionary.Instance.ContainsKey(this.GetType().Name))
            //{
            //    this.camera = CameraDictionary.Instance[this.GetType().Name];
            //}
            //else
            {
                this.camera = new ScientificCamera(CameraTypes.Perspecitive, this.glCanvas1.Width, this.glCanvas1.Height);
                //CameraDictionary.Instance.Add(this.GetType().Name, this.camera);
            }

            IPerspectiveCamera perspectiveCamera = this.camera;

            perspectiveCamera.FieldOfView = 60f;
            perspectiveCamera.AspectRatio = (double)this.glCanvas1.Width / (double)this.glCanvas1.Height;
            perspectiveCamera.Near        = 0.01;
            perspectiveCamera.Far         = 10000;

            IOrthoCamera orthoCamera = this.camera;

            orthoCamera.Left   = -this.glCanvas1.Width / 2;
            orthoCamera.Right  = this.glCanvas1.Width / 2;
            orthoCamera.Bottom = -this.glCanvas1.Height / 2;
            orthoCamera.Top    = this.glCanvas1.Height / 2;
            orthoCamera.Near   = -10000;
            orthoCamera.Far    = 10000;

            this.camera.Position = new vec3(0, 0, 9.23f);

            satelliteRoration = new SatelliteRotator(camera);

            //element = new ModernSingleTextureFont("simsun.ttf", 48, '祝', '神');//char.MinValue, char.MaxValue);
            //element = new FontElement("simsun.ttf", 48, '一', '龟');//包含了几乎所有汉字字符
            element = new FontElement("simsun.ttf", 48, (char)0, '~');

            element.Initialize();

            //element.SetText("祝神");
            //element.SetText("一龟");
            element.SetText("The quick brown fox jumps over the lazy dog!");

            element.BeforeRendering += element_BeforeRendering;
            element.AfterRendering  += element_AfterRendering;

            uiAxisElement = new SimpleUIAxis(
                new IUILayoutParam(AnchorStyles.Left | AnchorStyles.Bottom,
                                   new Padding(0, 0, 0, 0), new System.Drawing.Size(100, 100)));
            uiAxisElement.Initialize();

            this.glCanvas1.MouseWheel += glCanvas1_MouseWheel;
            this.glCanvas1.KeyPress   += glCanvas1_KeyPress;
            this.glCanvas1.MouseDown  += glCanvas1_MouseDown;
            this.glCanvas1.MouseMove  += glCanvas1_MouseMove;
            this.glCanvas1.MouseUp    += glCanvas1_MouseUp;
            this.glCanvas1.OpenGLDraw += glCanvas1_OpenGLDraw;
            this.glCanvas1.Resize     += glCanvas1_Resize;
        }
Пример #5
0
 /// <summary>
 /// Extension method for <see cref="IPerspectiveCamera"/> to get projection matrix.
 /// </summary>
 /// <param name="camera"></param>
 /// <returns></returns>
 public static mat4 GetProjectionMat4(this IPerspectiveCamera camera)
 {
     GlmNet.mat4 perspective = GlmNet.glm.perspective(
         (float)(camera.FieldOfView / 360.0 * Math.PI * 2),
         (float)camera.AspectRatio, (float)camera.Near, (float)camera.Far);
     return(perspective);
 }
Пример #6
0
        /// <summary>
        /// 摄像机。
        /// </summary>
        /// <param name="cameraType">类型</param>
        /// <param name="width">OpenGL窗口的宽度</param>
        /// <param name="height">OpenGL窗口的高度</param>
        public Camera(CameraType cameraType, double width, double height)
        {
            this.lastWidth  = width;
            this.lastHeight = height;

            IPerspectiveCamera perspectiveCamera = this;

            perspectiveCamera.FieldOfView = 60.0f;
            perspectiveCamera.AspectRatio = width / height;
            perspectiveCamera.Near        = 0.1;
            perspectiveCamera.Far         = 1000;

            const int    factor      = 100;
            IOrthoCamera orthoCamera = this;

            orthoCamera.Left   = -width / 2 / factor;
            orthoCamera.Right  = width / 2 / factor;
            orthoCamera.Bottom = -height / 2 / factor;
            orthoCamera.Top    = height / 2 / factor;
            orthoCamera.Near   = -1000;
            orthoCamera.Far    = 1000;

            this.Target   = defaultTarget;
            this.Position = defaultPosition;
            this.UpVector = defaultUpVector;

            this.CameraType = cameraType;
        }
        public ScientificCamera(CameraTypes cameraType = CameraTypes.Perspecitive)
        {
            Name = "Scientific Camera: " + count++;
            IPerspectiveCamera perspectiveCamera = this;

            perspectiveCamera.FieldOfView = 60f;
            perspectiveCamera.AspectRatio = 1f;
            perspectiveCamera.Near        = 0.01;
            perspectiveCamera.Far         = 1000;

            IOrthoCamera orthoCamera = this;

            orthoCamera.Left   = -100;
            orthoCamera.Right  = 100;
            orthoCamera.Bottom = -100;
            orthoCamera.Top    = 100;
            orthoCamera.Near   = -1000;
            orthoCamera.Far    = 1000;

            this.Target   = new Vertex(0, 0, 0);
            this.UpVector = new Vertex(0, 1, 0);
            this.Position = new Vertex(0, 0, 1);

            this.CameraType = cameraType;
        }
Пример #8
0
        /// <summary>
        /// 实施传统方式的投影
        /// </summary>
        /// <param name="camera"></param>
        public static void LegacyGLProjection(this ICamera camera)
        {
            //	Load the projection identity matrix.
            GL.MatrixMode(GL.GL_PROJECTION);
            GL.LoadIdentity();

            //	Perform the projection.
            switch (camera.CameraType)
            {
            case CameraType.Perspecitive:
                IPerspectiveCamera perspectiveCamera = camera;
                GL.gluPerspective(perspectiveCamera.FieldOfView, perspectiveCamera.AspectRatio, perspectiveCamera.Near, perspectiveCamera.Far);
                break;

            case CameraType.Ortho:
                IOrthoCamera orthoCamera = camera;
                GL.Ortho(orthoCamera.Left, orthoCamera.Right, orthoCamera.Bottom, orthoCamera.Top, orthoCamera.Near, orthoCamera.Far);
                break;

            default:
                break;
            }

            //  Perform the look at transformation.
            GL.gluLookAt((double)camera.Position.x, (double)camera.Position.y, (double)camera.Position.z,
                         (double)camera.Target.x, (double)camera.Target.y, (double)camera.Target.z,
                         (double)camera.UpVector.x, (double)camera.UpVector.y, (double)camera.UpVector.z);

            //	Back to the modelview matrix.
            GL.MatrixMode(GL.GL_MODELVIEW);
        }
Пример #9
0
        /// <summary>
        /// Extension method for <see cref="IPerspectiveCamera"/> to get projection matrix.
        /// </summary>
        /// <param name="camera"></param>
        /// <returns></returns>
        public static mat4 GetProjectionMat4(this IPerspectiveCamera camera)
        {
            mat4 perspective = glm.perspective(
                (float)(camera.FieldOfView * Math.PI / 180.0f),
                (float)camera.AspectRatio, (float)camera.Near, (float)camera.Far);

            return(perspective);
        }
Пример #10
0
        /// <summary>
        /// opengl控件的大小改变时调整camera.
        /// Adjust camera when OpenGL canvas's size changed.
        /// </summary>
        /// <param name="camera"></param>
        /// <param name="lastSize">canvas' last size.</param>
        /// <param name="currentSize">canvas' current size.</param>
        public static void Resize(this ICamera camera, Size lastSize, Size currentSize)
        {
            IPerspectiveCamera perspectiveCamera = camera;
            double             lastAspectRatio   = perspectiveCamera.AspectRatio;

            // update perspective camera.
            {
                perspectiveCamera.AspectRatio = ((double)currentSize.Width) / ((double)currentSize.Height);
            }

            // update ortho camera.
            {
                IOrthoCamera orthoCamera = camera;
                if (lastSize.Width != currentSize.Width)
                {
                    double lastWidth    = orthoCamera.Right - orthoCamera.Left;
                    double widthRatio   = ((double)currentSize.Width) / ((double)lastSize.Width);
                    double currentWidth = lastWidth * widthRatio;
                    orthoCamera.Left  = -currentWidth / 2.0;
                    orthoCamera.Right = currentWidth / 2.0;
                }

                if (lastSize.Height != currentSize.Height)
                {
                    double lastHeight    = orthoCamera.Top - orthoCamera.Bottom;
                    double heightRatio   = ((double)currentSize.Height) / ((double)lastSize.Height);
                    double currentHeight = lastHeight * heightRatio;
                    orthoCamera.Bottom = -currentHeight / 2.0;
                    orthoCamera.Top    = currentHeight / 2.0;
                }
                //if (aspectRatio > lastAspectRatio)
                //{
                //    double top = orthoCamera.Top;
                //    double newRight = top * aspectRatio;
                //    orthoCamera.Left = -newRight;
                //    orthoCamera.Right = newRight;
                //}
                //else if (aspectRatio < lastAspectRatio)
                //{
                //    double right = orthoCamera.Right;
                //    double newTop = right / aspectRatio;
                //    orthoCamera.Bottom = -newTop;
                //    orthoCamera.Top = newTop;
                //}

                //const int factor = 100;
                //if (width / 2 / factor != orthoCamera.Right)
                //{
                //    orthoCamera.Left = -width / 2 / factor;
                //    orthoCamera.Right = width / 2 / factor;
                //}
                //if (height / 2 / factor != orthoCamera.Top)
                //{
                //    orthoCamera.Bottom = -height / 2 / factor;
                //    orthoCamera.Top = height / 2 / factor;
                //}
            }
        }
Пример #11
0
        /// <summary>
        /// opengl控件的大小改变时调整camera.
        /// Adjust camera when OpenGL canvas's size changed.
        /// </summary>
        /// <param name="camera"></param>
        /// <param name="lastSize">canvas' last size.</param>
        /// <param name="currentSize">canvas' current size.</param>
        public static void Resize(this ICamera camera, Size lastSize, Size currentSize)
        {
            // update perspective camera.
            {
                IPerspectiveCamera perspectiveCamera = camera;
                perspectiveCamera.AspectRatio = ((double)currentSize.Width) / ((double)currentSize.Height);
            }

            // update ortho camera.
            {
                IOrthoCamera orthoCamera = camera;
                // fit window size.
                if (lastSize.Width != currentSize.Width)
                {
                    double lastWidth    = orthoCamera.Right - orthoCamera.Left;
                    double widthRatio   = ((double)currentSize.Width) / ((double)lastSize.Width);
                    double currentWidth = lastWidth * widthRatio;
                    double center       = (orthoCamera.Left + orthoCamera.Right) / 2.0 * widthRatio;
                    orthoCamera.Left  = center - currentWidth / 2.0;
                    orthoCamera.Right = center + currentWidth / 2.0;
                }
                // fit window size.
                if (lastSize.Height != currentSize.Height)
                {
                    double lastHeight    = orthoCamera.Top - orthoCamera.Bottom;
                    double heightRatio   = ((double)currentSize.Height) / ((double)lastSize.Height);
                    double currentHeight = lastHeight * heightRatio;
                    double center        = (orthoCamera.Bottom + orthoCamera.Top) / 2.0 * heightRatio;
                    orthoCamera.Bottom = center - currentHeight / 2.0;
                    orthoCamera.Top    = center + currentHeight / 2.0;
                }

                //// scale scene.
                //if (currentSize.Width >= currentSize.Height)
                //{
                //    double ratio1 = (double)currentSize.Width / (double)lastSize.Width;
                //    double ratio2 = (double)lastSize.Height / (double)currentSize.Height;
                //    double currentWidth = orthoCamera.Right - orthoCamera.Left;
                //    double center = (orthoCamera.Right + orthoCamera.Left) / 2.0;
                //    double newWidth = currentWidth * ratio1 * ratio2;
                //    orthoCamera.Left = center - newWidth / 2;
                //    orthoCamera.Right = center + newWidth / 2;
                //}
                //else
                //{
                //    double ratio1 = (double)currentSize.Height / (double)lastSize.Height;
                //    double ratio2 = (double)lastSize.Width / (double)currentSize.Width;
                //    double currentHeight = orthoCamera.Top - orthoCamera.Bottom;
                //    double center = (orthoCamera.Top + orthoCamera.Bottom) / 2;
                //    double newHeight = currentHeight * ratio1 * ratio2;
                //    orthoCamera.Bottom = center - newHeight / 2;
                //    orthoCamera.Top = center + newHeight / 2;
                //}
            }
        }
Пример #12
0
 public void CopyFrom(IPerspectiveCamera fromCamera)
 {
     this._position    = fromCamera.Position;
     this._lookAt      = fromCamera.LookAt;
     this._up          = fromCamera.Up;
     this._nearPlane   = fromCamera.NearPlane;
     this._farPlane    = fromCamera.FarPlane;
     this._fieldOfView = fromCamera.FieldOfView;
     this._aspectRatio = fromCamera.AspectRatio;
     UpdateView();
     UpdateProjection();
 }
        /// <summary>
        /// Initialises the scene.
        /// </summary>
        /// <param name="gl">The OpenGL instance.</param>
        /// <param name="width">The width of the screen.</param>
        /// <param name="height">The height of the screen.</param>
        public void Initialise(OpenGL gl, float width, float height)
        {
            //  Set a blue clear colour.
            gl.ClearColor(0.4f, 0.6f, 0.9f, 0.5f);

            {
                //  Create the shader program.
                var vertexShaderSource   = ManifestResourceLoader.LoadTextFile("Shader.vert");
                var fragmentShaderSource = ManifestResourceLoader.LoadTextFile("Shader.frag");
                var shaderProgram        = new ShaderProgram();
                shaderProgram.Create(gl, vertexShaderSource, fragmentShaderSource, null);
                shaderProgram.BindAttributeLocation(gl, attributeIndexPosition, "in_Position");
                shaderProgram.BindAttributeLocation(gl, attributeIndexColour, "in_Color");
                shaderProgram.AssertValid(gl);
                this.shaderProgram = shaderProgram;
            }
            {
                //  Create the shader program.
                var vertexShaderSource   = ColorCodedPickingShaderHelper.GetShaderSource(ColorCodedPickingShaderHelper.ShaderTypes.VertexShader);
                var fragmentShaderSource = ColorCodedPickingShaderHelper.GetShaderSource(ColorCodedPickingShaderHelper.ShaderTypes.FragmentShader);
                var shaderProgram        = new ShaderProgram();
                shaderProgram.Create(gl, vertexShaderSource, fragmentShaderSource, null);
                shaderProgram.BindAttributeLocation(gl, attributeIndexPosition, "in_Position");
                shaderProgram.BindAttributeLocation(gl, attributeIndexColour, "in_Color");
                shaderProgram.AssertValid(gl);
                this.pickingShaderProgram = shaderProgram;
            }

            //  Create a perspective projection matrix.
            const float rads = (60.0f / 360.0f) * (float)Math.PI * 2.0f;

            projectionMatrix = glm.perspective(rads, width / height, 0.1f, 100.0f);

            //  Create a view matrix to move us back a bit.
            viewMatrix = glm.translate(new mat4(1.0f), new vec3(0.0f, 0.0f, -5.0f));

            //  Create a model matrix to make the model a little bigger.
            modelMatrix = glm.scale(new mat4(1.0f), new vec3(2.5f));
            IPerspectiveCamera camera = this.cameraRotation.Camera;

            projectionMatrix = camera.GetProjectionMat4();
            viewMatrix       = this.cameraRotation.Camera.GetViewMat4();
            modelMatrix      = mat4.identity();

            //  Now create the geometry for the square.
            CreateVertices(gl);
        }
        /// <summary>
        /// Draws the scene.
        /// </summary>
        /// <param name="gl">The OpenGL instance.</param>
        public void Draw(OpenGL gl, RenderMode renderMode = RenderMode.Render)
        {
            var shader = (renderMode == RenderMode.HitTest) ? pickingShaderProgram : shaderProgram;

            if (renderMode == RenderMode.HitTest)
            {
                gl.ClearColor(1, 1, 1, 1);
            }
            else
            {
                //  Set a blue clear colour.
                gl.ClearColor(0.4f, 0.6f, 0.9f, 0.5f);
            }

            //  Clear the scene.
            gl.Clear(OpenGL.GL_COLOR_BUFFER_BIT | OpenGL.GL_DEPTH_BUFFER_BIT | OpenGL.GL_STENCIL_BUFFER_BIT);

            gl.PointSize(3);

            // Update matrices.
            IPerspectiveCamera camera = this.cameraRotation.Camera;

            projectionMatrix = camera.GetProjectionMat4();
            viewMatrix       = this.cameraRotation.Camera.GetViewMat4();
            modelMatrix      = mat4.identity();

            //  Bind the shader, set the matrices.
            shader.Bind(gl);
            shader.SetUniformMatrix4(gl, "projectionMatrix", projectionMatrix.to_array());
            shader.SetUniformMatrix4(gl, "viewMatrix", viewMatrix.to_array());
            shader.SetUniformMatrix4(gl, "modelMatrix", modelMatrix.to_array());

            //  Bind the out vertex array.
            vertexBufferArray.Bind(gl);

            //  Draw the square.
            //gl.DrawArrays(OpenGL.GL_TRIANGLES, 0, vertices.Length);
            gl.DrawArrays(OpenGL.GL_POINTS, 0, vertices.Length);

            //  Unbind our vertex array and shader.
            vertexBufferArray.Unbind(gl);
            shader.Unbind(gl);

            gl.Flush();
        }
Пример #15
0
        // TODO: This is not a good implemtation. rewrite it!
        /// <summary>
        /// 对摄像机执行一次缩放操作
        /// </summary>
        /// <param name="camera"></param>
        /// <param name="delta"></param>
        public static void MouseWheel(this ICamera camera, int delta)
        {
            //if (camera.CameraType == CameraTypes.Perspecitive)
            {
                var target2Position = (camera.Position - camera.Target);
                if (target2Position.length() < 0.01)
                {
                    target2Position    = target2Position.normalize();
                    target2Position.x *= 0.01f;
                    target2Position.y *= 0.01f;
                    target2Position.z *= 0.01f;
                }
                var scaledTarget2Position = target2Position * (1 - delta * 0.001f);
                camera.Position = camera.Target + scaledTarget2Position;
                double lengthDiff = scaledTarget2Position.length() - target2Position.length();
                // Increase ortho camera's Near/Far property in case the camera's position changes too much.
                IPerspectiveCamera perspectiveCamera = camera;
                perspectiveCamera.Far += lengthDiff;
                //perspectiveCamera.Near += lengthDiff;
                IOrthoCamera orthoCamera = camera;
                orthoCamera.Far  += lengthDiff;
                orthoCamera.Near += lengthDiff;

                System.Console.WriteLine("camera pos:({0},{1},{2}) target:({3},{4},{5})",
                                         camera.Position.x, camera.Position.y, camera.Position.z,
                                         camera.Target.x, camera.Target.y, camera.Target.z);
            }
            //else if (camera.CameraType == CameraTypes.Ortho)
            {
                IOrthoCamera orthoCamera = camera;
                double       distanceX   = orthoCamera.Right - orthoCamera.Left;
                double       distanceY   = orthoCamera.Top - orthoCamera.Bottom;
                double       centerX     = (orthoCamera.Left + orthoCamera.Right) / 2;
                double       centerY     = (orthoCamera.Bottom + orthoCamera.Top) / 2;
                orthoCamera.Left   = centerX - distanceX * (1 - delta * 0.001) / 2;
                orthoCamera.Right  = centerX + distanceX * (1 - delta * 0.001) / 2;
                orthoCamera.Bottom = centerY - distanceY * (1 - delta * 0.001) / 2;
                orthoCamera.Top    = centerX + distanceY * (1 - delta * 0.001) / 2;
            }
        }
Пример #16
0
        /// <summary>
        /// opengl控件的大小改变时调整camera
        /// </summary>
        /// <param name="width"></param>
        /// <param name="height"></param>
        public void Resize(double width, double height)
        {
            double aspectRatio = width / height;

            IPerspectiveCamera perspectiveCamera = this;

            perspectiveCamera.AspectRatio = aspectRatio;

            IOrthoCamera orthoCamera = this;

            double lastAspectRatio = this.lastWidth / this.lastHeight;

            if (aspectRatio > lastAspectRatio)
            {
                double top      = orthoCamera.Top;
                double newRight = top * aspectRatio;
                orthoCamera.Left  = -newRight;
                orthoCamera.Right = newRight;
            }
            else if (aspectRatio < lastAspectRatio)
            {
                double right  = orthoCamera.Right;
                double newTop = right / aspectRatio;
                orthoCamera.Bottom = -newTop;
                orthoCamera.Top    = newTop;
            }

            //const int factor = 100;
            //if (width / 2 / factor != orthoCamera.Right)
            //{
            //    orthoCamera.Left = -width / 2 / factor;
            //    orthoCamera.Right = width / 2 / factor;
            //}
            //if (height / 2 / factor != orthoCamera.Top)
            //{
            //    orthoCamera.Bottom = -height / 2 / factor;
            //    orthoCamera.Top = height / 2 / factor;
            //}
        }
        /// <summary>
        /// This is the class' main function, to override this function and perform a
        /// perspective transformation.
        /// </summary>
        public override void TransformProjectionMatrix(OpenGL gl)
        {
            //  Perform the look at transformation.
            switch (CameraType)
            {
            case CameraTypes.Perspecitive:
                IPerspectiveCamera perspectiveCamera = this;
                gl.Perspective(perspectiveCamera.FieldOfView, perspectiveCamera.AspectRatio, perspectiveCamera.Near, perspectiveCamera.Far);
                break;

            case CameraTypes.Ortho:
                IOrthoCamera orthoCamera = this;
                gl.Ortho(orthoCamera.Left, orthoCamera.Right, orthoCamera.Bottom, orthoCamera.Top, orthoCamera.Near, orthoCamera.Far);
                break;

            default:
                break;
            }
            gl.LookAt((double)Position.X, (double)Position.Y, (double)Position.Z,
                      (double)Target.X, (double)Target.Y, (double)Target.Z,
                      (double)UpVector.X, (double)UpVector.Y, (double)UpVector.Z);
        }
 public void Scale(int delta)
 {
     ScientificCamera camera = this;
     //if (camera.CameraType == CameraTypes.Perspecitive)
     {
         var target2Position = camera.Position - camera.Target;
         if (target2Position.Magnitude() < 0.01)
         {
             target2Position.Normalize();
             target2Position.X *= 0.01f;
             target2Position.Y *= 0.01f;
             target2Position.Z *= 0.01f;
         }
         var scaledTarget2Position = target2Position * (1 - delta * 0.001f);
         camera.Position = camera.Target + scaledTarget2Position;
         double lengthDiff = scaledTarget2Position.Magnitude() - target2Position.Magnitude();
         // Increase ortho camera's Near/Far property in case the camera's position changes too much.
         IPerspectiveCamera perspectiveCamera = camera;
         perspectiveCamera.Far += lengthDiff;
         //perspectiveCamera.Near += lengthDiff;
         IOrthoCamera orthoCamera = camera;
         orthoCamera.Far  += lengthDiff;
         orthoCamera.Near += lengthDiff;
     }
     //else if (camera.CameraType == CameraTypes.Ortho)
     {
         IOrthoCamera orthoCamera = camera;
         double       distanceX   = orthoCamera.Right - orthoCamera.Left;
         double       distanceY   = orthoCamera.Top - orthoCamera.Bottom;
         double       centerX     = (orthoCamera.Left + orthoCamera.Right) / 2;
         double       centerY     = (orthoCamera.Bottom + orthoCamera.Top) / 2;
         orthoCamera.Left   = centerX - distanceX * (1 - delta * 0.001) / 2;
         orthoCamera.Right  = centerX + distanceX * (1 - delta * 0.001) / 2;
         orthoCamera.Bottom = centerY - distanceY * (1 - delta * 0.001) / 2;
         orthoCamera.Top    = centerX + distanceY * (1 - delta * 0.001) / 2;
     }
 }
Пример #19
0
        /// <summary>
        /// Apply specifed viewType to camera according to bounding box's size and position.
        /// <para>    +-------+    </para>
        /// <para>   /|      /|    </para>
        /// <para>  +-------+ |    </para>
        /// <para>  | |     | |    </para>
        /// <para>  | O-----|-+---X</para>
        /// <para>  |/      |/     </para>
        /// <para>  +-------+      </para>
        /// <para> /  |            </para>
        /// <para>Y   Z            </para>
        /// <para>其边长为(2 * Math.Sqrt(3)), 所在的坐标系如下</para>
        /// <para>   O---X</para>
        /// <para>  /|    </para>
        /// <para> Y |    </para>
        /// <para>   Z    </para>
        /// </summary>
        /// <param name="camera"></param>
        /// <param name="boundingBox"></param>
        /// <param name="openGL"></param>
        /// <param name="viewType"></param>
        public static void ApplyViewType(this IPerspectiveViewCamera camera, IBoundingBox boundingBox,
                                         OpenGL openGL, ViewTypes viewType, CoordinateSystem coordinateSystem)
        {
            float sizeX, sizeY, sizeZ;

            boundingBox.GetBoundDimensions(out sizeX, out sizeY, out sizeZ);
            float size = Math.Max(Math.Max(sizeX, sizeY), sizeZ);

            {
                float centerX, centerY, centerZ;
                boundingBox.GetCenter(out centerX, out centerY, out centerZ);
                Vertex target = new Vertex(centerX, centerY, centerZ);

                Vertex target2Position;
                Vertex upVector;
                GetBackAndUp(out target2Position, out upVector, viewType, coordinateSystem);

                Vertex position = target + target2Position * (size * 2 + 1);

                camera.Position = position;
                camera.Target   = target;
                camera.UpVector = upVector;
            }

            {
                int[] viewport = new int[4];
                openGL.GetInteger(SharpGL.Enumerations.GetTarget.Viewport, viewport);
                int width = viewport[2]; int height = viewport[3];

                IPerspectiveCamera perspectiveCamera = camera;
                perspectiveCamera.FieldOfView = 60;
                perspectiveCamera.AspectRatio = (double)width / (double)height;
                perspectiveCamera.Near        = 0.01;
                perspectiveCamera.Far         = size * 3 + 1;// double.MaxValue;
            }
        }