Ndk: Added CameraComponent (WIP)

Former-commit-id: ae7be5448a1150b7beba10e03916e94df51ea3a0
This commit is contained in:
Lynix
2015-05-05 18:39:47 +02:00
parent a494ce5cca
commit e55b4edd0c
4 changed files with 405 additions and 0 deletions

View File

@@ -0,0 +1,93 @@
// Copyright (C) 2015 Jérôme Leclercq
// This file is part of the "Nazara Development Kit"
// For conditions of distribution and use, see copyright notice in Prerequesites.hpp
#pragma once
#ifndef NDK_COMPONENTS_CAMERACOMPONENT_HPP
#define NDK_COMPONENTS_CAMERACOMPONENT_HPP
#include <Nazara/Math/Frustum.hpp>
#include <Nazara/Math/Matrix4.hpp>
#include <Nazara/Math/Vector3.hpp>
#include <Nazara/Renderer/RenderTarget.hpp>
#include <NDK/Component.hpp>
namespace Ndk
{
class Entity;
class NDK_API CameraComponent : public Component<CameraComponent>, NzRenderTarget::Listener
{
public:
CameraComponent();
~CameraComponent();
void EnsureFrustumUpdate() const;
void EnsureProjectionMatrixUpdate() const;
void EnsureViewMatrixUpdate() const;
void EnsureViewportUpdate() const;
float GetAspectRatio() const;
NzVector3f GetEyePosition() const;
NzVector3f GetForward() const;
float GetFOV() const;
const NzFrustumf& GetFrustum() const;
unsigned int GetLayer() const;
const NzMatrix4f& GetProjectionMatrix() const;
const NzRenderTarget* GetTarget() const;
const NzRectf& GetTargetRegion() const;
const NzMatrix4f& GetViewMatrix() const;
const NzRecti& GetViewport() const;
float GetZFar() const;
float GetZNear() const;
void SetFOV(float fov);
void SetLayer(unsigned int layer);
void SetTarget(const NzRenderTarget* renderTarget);
void SetTargetRegion(const NzRectf& region);
void SetViewport(const NzRecti& viewport);
void SetZFar(float zFar);
void SetZNear(float zNear);
static ComponentIndex componentIndex;
private:
void InvalidateFrustum() const;
void InvalidateProjectionMatrix() const;
void InvalidateViewMatrix() const;
void InvalidateViewport() const;
void OnAttached() override;
void OnComponentAttached(BaseComponent& component) override;
void OnComponentDetached(BaseComponent& component) override;
void OnDetached() override;
void OnRenderTargetReleased(const NzRenderTarget* renderTarget, void* userdata) override;
bool OnRenderTargetSizeChange(const NzRenderTarget* renderTarget, void* userdata) override;
void UpdateFrustum() const;
void UpdateProjectionMatrix() const;
void UpdateViewMatrix() const;
void UpdateViewport() const;
mutable NzFrustumf m_frustum;
mutable NzMatrix4f m_projectionMatrix;
mutable NzMatrix4f m_viewMatrix;
NzRectf m_targetRegion;
mutable NzRecti m_viewport;
const NzRenderTarget* m_target;
mutable bool m_frustumUpdated;
mutable bool m_projectionMatrixUpdated;
mutable bool m_viewMatrixUpdated;
mutable bool m_viewportUpdated;
mutable float m_aspectRatio;
float m_fov;
float m_zFar;
float m_zNear;
unsigned int m_layer;
};
}
#include <NDK/Components/CameraComponent.inl>
#endif // NDK_COMPONENTS_CAMERACOMPONENT_HPP

View File

