123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165 |
- /*
- * Copyright (c) Contributors, http://opensimulator.org/
- * See CONTRIBUTORS.TXT for a full list of copyright holders.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * * Neither the name of the OpenSimulator Project nor the
- * names of its contributors may be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
- using System;
- using System.Drawing;
- using OpenMetaverse;
- namespace OpenSim.Region.CoreModules.World.Warp3DMap
- {
- public class Viewport
- {
- private const float DEG_TO_RAD = (float)Math.PI / 180f;
- private static readonly Vector3 UP_DIRECTION = Vector3.UnitZ;
- public Vector3 Position;
- public Vector3 LookDirection;
- public float FieldOfView;
- public float NearPlaneDistance;
- public float FarPlaneDistance;
- public int Width;
- public int Height;
- public bool Orthographic;
- public float OrthoWindowWidth;
- public float OrthoWindowHeight;
- public Viewport(Vector3 position, Vector3 lookDirection, float fieldOfView, float farPlaneDist, float nearPlaneDist, int width, int height)
- {
- // Perspective projection mode
- Position = position;
- LookDirection = lookDirection;
- FieldOfView = fieldOfView;
- FarPlaneDistance = farPlaneDist;
- NearPlaneDistance = nearPlaneDist;
- Width = width;
- Height = height;
- }
- public Viewport(Vector3 position, Vector3 lookDirection, float farPlaneDist, float nearPlaneDist, int width, int height, float orthoWindowWidth, float orthoWindowHeight)
- {
- // Orthographic projection mode
- Position = position;
- LookDirection = lookDirection;
- FarPlaneDistance = farPlaneDist;
- NearPlaneDistance = nearPlaneDist;
- Width = width;
- Height = height;
- OrthoWindowWidth = orthoWindowWidth;
- OrthoWindowHeight = orthoWindowHeight;
- Orthographic = true;
- }
- public Point VectorToScreen(Vector3 v)
- {
- Matrix4 m = GetWorldToViewportMatrix();
- Vector3 screenPoint = v * m;
- return new Point((int)screenPoint.X, (int)screenPoint.Y);
- }
- public Matrix4 GetWorldToViewportMatrix()
- {
- Matrix4 result = GetViewMatrix();
- result *= GetPerspectiveProjectionMatrix();
- result *= GetViewportMatrix();
- return result;
- }
- public Matrix4 GetViewMatrix()
- {
- Vector3 zAxis = -LookDirection;
- zAxis.Normalize();
- Vector3 xAxis = Vector3.Cross(UP_DIRECTION, zAxis);
- xAxis.Normalize();
- Vector3 yAxis = Vector3.Cross(zAxis, xAxis);
- Vector3 position = Position;
- float offsetX = -Vector3.Dot(xAxis, position);
- float offsetY = -Vector3.Dot(yAxis, position);
- float offsetZ = -Vector3.Dot(zAxis, position);
- return new Matrix4(
- xAxis.X, yAxis.X, zAxis.X, 0f,
- xAxis.Y, yAxis.Y, zAxis.Y, 0f,
- xAxis.Z, yAxis.Z, zAxis.Z, 0f,
- offsetX, offsetY, offsetZ, 1f);
- }
- public Matrix4 GetPerspectiveProjectionMatrix()
- {
- float aspectRatio = (float)Width / (float)Height;
- float hFoV = FieldOfView * DEG_TO_RAD;
- float zn = NearPlaneDistance;
- float zf = FarPlaneDistance;
- float xScale = 1f / (float)Math.Tan(hFoV / 2f);
- float yScale = aspectRatio * xScale;
- float m33 = (zf == double.PositiveInfinity) ? -1 : (zf / (zn - zf));
- float m43 = zn * m33;
- return new Matrix4(
- xScale, 0f, 0f, 0f,
- 0f, yScale, 0f, 0f,
- 0f, 0f, m33, -1f,
- 0f, 0f, m43, 0f);
- }
- public Matrix4 GetOrthographicProjectionMatrix(float aspectRatio)
- {
- float w = Width;
- float h = Height;
- float zn = NearPlaneDistance;
- float zf = FarPlaneDistance;
- float m33 = 1 / (zn - zf);
- float m43 = zn * m33;
- return new Matrix4(
- 2f / w, 0f, 0f, 0f,
- 0f, 2f / h, 0f, 0f,
- 0f, 0f, m33, 0f,
- 0f, 0f, m43, 1f);
- }
- public Matrix4 GetViewportMatrix()
- {
- float scaleX = (float)Width * 0.5f;
- float scaleY = (float)Height * 0.5f;
- float offsetX = 0f + scaleX;
- float offsetY = 0f + scaleY;
- return new Matrix4(
- scaleX, 0f, 0f, 0f,
- 0f, -scaleY, 0f, 0f,
- 0f, 0f, 1f, 0f,
- offsetX, offsetY, 0f, 1f);
- }
- }
- }
|