(View) Added Map[Pixel|World]To[World|Pixel] method

Former-commit-id: 39295c71d040d472117cb30c266169476f563e9d
This commit is contained in:
Lynix 2015-03-18 20:26:59 +01:00
parent 6648fbe577
commit e873d40ccc
2 changed files with 97 additions and 0 deletions

View File

@ -35,15 +35,20 @@ class NAZARA_API NzView : public NzAbstractViewer, public NzNode, NzRenderTarget
NzVector3f GetGlobalForward() const;
NzVector3f GetGlobalRight() const;
NzVector3f GetGlobalUp() const;
const NzMatrix4f& GetInvViewProjMatrix() const;
const NzMatrix4f& GetProjectionMatrix() const;
const NzVector2f& GetSize() const;
const NzRenderTarget* GetTarget() const;
const NzRectf& GetTargetRegion() const;
const NzMatrix4f& GetViewMatrix() const;
const NzMatrix4f& GetViewProjMatrix() const;
const NzRecti& GetViewport() const;
float GetZFar() const;
float GetZNear() const;
NzVector2i MapWorldToPixel(const NzVector2f& coords);
NzVector2f MapPixelToWorld(const NzVector2i& pixel);
void SetSize(const NzVector2f& size);
void SetSize(float width, float height);
void SetTarget(const NzRenderTarget* renderTarget);
@ -61,20 +66,26 @@ class NAZARA_API NzView : public NzAbstractViewer, public NzNode, NzRenderTarget
bool OnRenderTargetSizeChange(const NzRenderTarget* renderTarget, void* userdata) override;
void UpdateFrustum() const;
void UpdateInvViewProjMatrix() const;
void UpdateProjectionMatrix() const;
void UpdateViewMatrix() const;
void UpdateViewProjMatrix() const;
void UpdateViewport() const;
mutable NzFrustumf m_frustum;
mutable NzMatrix4f m_invViewProjMatrix;
mutable NzMatrix4f m_projectionMatrix;
mutable NzMatrix4f m_viewMatrix;
mutable NzMatrix4f m_viewProjMatrix;
NzRectf m_targetRegion;
mutable NzRecti m_viewport;
NzVector2f m_size;
const NzRenderTarget* m_target;
mutable bool m_frustumUpdated;
mutable bool m_invViewProjMatrixUpdated;
mutable bool m_projectionMatrixUpdated;
mutable bool m_viewMatrixUpdated;
mutable bool m_viewProjMatrixUpdated;
mutable bool m_viewportUpdated;
float m_zFar;
float m_zNear;

View File

