/Source/Engine/GreenBox3D/Graphics/Viewport.cs

https://bitbucket.org/greenboxdevelopment/greenbox3d · C# · 176 lines · 136 code · 34 blank · 6 comment · 7 complexity · bce67b5178dcef9c632a20c11674adb4 MD5 · raw file

  1. // Viewport.cs
  2. //
  3. // Copyright (c) 2013 The GreenBox Development LLC, all rights reserved
  4. //
  5. // This file is a proprietary part of GreenBox3D, disclosing the content
  6. // of this file without the owner consent may lead to legal actions
  7. using System;
  8. using System.Collections.Generic;
  9. using System.Linq;
  10. using System.Text;
  11. using System.Threading.Tasks;
  12. namespace GreenBox3D.Graphics
  13. {
  14. [Serializable]
  15. public struct Viewport
  16. {
  17. #region Fields
  18. private int _height;
  19. private float _maxDepth;
  20. private float _minDepth;
  21. private int _width;
  22. private int _x;
  23. private int _y;
  24. #endregion
  25. #region Constructors and Destructors
  26. public Viewport(int x, int y, int width, int height)
  27. {
  28. _x = x;
  29. _y = y;
  30. _width = width;
  31. _height = height;
  32. _minDepth = 0.0f;
  33. _maxDepth = 1.0f;
  34. }
  35. public Viewport(Rectangle bounds)
  36. : this(bounds.X, bounds.Y, bounds.Width, bounds.Height)
  37. {
  38. }
  39. #endregion
  40. #region Public Properties
  41. public float AspectRatio
  42. {
  43. get
  44. {
  45. if ((_height != 0) && (_width != 0))
  46. return ((_width) / ((float)_height));
  47. return 0f;
  48. }
  49. }
  50. public Rectangle Bounds
  51. {
  52. get
  53. {
  54. Rectangle rectangle = new Rectangle();
  55. rectangle.X = _x;
  56. rectangle.Y = _y;
  57. rectangle.Width = _width;
  58. rectangle.Height = _height;
  59. return rectangle;
  60. }
  61. set
  62. {
  63. _x = value.X;
  64. _y = value.Y;
  65. _width = value.Width;
  66. _height = value.Height;
  67. }
  68. }
  69. public int Height
  70. {
  71. get { return _height; }
  72. set { _height = value; }
  73. }
  74. public float MaxDepth
  75. {
  76. get { return _maxDepth; }
  77. set { _maxDepth = value; }
  78. }
  79. public float MinDepth
  80. {
  81. get { return _minDepth; }
  82. set { _minDepth = value; }
  83. }
  84. public Rectangle TitleSafeArea
  85. {
  86. get { return new Rectangle(_x, _y, _width, _height); }
  87. }
  88. public int Width
  89. {
  90. get { return _width; }
  91. set { _width = value; }
  92. }
  93. public int X
  94. {
  95. get { return _x; }
  96. set { _x = value; }
  97. }
  98. public int Y
  99. {
  100. get { return _y; }
  101. set { _y = value; }
  102. }
  103. #endregion
  104. #region Public Methods and Operators
  105. public Vector3 Project(Vector3 source, Matrix4 projection, Matrix4 view, Matrix4 world)
  106. {
  107. Matrix4 matrix = Matrix4.Mult(Matrix4.Mult(world, view), projection);
  108. Vector3 vector = Vector3.Transform(source, matrix);
  109. float a = (((source.X * matrix.M14) + (source.Y * matrix.M24)) + (source.Z * matrix.M34)) + matrix.M44;
  110. if (!WithinEpsilon(a, 1f))
  111. vector = (vector / a);
  112. vector.X = (((vector.X + 1f) * 0.5f) * Width) + X;
  113. vector.Y = (((-vector.Y + 1f) * 0.5f) * Height) + Y;
  114. vector.Z = (vector.Z * (MaxDepth - MinDepth)) + MinDepth;
  115. return vector;
  116. }
  117. public override string ToString()
  118. {
  119. return string.Format("[Viewport: X={0} Y={1} Width={2} Height={3}]", X, Y, Width, Height);
  120. }
  121. public Vector3 Unproject(Vector3 source, Matrix4 projection, Matrix4 view, Matrix4 world)
  122. {
  123. Matrix4 matrix = Matrix4.Invert(Matrix4.Mult(Matrix4.Mult(world, view), projection));
  124. source.X = (((source.X - X) / (Width)) * 2f) - 1f;
  125. source.Y = -((((source.Y - Y) / (Height)) * 2f) - 1f);
  126. source.Z = (source.Z - MinDepth) / (MaxDepth - MinDepth);
  127. Vector3 vector = Vector3.Transform(source, matrix);
  128. float a = (((source.X * matrix.M14) + (source.Y * matrix.M24)) + (source.Z * matrix.M34)) + matrix.M44;
  129. if (!WithinEpsilon(a, 1f))
  130. vector = (vector / a);
  131. return vector;
  132. }
  133. #endregion
  134. #region Methods
  135. private static bool WithinEpsilon(float a, float b)
  136. {
  137. float num = a - b;
  138. return ((-1.401298E-45f <= num) && (num <= float.Epsilon));
  139. }
  140. #endregion
  141. }
  142. }