204 lines
4.1 KiB
C++
204 lines
4.1 KiB
C++
#ifndef Light_h__
|
|
#define Light_h__
|
|
#include "IGraphicsNode.h"
|
|
#include "math/Vector3D.h"
|
|
#include "math/Vector4D.h"
|
|
#include "camera/Frustum.h"
|
|
|
|
namespace LifeGraphics
|
|
{
|
|
enum LIGHT_TYPE
|
|
{
|
|
LT_POINT = 0,
|
|
LT_SPOT = 1,
|
|
LT_DIRECTIONAL = 2
|
|
};
|
|
class Light : public IGraphicsNode
|
|
{
|
|
public:
|
|
Light(LIGHT_TYPE lt)
|
|
: range(1), innerAngle(0.5f), outerAngle(0.6f), direction(0.0f, -1.0f, 0.0f),
|
|
position(0.0f,0.0f, 0.0f), up(0.0f, 1.0f, 0.0f), color(1.0f, 0.0f, 1.0f),
|
|
intensity(1.0f), isMatrixValid(false), castShadows(false)
|
|
{
|
|
lightType = lt;
|
|
}
|
|
Light()
|
|
: lightType(LT_POINT), range(1), innerAngle(0.5f), outerAngle(0.6f), direction(0.0f, -1.0f, 0.0f),
|
|
position(0.0f,0.0f, 0.0f), up(0.0f, 1.0f, 0.0f), color(1.0f, 0.0f, 1.0f),
|
|
intensity(1.0f), isMatrixValid(false), castShadows(false)
|
|
{
|
|
}
|
|
~Light()
|
|
{
|
|
}
|
|
NodeType getType()
|
|
{
|
|
return NT_LIGHT;
|
|
}
|
|
void setDirection(const LifeMath::float3& dir)
|
|
{
|
|
direction = dir;
|
|
isMatrixValid = false;
|
|
//this->bSphere.center = this->_position;
|
|
//this->bSphere.radius = this->range;
|
|
}
|
|
|
|
const LifeMath::float4x4& getMatrix()
|
|
{
|
|
fixupTransform();
|
|
return matrix;
|
|
}
|
|
|
|
const LifeMath::float4x4& getView()
|
|
{
|
|
fixupTransform();
|
|
return mView;
|
|
}
|
|
const LifeMath::float4x4& getProj()
|
|
{
|
|
fixupTransform();
|
|
return mProj;
|
|
}
|
|
LifeMath::float3 getDirection()
|
|
{
|
|
fixupTransform();
|
|
return direction;
|
|
}
|
|
LifeMath::float3 getPosition()
|
|
{
|
|
fixupTransform();
|
|
return position;
|
|
}
|
|
void setInnerAngle(float angle)
|
|
{
|
|
innerAngle = angle;
|
|
if(innerAngle > 3.1415f)
|
|
innerAngle = 3.1415f;
|
|
isMatrixValid = false;
|
|
}
|
|
float getInnerAngle()
|
|
{
|
|
return innerAngle;
|
|
}
|
|
void setOuterAngle(float angle)
|
|
{
|
|
outerAngle = angle;
|
|
if(outerAngle<innerAngle)
|
|
outerAngle = innerAngle;
|
|
isMatrixValid = false;
|
|
}
|
|
float getOuterAngle()
|
|
{
|
|
return outerAngle;
|
|
}
|
|
void setRange(float _range)
|
|
{
|
|
range = _range;
|
|
this->bSphere.radius = this->range;
|
|
isMatrixValid = false;
|
|
}
|
|
float getRange()
|
|
{
|
|
return range;
|
|
}
|
|
void update(float dt)
|
|
{
|
|
fixupTransform();
|
|
}
|
|
LifeMath::float4x4 getMeshMatrix()
|
|
{
|
|
float baseRadius = tanf(outerAngle * 0.5f) * range * 1.1f;
|
|
LifeMath::float4x4 b;
|
|
Mat4x4Scaling(baseRadius, baseRadius, range, b);
|
|
|
|
LifeMath::float3 right;
|
|
LifeMath::float3 orthoUp;
|
|
LifeMath::float3 dir = direction - position;
|
|
LifeMath::Vec3Normalize(&dir);
|
|
LifeMath::Vec3Cross(up, dir, right);
|
|
LifeMath::Vec3Cross(dir, right, orthoUp);
|
|
LifeMath::Vec3Normalize(&orthoUp);
|
|
|
|
LifeMath::float4x4 r;
|
|
Mat4x4Identity(&r);
|
|
|
|
r.M11 = right.X;
|
|
r.M12 = right.Y;
|
|
r.M13 = right.Z;
|
|
|
|
r.M21 = orthoUp.X;
|
|
r.M22 = orthoUp.Y;
|
|
r.M23 = orthoUp.Z;
|
|
|
|
r.M31 = dir.X;
|
|
r.M32 = dir.Y;
|
|
r.M33 = dir.Z;
|
|
|
|
LifeMath::float3 pos = transform->GetPosition();
|
|
r.M41 = pos.X;
|
|
r.M42 = pos.Y;
|
|
r.M43 = pos.Z;
|
|
|
|
return b * r;
|
|
}
|
|
Frustum* getFrustum()
|
|
{
|
|
if(!isMatrixValid)
|
|
computeMatrix();
|
|
return &frustum;
|
|
}
|
|
LIGHT_TYPE lightType;
|
|
|
|
LifeMath::float3 color;
|
|
float specularPower;
|
|
float intensity;
|
|
bool castShadows;
|
|
private:
|
|
void fixupTransform()
|
|
{
|
|
if(position!= transform->GetPosition())
|
|
{
|
|
position = transform->GetPosition();
|
|
isMatrixValid = false;
|
|
this->bSphere.center = position;
|
|
this->bSphere.radius = range;
|
|
}
|
|
if(!isMatrixValid)
|
|
{
|
|
computeMatrix();
|
|
}
|
|
}
|
|
void computeMatrix()
|
|
{
|
|
LifeMath::float3 dir = direction - position;
|
|
LifeMath::Vec3Normalize(&dir);
|
|
|
|
float angle = LifeMath::Vec3Dot(&up, &dir);
|
|
if((angle>0.9f) | (angle<-0.9f))
|
|
up = LifeMath::float3(0.0f,0.0f,1.0f);
|
|
else
|
|
up = LifeMath::float3(0.0f,1.0f,0.0f);
|
|
|
|
LifeMath::Mat4x4LookAtLH(position,direction,up,mView);
|
|
LifeMath::Mat4x4PerspectiveFOV(outerAngle,1.0f,0.1f,range, mProj);
|
|
matrix = mView * mProj;
|
|
|
|
frustum.UpdateFrustum(matrix);
|
|
|
|
isMatrixValid = true;
|
|
}
|
|
LifeMath::float3 up;
|
|
bool isMatrixValid;
|
|
LifeMath::float4x4 matrix;
|
|
LifeMath::float4x4 mView;
|
|
LifeMath::float4x4 mProj;
|
|
float range;
|
|
LifeMath::float3 direction;
|
|
LifeMath::float3 position;
|
|
float innerAngle;
|
|
float outerAngle;
|
|
Frustum frustum;
|
|
};
|
|
}
|
|
#endif // Light_h__
|