Viewport.cs 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. /*
  2. * Copyright (c) Contributors, http://opensimulator.org/
  3. * See CONTRIBUTORS.TXT for a full list of copyright holders.
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions are met:
  7. * * Redistributions of source code must retain the above copyright
  8. * notice, this list of conditions and the following disclaimer.
  9. * * Redistributions in binary form must reproduce the above copyright
  10. * notice, this list of conditions and the following disclaimer in the
  11. * documentation and/or other materials provided with the distribution.
  12. * * Neither the name of the OpenSimulator Project nor the
  13. * names of its contributors may be used to endorse or promote products
  14. * derived from this software without specific prior written permission.
  15. *
  16. * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
  17. * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  18. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  19. * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
  20. * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  21. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  22. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  23. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  24. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  25. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  26. */
  27. using System;
  28. using System.Drawing;
  29. using OpenMetaverse;
  30. namespace OpenSim.Region.CoreModules.World.Warp3DMap
  31. {
  32. public class Viewport
  33. {
  34. private const float DEG_TO_RAD = (float)Math.PI / 180f;
  35. private static readonly Vector3 UP_DIRECTION = Vector3.UnitZ;
  36. public Vector3 Position;
  37. public Vector3 LookDirection;
  38. public float FieldOfView;
  39. public float NearPlaneDistance;
  40. public float FarPlaneDistance;
  41. public int Width;
  42. public int Height;
  43. public bool Orthographic;
  44. public float OrthoWindowWidth;
  45. public float OrthoWindowHeight;
  46. public Viewport(Vector3 position, Vector3 lookDirection, float fieldOfView, float farPlaneDist, float nearPlaneDist, int width, int height)
  47. {
  48. // Perspective projection mode
  49. Position = position;
  50. LookDirection = lookDirection;
  51. FieldOfView = fieldOfView;
  52. FarPlaneDistance = farPlaneDist;
  53. NearPlaneDistance = nearPlaneDist;
  54. Width = width;
  55. Height = height;
  56. }
  57. public Viewport(Vector3 position, Vector3 lookDirection, float farPlaneDist, float nearPlaneDist, int width, int height, float orthoWindowWidth, float orthoWindowHeight)
  58. {
  59. // Orthographic projection mode
  60. Position = position;
  61. LookDirection = lookDirection;
  62. FarPlaneDistance = farPlaneDist;
  63. NearPlaneDistance = nearPlaneDist;
  64. Width = width;
  65. Height = height;
  66. OrthoWindowWidth = orthoWindowWidth;
  67. OrthoWindowHeight = orthoWindowHeight;
  68. Orthographic = true;
  69. }
  70. public Point VectorToScreen(Vector3 v)
  71. {
  72. Matrix4 m = GetWorldToViewportMatrix();
  73. Vector3 screenPoint = v * m;
  74. return new Point((int)screenPoint.X, (int)screenPoint.Y);
  75. }
  76. public Matrix4 GetWorldToViewportMatrix()
  77. {
  78. Matrix4 result = GetViewMatrix();
  79. result *= GetPerspectiveProjectionMatrix();
  80. result *= GetViewportMatrix();
  81. return result;
  82. }
  83. public Matrix4 GetViewMatrix()
  84. {
  85. Vector3 zAxis = -LookDirection;
  86. zAxis.Normalize();
  87. Vector3 xAxis = Vector3.Cross(UP_DIRECTION, zAxis);
  88. xAxis.Normalize();
  89. Vector3 yAxis = Vector3.Cross(zAxis, xAxis);
  90. Vector3 position = Position;
  91. float offsetX = -Vector3.Dot(xAxis, position);
  92. float offsetY = -Vector3.Dot(yAxis, position);
  93. float offsetZ = -Vector3.Dot(zAxis, position);
  94. return new Matrix4(
  95. xAxis.X, yAxis.X, zAxis.X, 0f,
  96. xAxis.Y, yAxis.Y, zAxis.Y, 0f,
  97. xAxis.Z, yAxis.Z, zAxis.Z, 0f,
  98. offsetX, offsetY, offsetZ, 1f);
  99. }
  100. public Matrix4 GetPerspectiveProjectionMatrix()
  101. {
  102. float aspectRatio = (float)Width / (float)Height;
  103. float hFoV = FieldOfView * DEG_TO_RAD;
  104. float zn = NearPlaneDistance;
  105. float zf = FarPlaneDistance;
  106. float xScale = 1f / (float)Math.Tan(hFoV / 2f);
  107. float yScale = aspectRatio * xScale;
  108. float m33 = (zf == double.PositiveInfinity) ? -1 : (zf / (zn - zf));
  109. float m43 = zn * m33;
  110. return new Matrix4(
  111. xScale, 0f, 0f, 0f,
  112. 0f, yScale, 0f, 0f,
  113. 0f, 0f, m33, -1f,
  114. 0f, 0f, m43, 0f);
  115. }
  116. public Matrix4 GetOrthographicProjectionMatrix(float aspectRatio)
  117. {
  118. float w = Width;
  119. float h = Height;
  120. float zn = NearPlaneDistance;
  121. float zf = FarPlaneDistance;
  122. float m33 = 1 / (zn - zf);
  123. float m43 = zn * m33;
  124. return new Matrix4(
  125. 2f / w, 0f, 0f, 0f,
  126. 0f, 2f / h, 0f, 0f,
  127. 0f, 0f, m33, 0f,
  128. 0f, 0f, m43, 1f);
  129. }
  130. public Matrix4 GetViewportMatrix()
  131. {
  132. float scaleX = (float)Width * 0.5f;
  133. float scaleY = (float)Height * 0.5f;
  134. float offsetX = 0f + scaleX;
  135. float offsetY = 0f + scaleY;
  136. return new Matrix4(
  137. scaleX, 0f, 0f, 0f,
  138. 0f, -scaleY, 0f, 0f,
  139. 0f, 0f, 1f, 0f,
  140. offsetX, offsetY, 0f, 1f);
  141. }
  142. }
  143. }