@@ -0,0 +1,186 @@
// Copyright (C) 2015 Jérôme Leclercq
// This file is part of the "Nazara Development Kit"
// For conditions of distribution and use, see copyright notice in Prerequesites.hpp
#include <Nazara/Core/Error.hpp>
namespace Ndk
{
inline CameraComponent::CameraComponent() :
m_targetRegion(0.f, 0.f, 1.f, 1.f),
m_target(nullptr),
m_frustumUpdated(false),
m_projectionMatrixUpdated(false),
m_viewMatrixUpdated(false),
m_viewportUpdated(false),
m_aspectRatio(0.f),
m_fov(70.f),
m_zFar(100.f),
m_zNear(1.f),
m_layer(0)
{
}
inline CameraComponent::~CameraComponent()
{
if (m_target)
m_target->RemoveListener(this);
}
inline void CameraComponent::EnsureFrustumUpdate() const
{
if (!m_frustumUpdated)
UpdateFrustum();
}
inline void CameraComponent::EnsureProjectionMatrixUpdate() const
{
if (!m_projectionMatrixUpdated)
UpdateProjectionMatrix();
}
inline void CameraComponent::EnsureViewMatrixUpdate() const
{
if (!m_viewMatrixUpdated)
UpdateViewMatrix();
}
inline void CameraComponent::EnsureViewportUpdate() const
{
if (!m_viewportUpdated)
UpdateViewport();
}
inline float CameraComponent::GetAspectRatio() const
{
EnsureViewportUpdate();
return m_aspectRatio;
}
inline float CameraComponent::GetFOV() const
{
return m_fov;
}
inline const NzFrustumf& CameraComponent::GetFrustum() const
{
EnsureFrustumUpdate();
return m_frustum;
}
inline const NzMatrix4f& CameraComponent::GetProjectionMatrix() const
{
EnsureProjectionMatrixUpdate();
return m_projectionMatrix;
}
inline const NzRenderTarget* CameraComponent::GetTarget() const
{
return m_target;
}
inline const NzRectf& CameraComponent::GetTargetRegion() const
{
return m_targetRegion;
}
inline const NzMatrix4f& CameraComponent::GetViewMatrix() const
{
EnsureViewMatrixUpdate();
return m_viewMatrix;
}
inline const NzRecti& CameraComponent::GetViewport() const
{
EnsureViewportUpdate();
return m_viewport;
}
inline float CameraComponent::GetZFar() const
{
return m_zFar;
}
inline float CameraComponent::GetZNear() const
{
return m_zNear;
}
inline void CameraComponent::SetFOV(float fov)
{
NazaraAssert(fov != 0.f, "FOV must be different from zero");
m_fov = fov;
InvalidateProjectionMatrix();
}
inline void CameraComponent::SetTarget(const NzRenderTarget* renderTarget)
{
if (m_target)
m_target->RemoveListener(this);
m_target = renderTarget;
if (m_target)
m_target->AddListener(this);
}
inline void CameraComponent::SetTargetRegion(const NzRectf& region)
{
m_targetRegion = region;
InvalidateViewport();
}
inline void CameraComponent::SetViewport(const NzRecti& viewport)
{
NazaraAssert(m_target, "Component has no render target");
// On calcule la région nécessaire pour produire ce viewport avec la taille actuelle de la cible
float invWidth = 1.f/m_target->GetWidth();
float invHeight = 1.f/m_target->GetHeight();
SetTargetRegion(NzRectf(invWidth * viewport.x, invHeight * viewport.y, invWidth * viewport.width, invHeight * viewport.height));
}
inline void CameraComponent::SetZFar(float zFar)
{
m_zFar = zFar;
InvalidateProjectionMatrix();
}
inline void CameraComponent::SetZNear(float zNear)
{
NazaraAssert(NzNumberEquals(zNear, 0.f), "zNear cannot be zero");
m_zNear = zNear;
InvalidateProjectionMatrix();
}
inline void CameraComponent::InvalidateFrustum() const
{
m_frustumUpdated = false;
}
inline void CameraComponent::InvalidateProjectionMatrix() const
{
m_frustumUpdated = false;
m_projectionMatrixUpdated = false;
}
inline void CameraComponent::InvalidateViewMatrix() const
{
m_frustumUpdated = false;
m_viewMatrixUpdated = false;
}
inline void CameraComponent::InvalidateViewport() const
{
m_frustumUpdated = false;
m_projectionMatrixUpdated = false;
m_viewportUpdated = false;
}
}