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); }
///// <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; }
/// <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; } }
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; }
/// <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); }
/// <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; }
/// <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); }
/// <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); }
/// <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; //} } }
/// <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; //} } }
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(); }
// 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; } }
/// <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; } }
/// <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; } }