Added lights bounding box
Former-commit-id: 9ab45181c8b0586e9d4040d48d756683e88dd8fe
This commit is contained in:
parent
1e57c00fa1
commit
593fec134d
|
|
@ -47,17 +47,18 @@ class NAZARA_API NzLight : public NzSceneNode
|
||||||
NzLight& operator=(const NzLight& light);
|
NzLight& operator=(const NzLight& light);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void Invalidate();
|
||||||
void Register();
|
void Register();
|
||||||
void Unregister();
|
void Unregister();
|
||||||
void UpdateFrustum();
|
void UpdateBoundingBox() const;
|
||||||
bool VisibilityTest(const NzFrustumf& frustum);
|
bool VisibilityTest(const NzFrustumf& frustum);
|
||||||
|
|
||||||
nzLightType m_type;
|
nzLightType m_type;
|
||||||
NzBoundingBoxf m_boundingBox;
|
mutable NzBoundingBoxf m_boundingBox;
|
||||||
NzColor m_ambientColor;
|
NzColor m_ambientColor;
|
||||||
NzColor m_diffuseColor;
|
NzColor m_diffuseColor;
|
||||||
NzColor m_specularColor;
|
NzColor m_specularColor;
|
||||||
bool m_boundingBoxUpdated;
|
mutable bool m_boundingBoxUpdated;
|
||||||
float m_attenuation;
|
float m_attenuation;
|
||||||
float m_innerAngle;
|
float m_innerAngle;
|
||||||
float m_outerAngle;
|
float m_outerAngle;
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
#include <Nazara/3D/Light.hpp>
|
#include <Nazara/3D/Light.hpp>
|
||||||
#include <Nazara/Core/Error.hpp>
|
#include <Nazara/Core/Error.hpp>
|
||||||
#include <Nazara/Math/Basic.hpp>
|
#include <Nazara/Math/Basic.hpp>
|
||||||
|
#include <Nazara/Math/Sphere.hpp>
|
||||||
#include <Nazara/Renderer/Renderer.hpp>
|
#include <Nazara/Renderer/Renderer.hpp>
|
||||||
#include <Nazara/Renderer/Shader.hpp>
|
#include <Nazara/Renderer/Shader.hpp>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
@ -130,8 +131,10 @@ void NzLight::Apply(const NzShader* shader, unsigned int lightUnit) const
|
||||||
|
|
||||||
const NzBoundingBoxf& NzLight::GetBoundingBox() const
|
const NzBoundingBoxf& NzLight::GetBoundingBox() const
|
||||||
{
|
{
|
||||||
static NzBoundingBoxf dummy(nzExtend_Null);
|
if (!m_boundingBoxUpdated)
|
||||||
return dummy;
|
UpdateBoundingBox();
|
||||||
|
|
||||||
|
return m_boundingBox;
|
||||||
}
|
}
|
||||||
|
|
||||||
NzColor NzLight::GetAmbientColor() const
|
NzColor NzLight::GetAmbientColor() const
|
||||||
|
|
@ -202,11 +205,17 @@ void NzLight::SetInnerAngle(float innerAngle)
|
||||||
void NzLight::SetOuterAngle(float outerAngle)
|
void NzLight::SetOuterAngle(float outerAngle)
|
||||||
{
|
{
|
||||||
m_outerAngle = outerAngle;
|
m_outerAngle = outerAngle;
|
||||||
|
|
||||||
|
m_boundingBox.MakeNull();
|
||||||
|
m_boundingBoxUpdated = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void NzLight::SetRadius(float radius)
|
void NzLight::SetRadius(float radius)
|
||||||
{
|
{
|
||||||
m_radius = radius;
|
m_radius = radius;
|
||||||
|
|
||||||
|
m_boundingBox.MakeNull();
|
||||||
|
m_boundingBoxUpdated = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void NzLight::SetSpecularColor(const NzColor& specular)
|
void NzLight::SetSpecularColor(const NzColor& specular)
|
||||||
|
|
@ -221,6 +230,13 @@ NzLight& NzLight::operator=(const NzLight& light)
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NzLight::Invalidate()
|
||||||
|
{
|
||||||
|
NzSceneNode::Invalidate();
|
||||||
|
|
||||||
|
m_boundingBoxUpdated = false;
|
||||||
|
}
|
||||||
|
|
||||||
void NzLight::Register()
|
void NzLight::Register()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
@ -229,10 +245,95 @@ void NzLight::Unregister()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NzLight::UpdateBoundingBox() const
|
||||||
|
{
|
||||||
|
if (m_boundingBox.IsNull())
|
||||||
|
{
|
||||||
|
switch (m_type)
|
||||||
|
{
|
||||||
|
case nzLightType_Directional:
|
||||||
|
m_boundingBox.MakeInfinite();
|
||||||
|
m_boundingBoxUpdated = true;
|
||||||
|
return; // Rien d'autre à faire
|
||||||
|
|
||||||
|
case nzLightType_Point:
|
||||||
|
{
|
||||||
|
NzVector3f radius(m_radius);
|
||||||
|
m_boundingBox.Set(-radius, radius);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case nzLightType_Spot:
|
||||||
|
{
|
||||||
|
// On forme un cube sur l'origine
|
||||||
|
NzCubef cube(NzVector3f::Zero());
|
||||||
|
|
||||||
|
// On calcule le reste des points
|
||||||
|
float height = m_radius;
|
||||||
|
NzVector3f base(NzVector3f::Forward()*height);
|
||||||
|
|
||||||
|
// Il nous faut maintenant le rayon du cercle projeté à cette distance
|
||||||
|
// Tangente = Opposé/Adjaçent <=> Opposé = Adjaçent*Tangente
|
||||||
|
float radius = height*std::tan(NzDegreeToRadian(m_outerAngle));
|
||||||
|
NzVector3f lExtend = NzVector3f::Left()*radius;
|
||||||
|
NzVector3f uExtend = NzVector3f::Up()*radius;
|
||||||
|
|
||||||
|
// Et on ajoute ensuite les quatres extrêmités de la pyramide
|
||||||
|
cube.ExtendTo(base + lExtend + uExtend);
|
||||||
|
cube.ExtendTo(base + lExtend - uExtend);
|
||||||
|
cube.ExtendTo(base - lExtend + uExtend);
|
||||||
|
cube.ExtendTo(base - lExtend - uExtend);
|
||||||
|
|
||||||
|
m_boundingBox.Set(cube);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (m_type)
|
||||||
|
{
|
||||||
|
case nzLightType_Directional:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case nzLightType_Point:
|
||||||
|
if (!m_derivedUpdated)
|
||||||
|
UpdateDerived();
|
||||||
|
|
||||||
|
m_boundingBox.Update(NzMatrix4f::Translate(m_derivedPosition)); // Notre BoundingBox ne changera que selon la position
|
||||||
|
break;
|
||||||
|
|
||||||
|
case nzLightType_Spot:
|
||||||
|
if (!m_transformMatrixUpdated)
|
||||||
|
UpdateTransformMatrix();
|
||||||
|
|
||||||
|
m_boundingBox.Update(m_transformMatrix);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_boundingBoxUpdated = true;
|
||||||
|
}
|
||||||
|
|
||||||
bool NzLight::VisibilityTest(const NzFrustumf& frustum)
|
bool NzLight::VisibilityTest(const NzFrustumf& frustum)
|
||||||
{
|
{
|
||||||
NazaraUnused(frustum);
|
switch (m_type)
|
||||||
|
{
|
||||||
|
case nzLightType_Directional:
|
||||||
|
return true; // Toujours visible
|
||||||
|
|
||||||
///FIXME: Pour l'instant toujours visible
|
case nzLightType_Point:
|
||||||
return true; // Toujours visible
|
if (!m_derivedUpdated)
|
||||||
|
UpdateDerived();
|
||||||
|
|
||||||
|
// Un test sphérique est bien plus rapide et précis que celui de la bounding box
|
||||||
|
return frustum.Contains(NzSpheref(m_derivedPosition, m_radius));
|
||||||
|
|
||||||
|
case nzLightType_Spot:
|
||||||
|
if (!m_boundingBoxUpdated)
|
||||||
|
UpdateBoundingBox();
|
||||||
|
|
||||||
|
return frustum.Contains(m_boundingBox);
|
||||||
|
}
|
||||||
|
|
||||||
|
NazaraError("Invalid light type (0x" + NzString::Number(m_type, 16) + ')');
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue