| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347 |
- #ifndef ANKI_SCENE_LIGHT_H
- #define ANKI_SCENE_LIGHT_H
- #include "anki/scene/SceneNode.h"
- #include "anki/scene/MoveComponent.h"
- #include "anki/scene/FrustumComponent.h"
- #include "anki/scene/SpatialComponent.h"
- #include "anki/resource/Resource.h"
- #include "anki/resource/TextureResource.h"
- namespace anki {
- /// XXX
- class FlareBatch
- {
- public:
- static constexpr U MAX_FLARES = 10;
- enum FlareFlag
- {
- POSITION_LIGHT = 1 << 0,
- POSITION_FLOATING = 1 << 1
- };
- private:
- /// A 2D array texture with the flare textures
- TextureResourcePointer flaresTex;
- /// The size of each flare
- Array<Vec2, MAX_FLARES> size;
- Array<Vec2, MAX_FLARES> stretchMultiplier;
- F32 flaresAlpha = 1.0;
- };
- /// Light scene node. It can be spot or point
- ///
- /// Explaining the lighting model:
- /// @code
- /// Final intensity: If = Ia + Id + Is
- /// Ambient intensity: Ia = Al * Am
- /// Ambient intensity of light: Al
- /// Ambient intensity of material: Am
- /// Diffuse intensity: Id = Dl * Dm * LambertTerm
- /// Diffuse intensity of light: Dl
- /// Diffuse intensity of material: Dm
- /// LambertTerm: max(Normal dot Light, 0.0)
- /// Specular intensity: Is = Sm * Sl * pow(max(R dot E, 0.0), f)
- /// Specular intensity of light: Sl
- /// Specular intensity of material: Sm
- /// @endcode
- class Light: public SceneNode, public MoveComponent, public SpatialComponent
- {
- public:
- enum LightType
- {
- LT_POINT,
- LT_SPOT,
- LT_NUM
- };
- /// @name Constructors
- /// @{
- Light(
- const char* name, SceneGraph* scene, // SceneNode
- CollisionShape* cs, // SpatialComponent
- LightType t); // Self
- /// @}
- virtual ~Light();
- /// @name Accessors
- /// @{
- LightType getLightType() const
- {
- return type;
- }
- const Vec4& getDiffuseColor() const
- {
- return color;
- }
- Vec4& getDiffuseColor()
- {
- return color;
- }
- void setDiffuseColor(const Vec4& x)
- {
- color = x;
- }
- const Vec4& getSpecularColor() const
- {
- return specColor;
- }
- Vec4& getSpecularColor()
- {
- return specColor;
- }
- void setSpecularColor(const Vec4& x)
- {
- specColor = x;
- }
- Bool getShadowEnabled() const
- {
- return shadow;
- }
- void setShadowEnabled(const Bool x)
- {
- shadow = x;
- }
- U getShadowMapIndex() const
- {
- return (U)shadowMapIndex;
- }
- void setShadowMapIndex(const U i)
- {
- ANKI_ASSERT(i < 0xFF);
- shadowMapIndex = (U8)i;
- }
- Bool hasLensFlare() const
- {
- return flaresTex.isLoaded();
- }
- const Texture& getLensFlareTexture() const
- {
- ANKI_ASSERT(hasLensFlare());
- return *flaresTex;
- }
- const Vec2& getLensFlaresSize() const
- {
- return flaresSize;
- }
- void setLensFlaresSize(const Vec2& val)
- {
- flaresSize = val;
- }
- const Vec2& getLensFlaresStretchMultiplier() const
- {
- return flaresStretchMultiplier;
- }
- void setLensFlaresStretchMultiplier(const Vec2& val)
- {
- flaresStretchMultiplier = val;
- }
- F32 getLensFlaresAlpha() const
- {
- return flaresAlpha;
- }
- void setLensFlaresAlpha(F32 val)
- {
- flaresAlpha = val;
- }
- /// @}
- /// @name SceneNode virtuals
- /// @{
- /// Override SceneNode::frameUpdate
- void frameUpdate(F32 prevUpdateTime, F32 crntTime, int frame)
- {
- SceneNode::frameUpdate(prevUpdateTime, crntTime, frame);
- }
- /// @}
- void loadLensFlare(const char* filename)
- {
- ANKI_ASSERT(!hasLensFlare());
- flaresTex.load(filename);
- }
- private:
- LightType type;
- Vec4 color = Vec4(1.0);
- Vec4 specColor = Vec4(1.0);
- /// @name Flare struff
- /// @{
- TextureResourcePointer flaresTex;
- Vec2 flaresSize = Vec2(0.2);
- Vec2 flaresStretchMultiplier = Vec2(1.0);
- F32 flaresAlpha = 1.0;
- /// @}
- Bool8 shadow = false;
- U8 shadowMapIndex = 0xFF; ///< Used by the renderer
- };
- /// Point light
- class PointLight: public Light
- {
- public:
- /// @name Constructors/Destructor
- /// @{
- PointLight(const char* name, SceneGraph* scene);
- /// @}
- /// @name Accessors
- /// @{
- F32 getRadius() const
- {
- return sphereW.getRadius();
- }
- void setRadius(const F32 x)
- {
- sphereW.setRadius(x);
- SpatialComponent::markForUpdate();
- }
- const Sphere& getSphere() const
- {
- return sphereW;
- }
- /// @}
- /// @name MoveComponent virtuals
- /// @{
- /// Overrides MoveComponent::moveUpdate(). This does:
- /// - Update the collision shape
- void moveUpdate()
- {
- sphereW.setCenter(getWorldTransform().getOrigin());
- SpatialComponent::markForUpdate();
- }
- /// @}
- public:
- Sphere sphereW = Sphere(Vec3(0.0), 1.0);
- };
- /// Spot light
- class SpotLight: public Light, public FrustumComponent
- {
- public:
- /// @name Constructors/Destructor
- /// @{
- SpotLight(const char* name, SceneGraph* scene);
- /// @}
- /// @name Accessors
- /// @{
- Texture& getTexture()
- {
- return *tex;
- }
- const Texture& getTexture() const
- {
- return *tex;
- }
- F32 getOuterAngle() const
- {
- return frustum.getFovX();
- }
- void setOuterAngle(F32 x)
- {
- frustum.setFovX(x);
- frustum.setFovY(x);
- cosOuterAngle = cos(x / 2.0);
- frustumUpdate();
- }
- F32 getOuterAngleCos() const
- {
- return cosOuterAngle;
- }
- void setInnerAngle(F32 ang)
- {
- cosInnerAngle = cos(ang / 2.0);
- }
- F32 getInnerAngleCos() const
- {
- return cosInnerAngle;
- }
- F32 getDistance() const
- {
- return frustum.getFar();
- }
- void setDistance(F32 f)
- {
- frustum.setFar(f);
- frustumUpdate();
- }
- const PerspectiveFrustum& getFrustum() const
- {
- return frustum;
- }
- /// @}
- /// @name MoveComponent virtuals
- /// @{
- /// Overrides MoveComponent::moveUpdate(). This does:
- /// - Update the collision shape
- void moveUpdate()
- {
- frustum.setTransform(getWorldTransform());
- viewMat = Mat4(getWorldTransform().getInverse());
- viewProjectionMat = projectionMat * viewMat;
- SpatialComponent::markForUpdate();
- }
- /// @}
- /// @name FrustumComponent virtuals
- /// @{
- /// Override FrustumComponent::getFrustumOrigin()
- const Vec3& getFrustumOrigin() const
- {
- return getWorldTransform().getOrigin();
- }
- /// @}
- void loadTexture(const char* filename)
- {
- tex.load(filename);
- }
- private:
- PerspectiveFrustum frustum;
- TextureResourcePointer tex;
- F32 cosOuterAngle;
- F32 cosInnerAngle;
- void frustumUpdate()
- {
- projectionMat = frustum.calculateProjectionMatrix();
- viewProjectionMat = projectionMat * viewMat;
- SpatialComponent::markForUpdate();
- FrustumComponent::markForUpdate();
- }
- };
- } // end namespace anki
- #endif
|