66 lines
1.6 KiB
C++
66 lines
1.6 KiB
C++
// Copyright (c) 2012-2022 Wojciech Figat. All rights reserved.
|
|
|
|
#include "Viewport.h"
|
|
#include "Rectangle.h"
|
|
#include "Vector3.h"
|
|
#include "Matrix.h"
|
|
#include "../Types/String.h"
|
|
|
|
Viewport::Viewport(const Rectangle& bounds)
|
|
: X(bounds.Location.X)
|
|
, Y(bounds.Location.Y)
|
|
, Width(bounds.Size.X)
|
|
, Height(bounds.Size.Y)
|
|
, MinDepth(0.0f)
|
|
, MaxDepth(1.0f)
|
|
{
|
|
}
|
|
|
|
String Viewport::ToString() const
|
|
{
|
|
return String::Format(TEXT("{}"), *this);
|
|
}
|
|
|
|
Rectangle Viewport::GetBounds() const
|
|
{
|
|
return Rectangle(X, Y, Width, Height);
|
|
}
|
|
|
|
void Viewport::SetBounds(const Rectangle& bounds)
|
|
{
|
|
X = bounds.Location.X;
|
|
Y = bounds.Location.Y;
|
|
Width = bounds.Size.X;
|
|
Height = bounds.Size.Y;
|
|
}
|
|
|
|
void Viewport::Project(const Vector3& source, const Matrix& vp, Vector3& result) const
|
|
{
|
|
Vector3::Transform(source, vp, result);
|
|
const Real a = source.X * vp.M14 + source.Y * vp.M24 + source.Z * vp.M34 + vp.M44;
|
|
|
|
if (!Math::IsOne(a))
|
|
{
|
|
result /= a;
|
|
}
|
|
|
|
result.X = (result.X + 1.0f) * 0.5f * Width + X;
|
|
result.Y = (-result.Y + 1.0f) * 0.5f * Height + Y;
|
|
result.Z = result.Z * (MaxDepth - MinDepth) + MinDepth;
|
|
}
|
|
|
|
void Viewport::Unproject(const Vector3& source, const Matrix& ivp, Vector3& result) const
|
|
{
|
|
result.X = (source.X - X) / Width * 2.0f - 1.0f;
|
|
result.Y = -((source.Y - Y) / Height * 2.0f - 1.0f);
|
|
result.Z = (source.Z - MinDepth) / (MaxDepth - MinDepth);
|
|
|
|
const Real a = result.X * ivp.M14 + result.Y * ivp.M24 + result.Z * ivp.M34 + ivp.M44;
|
|
Vector3::Transform(result, ivp, result);
|
|
|
|
if (!Math::IsOne(a))
|
|
{
|
|
result /= a;
|
|
}
|
|
}
|