@ -13,8 +13,10 @@ m_targetRegion(0.f, 0.f, 1.f, 1.f),
m_size(0.f),
m_target(nullptr),
m_frustumUpdated(false),
m_invViewProjMatrixUpdated(false),
m_projectionMatrixUpdated(false),
m_viewMatrixUpdated(false),
m_viewProjMatrixUpdated(false),
m_viewportUpdated(false),
m_zFar(1.f),
m_zNear(-1.f)
@ -95,6 +97,14 @@ NzVector3f NzView::GetGlobalUp() const
return -NzVector3f::UnitY();
}
const NzMatrix4f& NzView::GetInvViewProjMatrix() const
{
if (!m_invViewProjMatrixUpdated)
UpdateInvViewProjMatrix();
return m_invViewProjMatrix;
}
const NzMatrix4f& NzView::GetProjectionMatrix() const
{
if (!m_projectionMatrixUpdated)
@ -121,6 +131,14 @@ const NzMatrix4f& NzView::GetViewMatrix() const
return m_viewMatrix;
}
const NzMatrix4f& NzView::GetViewProjMatrix() const
{
if (!m_viewProjMatrixUpdated)
UpdateViewProjMatrix();
return m_viewProjMatrix;
}
const NzRecti& NzView::GetViewport() const
{
#if NAZARA_GRAPHICS_SAFE
@ -147,6 +165,44 @@ float NzView::GetZNear() const
return m_zNear;
}
NzVector2i NzView::MapWorldToPixel(const NzVector2f& coords)
{
if (!m_viewProjMatrixUpdated)
UpdateViewProjMatrix();
if (!m_viewportUpdated)
UpdateViewport();
// Conversion du viewport en flottant
NzRectf viewport(m_viewport);
NzVector2f normalized = m_viewProjMatrix.Transform(coords);
NzVector2i pixel;
pixel.x = static_cast<int>(( normalized.x + 1.f) * viewport.width / 2.f + viewport.x);
pixel.y = static_cast<int>((-normalized.y + 1.f) * viewport.width / 2.f + viewport.y);
return pixel;
}
NzVector2f NzView::MapPixelToWorld(const NzVector2i& pixel)
{
if (!m_invViewProjMatrixUpdated)
UpdateInvViewProjMatrix();
if (!m_viewportUpdated)
UpdateViewport();
// Conversion du viewport en flottant
NzRectf viewport(m_viewport);
NzVector2f normalized;
normalized.x = -1.f + 2.f * (pixel.x - viewport.x) / viewport.width;
normalized.y = 1.f - 2.f * (pixel.y - viewport.y) / viewport.height;
return m_invViewProjMatrix.Transform(normalized);
}
void NzView::SetSize(const NzVector2f& size)
{
SetSize(size.x, size.y);
@ -178,7 +234,9 @@ void NzView::SetTargetRegion(const NzRectf& region)
m_targetRegion = region;
m_frustumUpdated = false;
m_invViewProjMatrixUpdated = false;
m_projectionMatrixUpdated = false;
m_viewProjMatrixUpdated = false;
m_viewportUpdated = false;
}
@ -204,7 +262,9 @@ void NzView::SetZFar(float zFar)
m_zFar = zFar;
m_frustumUpdated = false;
m_invViewProjMatrixUpdated = false;
m_projectionMatrixUpdated = false;
m_viewProjMatrixUpdated = false;
}
void NzView::SetZNear(float zNear)
@ -212,7 +272,9 @@ void NzView::SetZNear(float zNear)
m_zNear = zNear;
m_frustumUpdated = false;
m_invViewProjMatrixUpdated = false;
m_projectionMatrixUpdated = false;
m_viewProjMatrixUpdated = false;
}
void NzView::ApplyView() const
@ -246,7 +308,9 @@ void NzView::InvalidateNode()
// Le frustum et la view matrix dépendent des paramètres du node, invalidons-les
m_frustumUpdated = false;
m_invViewProjMatrixUpdated = false;
m_viewMatrixUpdated = false;
m_viewProjMatrixUpdated = false;
}
void NzView::OnRenderTargetReleased(const NzRenderTarget* renderTarget, void* userdata)
@ -287,6 +351,15 @@ void NzView::UpdateFrustum() const
m_frustumUpdated = true;
}
void NzView::UpdateInvViewProjMatrix() const
{
if (!m_viewProjMatrixUpdated)
UpdateViewProjMatrix();
m_viewProjMatrix.GetInverseAffine(&m_invViewProjMatrix);
m_invViewProjMatrixUpdated = true;
}
void NzView::UpdateProjectionMatrix() const
{
if (m_size.x <= 0.f || m_size.y <= 0.f) // Si la taille est nulle, on prendra la taille du viewport
@ -311,6 +384,19 @@ void NzView::UpdateViewMatrix() const
m_viewMatrixUpdated = true;
}
void NzView::UpdateViewProjMatrix() const
{
if (!m_projectionMatrixUpdated)
UpdateProjectionMatrix();
if (!m_viewMatrixUpdated)
UpdateViewMatrix();
// La matrice de projection orthogonale est affine
m_viewProjMatrix = NzMatrix4f::ConcatenateAffine(m_viewMatrix, m_projectionMatrix);
m_viewProjMatrixUpdated = true;
}
void NzView::UpdateViewport() const
{
unsigned int width = m_target->GetWidth();