From 974df4288f97cc9e83c7823f10f8234ab96516fe Mon Sep 17 00:00:00 2001 From: Lynix Date: Tue, 16 Jun 2015 14:21:20 +0200 Subject: [PATCH 01/37] First shadow mapping commit Former-commit-id: 7465a7c3297626f8db8c1ff48a20c0e0d9feb765 --- SDK/include/NDK/Systems/RenderSystem.hpp | 4 ++ SDK/src/NDK/Systems/RenderSystem.cpp | 64 ++++++++++++++++++++-- include/Nazara/Graphics/Light.hpp | 57 ++++++++++++-------- include/Nazara/Graphics/Light.inl | 68 ++++++++++++++++++++++++ src/Nazara/Graphics/Light.cpp | 19 ++++++- src/Nazara/Renderer/RenderTexture.cpp | 6 +++ 6 files changed, 190 insertions(+), 28 deletions(-) diff --git a/SDK/include/NDK/Systems/RenderSystem.hpp b/SDK/include/NDK/Systems/RenderSystem.hpp index 522f1c775..0baae7684 100644 --- a/SDK/include/NDK/Systems/RenderSystem.hpp +++ b/SDK/include/NDK/Systems/RenderSystem.hpp @@ -8,6 +8,7 @@ #define NDK_SYSTEMS_RENDERSYSTEM_HPP #include +#include #include #include #include @@ -31,11 +32,14 @@ namespace Ndk private: void OnEntityRemoved(Entity* entity) override; void OnEntityValidation(Entity* entity, bool justAdded) override; + void UpdateShadowMaps(); EntityList m_cameras; EntityList m_drawables; EntityList m_lights; NzForwardRenderTechnique m_renderTechnique; + NzForwardRenderTechnique m_shadowTechnique; + NzRenderTexture m_shadowRT; }; } diff --git a/SDK/src/NDK/Systems/RenderSystem.cpp b/SDK/src/NDK/Systems/RenderSystem.cpp index 1f781e951..4f6f27f86 100644 --- a/SDK/src/NDK/Systems/RenderSystem.cpp +++ b/SDK/src/NDK/Systems/RenderSystem.cpp @@ -3,7 +3,9 @@ // For conditions of distribution and use, see copyright notice in Prerequesites.hpp #include +#include #include +#include #include #include #include @@ -17,6 +19,8 @@ namespace Ndk void RenderSystem::Update(float elapsedTime) { + UpdateShadowMaps(); + for (const Ndk::EntityHandle& camera : m_cameras) { CameraComponent& camComponent = camera->GetComponent(); @@ -25,10 +29,10 @@ namespace Ndk NzAbstractRenderQueue* renderQueue = m_renderTechnique.GetRenderQueue(); renderQueue->Clear(); - for (const Ndk::EntityHandle& light : m_drawables) + for (const Ndk::EntityHandle& drawable : m_drawables) { - GraphicsComponent& graphicsComponent = light->GetComponent(); - NodeComponent& drawableNode = light->GetComponent(); + GraphicsComponent& graphicsComponent = drawable->GetComponent(); + NodeComponent& drawableNode = drawable->GetComponent(); graphicsComponent.AddToRenderQueue(renderQueue); } @@ -36,9 +40,9 @@ namespace Ndk for (const Ndk::EntityHandle& light : m_lights) { LightComponent& lightComponent = light->GetComponent(); - NodeComponent& drawableNode = light->GetComponent(); + NodeComponent& lightNode = light->GetComponent(); - lightComponent.AddToRenderQueue(renderQueue, drawableNode.GetTransformMatrix()); + lightComponent.AddToRenderQueue(renderQueue, lightNode.GetTransformMatrix()); } NzColorBackground background; @@ -83,5 +87,55 @@ namespace Ndk m_lights.Remove(entity); } + void RenderSystem::UpdateShadowMaps() + { + if (!m_shadowRT.IsValid()) + m_shadowRT.Create(); + + for (const Ndk::EntityHandle& light : m_lights) + { + LightComponent& lightComponent = light->GetComponent(); + NodeComponent& lightNode = light->GetComponent(); + + if (!lightComponent.IsShadowCastingEnabled() || lightComponent.GetLightType() != nzLightType_Spot) + continue; + + /// HACKY + NzCamera lightPOV; + lightPOV.SetPosition(lightNode.GetPosition()); + lightPOV.SetFOV(lightComponent.GetOuterAngle()); + lightPOV.SetRotation(lightNode.GetRotation()); + lightPOV.SetZFar(1000.f); + lightPOV.SetTarget(&m_shadowRT); + + NzVector2ui shadowMapSize(lightComponent.GetShadowMap()->GetSize()); + + m_shadowRT.AttachTexture(nzAttachmentPoint_Depth, 0, lightComponent.GetShadowMap()); + + NzRenderer::SetMatrix(nzMatrixType_Projection, lightPOV.GetProjectionMatrix()); + NzRenderer::SetMatrix(nzMatrixType_View, lightPOV.GetViewMatrix()); + NzRenderer::SetTarget(&m_shadowRT); + NzRenderer::SetViewport(NzRecti(0, 0, shadowMapSize.x, shadowMapSize.y)); + + NzAbstractRenderQueue* renderQueue = m_renderTechnique.GetRenderQueue(); + renderQueue->Clear(); + + for (const Ndk::EntityHandle& drawable : m_drawables) + { + GraphicsComponent& graphicsComponent = drawable->GetComponent(); + NodeComponent& drawableNode = drawable->GetComponent(); + + graphicsComponent.AddToRenderQueue(renderQueue); + } + + NzSceneData sceneData; + sceneData.ambientColor = NzColor(0, 0, 0); + sceneData.background = nullptr; + sceneData.viewer = &lightPOV; + + m_renderTechnique.Draw(sceneData); + } + } + SystemIndex RenderSystem::systemIndex; } diff --git a/include/Nazara/Graphics/Light.hpp b/include/Nazara/Graphics/Light.hpp index 9a6a4235b..a28a86c17 100644 --- a/include/Nazara/Graphics/Light.hpp +++ b/include/Nazara/Graphics/Light.hpp @@ -11,6 +11,8 @@ #include #include #include +#include +#include class NzLight; struct NzLightUniforms; @@ -19,7 +21,7 @@ class NAZARA_GRAPHICS_API NzLight : public NzRenderable { public: NzLight(nzLightType type = nzLightType_Point); - NzLight(const NzLight& light) = default; + inline NzLight(const NzLight& light); ~NzLight() = default; void AddToRenderQueue(NzAbstractRenderQueue* renderQueue, const NzMatrix4f& transformMatrix) const override; @@ -29,37 +31,48 @@ class NAZARA_GRAPHICS_API NzLight : public NzRenderable bool Cull(const NzFrustumf& frustum, const NzMatrix4f& transformMatrix) const override; - float GetAmbientFactor() const; - float GetAttenuation() const; - NzColor GetColor() const; - float GetDiffuseFactor() const; - float GetInnerAngle() const; - float GetInnerAngleCosine() const; - float GetInvRadius() const; - nzLightType GetLightType() const; - float GetOuterAngle() const; - float GetOuterAngleCosine() const; - float GetOuterAngleTangent() const; - float GetRadius() const; + inline void EnableShadowCasting(bool castShadows); - void SetAmbientFactor(float factor); - void SetAttenuation(float attenuation); - void SetColor(const NzColor& color); - void SetDiffuseFactor(float factor); - void SetInnerAngle(float innerAngle); - void SetLightType(nzLightType type); - void SetOuterAngle(float outerAngle); - void SetRadius(float radius); + inline void EnsureShadowMapUpdate() const; + + inline float GetAmbientFactor() const; + inline float GetAttenuation() const; + inline NzColor GetColor() const; + inline float GetDiffuseFactor() const; + inline float GetInnerAngle() const; + inline float GetInnerAngleCosine() const; + inline float GetInvRadius() const; + inline nzLightType GetLightType() const; + inline float GetOuterAngle() const; + inline float GetOuterAngleCosine() const; + inline float GetOuterAngleTangent() const; + inline float GetRadius() const; + inline NzTextureRef GetShadowMap() const; + + inline bool IsShadowCastingEnabled() const; + + inline void SetAmbientFactor(float factor); + inline void SetAttenuation(float attenuation); + inline void SetColor(const NzColor& color); + inline void SetDiffuseFactor(float factor); + inline void SetInnerAngle(float innerAngle); + inline void SetLightType(nzLightType type); + inline void SetOuterAngle(float outerAngle); + inline void SetRadius(float radius); void UpdateBoundingVolume(const NzMatrix4f& transformMatrix) override; - NzLight& operator=(const NzLight& light) = default; + NzLight& operator=(const NzLight& light); private: void MakeBoundingVolume() const override; + void UpdateShadowMap() const; nzLightType m_type; NzColor m_color; + mutable NzTextureRef m_shadowMap; + bool m_shadowCastingEnabled; + mutable bool m_shadowMapUpdated; float m_ambientFactor; float m_attenuation; float m_diffuseFactor; diff --git a/include/Nazara/Graphics/Light.inl b/include/Nazara/Graphics/Light.inl index ecda520a4..d981e95bb 100644 --- a/include/Nazara/Graphics/Light.inl +++ b/include/Nazara/Graphics/Light.inl @@ -5,6 +5,40 @@ #include #include +inline NzLight::NzLight(const NzLight& light) : +NzRenderable(light), +m_type(light.m_type), +m_color(light.m_color), +m_shadowCastingEnabled(light.m_shadowCastingEnabled), +m_shadowMapUpdated(false), +m_ambientFactor(light.m_ambientFactor), +m_attenuation(light.m_attenuation), +m_diffuseFactor(light.m_diffuseFactor), +m_innerAngle(light.m_innerAngle), +m_innerAngleCosine(light.m_innerAngleCosine), +m_invRadius(light.m_invRadius), +m_outerAngle(light.m_outerAngle), +m_outerAngleCosine(light.m_outerAngleCosine), +m_outerAngleTangent(light.m_outerAngleTangent), +m_radius(light.m_radius) +{ +} + +inline void NzLight::EnableShadowCasting(bool castShadows) +{ + if (m_shadowCastingEnabled != castShadows) + { + m_shadowCastingEnabled = castShadows; + m_shadowMapUpdated = false; + } +} + +inline void NzLight::EnsureShadowMapUpdate() const +{ + if (!m_shadowMapUpdated) + UpdateShadowMap(); +} + inline float NzLight::GetAmbientFactor() const { return m_ambientFactor; @@ -45,6 +79,18 @@ inline float NzLight::GetRadius() const return m_radius; } +inline NzTextureRef NzLight::GetShadowMap() const +{ + EnsureShadowMapUpdate(); + + return m_shadowMap; +} + +inline bool NzLight::IsShadowCastingEnabled() const +{ + return m_shadowCastingEnabled; +} + inline void NzLight::SetAmbientFactor(float factor) { m_ambientFactor = factor; @@ -94,4 +140,26 @@ inline void NzLight::SetRadius(float radius) InvalidateBoundingVolume(); } +inline NzLight& NzLight::operator=(const NzLight& light) +{ + NzRenderable::operator=(light); + + m_ambientFactor = light.m_ambientFactor; + m_attenuation = light.m_attenuation; + m_color = light.m_color; + m_diffuseFactor = light.m_diffuseFactor; + m_innerAngle = light.m_innerAngle; + m_innerAngleCosine = light.m_innerAngleCosine; + m_invRadius = light.m_invRadius; + m_outerAngle = light.m_outerAngle; + m_outerAngleCosine = light.m_outerAngleCosine; + m_outerAngleTangent = light.m_outerAngleTangent; + m_radius = light.m_radius; + m_shadowCastingEnabled = light.m_shadowCastingEnabled; + m_shadowMapUpdated = false; + m_type = light.m_type; + + return *this; +} + #include diff --git a/src/Nazara/Graphics/Light.cpp b/src/Nazara/Graphics/Light.cpp index 35717498f..0bc491511 100644 --- a/src/Nazara/Graphics/Light.cpp +++ b/src/Nazara/Graphics/Light.cpp @@ -17,7 +17,9 @@ ///TODO: Scale ? NzLight::NzLight(nzLightType type) : -m_type(type) +m_type(type), +m_shadowCastingEnabled(false), +m_shadowMapUpdated(false) { SetAmbientFactor((type == nzLightType_Directional) ? 0.2f : 0.f); SetAttenuation(0.9f); @@ -177,3 +179,18 @@ void NzLight::MakeBoundingVolume() const break; } } + +void NzLight::UpdateShadowMap() const +{ + if (m_shadowCastingEnabled) + { + if (!m_shadowMap) + m_shadowMap = NzTexture::New(); + + m_shadowMap->Create(nzImageType_2D, nzPixelFormat_Depth16, 256, 256); + } + else + m_shadowMap.Reset(); + + m_shadowMapUpdated = true; +} diff --git a/src/Nazara/Renderer/RenderTexture.cpp b/src/Nazara/Renderer/RenderTexture.cpp index f2dc61bfc..c9dc2d611 100644 --- a/src/Nazara/Renderer/RenderTexture.cpp +++ b/src/Nazara/Renderer/RenderTexture.cpp @@ -148,6 +148,9 @@ bool NzRenderTexture::AttachBuffer(nzAttachmentPoint attachmentPoint, nzUInt8 in Unlock(); unsigned int attachIndex = attachmentIndex[attachmentPoint] + index; + if (attachIndex >= m_impl->attachments.size()) + m_impl->attachments.resize(attachIndex+1); + Attachment& attachment = m_impl->attachments[attachIndex]; attachment.attachmentPoint = attachmentPoint; attachment.buffer = buffer; @@ -286,6 +289,9 @@ bool NzRenderTexture::AttachTexture(nzAttachmentPoint attachmentPoint, nzUInt8 i Unlock(); unsigned int attachIndex = attachmentIndex[attachmentPoint] + index; + if (attachIndex >= m_impl->attachments.size()) + m_impl->attachments.resize(attachIndex+1); + Attachment& attachment = m_impl->attachments[attachIndex]; attachment.attachmentPoint = attachmentPoint; attachment.isBuffer = false; From 39779c059d2dbc48269cac651ae8c33803b97197 Mon Sep 17 00:00:00 2001 From: Lynix Date: Tue, 16 Jun 2015 23:35:52 +0200 Subject: [PATCH 02/37] Renderer/OpenGL: Apply swizzle on depth formats Too much red when debugging shadow maps Former-commit-id: 4445429fcae3208912fd509097403f3293a2ec7e --- src/Nazara/Renderer/OpenGL.cpp | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/Nazara/Renderer/OpenGL.cpp b/src/Nazara/Renderer/OpenGL.cpp index 5c8167ad8..5331e902c 100644 --- a/src/Nazara/Renderer/OpenGL.cpp +++ b/src/Nazara/Renderer/OpenGL.cpp @@ -1803,24 +1803,44 @@ bool NzOpenGL::TranslateFormat(nzPixelFormat pixelFormat, Format* format, Format format->dataFormat = GL_DEPTH_COMPONENT; format->dataType = GL_UNSIGNED_SHORT; format->internalFormat = GL_DEPTH_COMPONENT16; + + format->swizzle[0] = GL_RED; + format->swizzle[1] = GL_RED; + format->swizzle[2] = GL_RED; + format->swizzle[3] = GL_ONE; return true; case nzPixelFormat_Depth24: format->dataFormat = GL_DEPTH_COMPONENT; format->dataType = GL_UNSIGNED_INT; format->internalFormat = GL_DEPTH_COMPONENT24; + + format->swizzle[0] = GL_RED; + format->swizzle[1] = GL_RED; + format->swizzle[2] = GL_RED; + format->swizzle[3] = GL_ONE; return true; case nzPixelFormat_Depth24Stencil8: format->dataFormat = GL_DEPTH_STENCIL; format->dataType = GL_UNSIGNED_INT_24_8; format->internalFormat = GL_DEPTH24_STENCIL8; + + format->swizzle[0] = GL_RED; + format->swizzle[1] = GL_RED; + format->swizzle[2] = GL_RED; + format->swizzle[3] = GL_GREEN; return true; case nzPixelFormat_Depth32: format->dataFormat = GL_DEPTH_COMPONENT; format->dataType = GL_UNSIGNED_BYTE; format->internalFormat = GL_DEPTH_COMPONENT32; + + format->swizzle[0] = GL_RED; + format->swizzle[1] = GL_RED; + format->swizzle[2] = GL_RED; + format->swizzle[3] = GL_ONE; return true; case nzPixelFormat_Stencil1: From ebbaaf7ff2b4b7fb69192ce9ec086e91ce22287f Mon Sep 17 00:00:00 2001 From: Lynix Date: Wed, 17 Jun 2015 14:32:05 +0200 Subject: [PATCH 03/37] Graphics: Add depth render technique/queue Former-commit-id: 711306ee5f84a9579068ce23240dc105cec15cde --- SDK/include/NDK/Systems/RenderSystem.hpp | 3 +- SDK/src/NDK/Systems/RenderSystem.cpp | 19 +- include/Nazara/Graphics/DepthRenderQueue.hpp | 76 ++++ .../Nazara/Graphics/DepthRenderTechnique.hpp | 53 +++ .../Nazara/Graphics/DepthRenderTechnique.inl | 3 + include/Nazara/Graphics/Enums.hpp | 1 + src/Nazara/Graphics/DepthRenderQueue.cpp | 377 ++++++++++++++++++ src/Nazara/Graphics/DepthRenderTechnique.cpp | 363 +++++++++++++++++ src/Nazara/Graphics/Graphics.cpp | 8 + src/Nazara/Graphics/RenderTechniques.cpp | 1 + 10 files changed, 890 insertions(+), 14 deletions(-) create mode 100644 include/Nazara/Graphics/DepthRenderQueue.hpp create mode 100644 include/Nazara/Graphics/DepthRenderTechnique.hpp create mode 100644 include/Nazara/Graphics/DepthRenderTechnique.inl create mode 100644 src/Nazara/Graphics/DepthRenderQueue.cpp create mode 100644 src/Nazara/Graphics/DepthRenderTechnique.cpp diff --git a/SDK/include/NDK/Systems/RenderSystem.hpp b/SDK/include/NDK/Systems/RenderSystem.hpp index 0baae7684..b06fe7ddc 100644 --- a/SDK/include/NDK/Systems/RenderSystem.hpp +++ b/SDK/include/NDK/Systems/RenderSystem.hpp @@ -7,6 +7,7 @@ #ifndef NDK_SYSTEMS_RENDERSYSTEM_HPP #define NDK_SYSTEMS_RENDERSYSTEM_HPP +#include #include #include #include @@ -37,8 +38,8 @@ namespace Ndk EntityList m_cameras; EntityList m_drawables; EntityList m_lights; + NzDepthRenderTechnique m_shadowTechnique; NzForwardRenderTechnique m_renderTechnique; - NzForwardRenderTechnique m_shadowTechnique; NzRenderTexture m_shadowRT; }; } diff --git a/SDK/src/NDK/Systems/RenderSystem.cpp b/SDK/src/NDK/Systems/RenderSystem.cpp index 4f6f27f86..fa7ea650a 100644 --- a/SDK/src/NDK/Systems/RenderSystem.cpp +++ b/SDK/src/NDK/Systems/RenderSystem.cpp @@ -100,24 +100,17 @@ namespace Ndk if (!lightComponent.IsShadowCastingEnabled() || lightComponent.GetLightType() != nzLightType_Spot) continue; - /// HACKY - NzCamera lightPOV; - lightPOV.SetPosition(lightNode.GetPosition()); - lightPOV.SetFOV(lightComponent.GetOuterAngle()); - lightPOV.SetRotation(lightNode.GetRotation()); - lightPOV.SetZFar(1000.f); - lightPOV.SetTarget(&m_shadowRT); - NzVector2ui shadowMapSize(lightComponent.GetShadowMap()->GetSize()); m_shadowRT.AttachTexture(nzAttachmentPoint_Depth, 0, lightComponent.GetShadowMap()); - NzRenderer::SetMatrix(nzMatrixType_Projection, lightPOV.GetProjectionMatrix()); - NzRenderer::SetMatrix(nzMatrixType_View, lightPOV.GetViewMatrix()); + ///TODO: Cache the matrices in the light? + NzRenderer::SetMatrix(nzMatrixType_Projection, NzMatrix4f::Perspective(lightComponent.GetOuterAngle(), 1.f, 1.f, 1000.f)); + NzRenderer::SetMatrix(nzMatrixType_View, NzMatrix4f::ViewMatrix(lightNode.GetPosition(), lightNode.GetRotation())); NzRenderer::SetTarget(&m_shadowRT); NzRenderer::SetViewport(NzRecti(0, 0, shadowMapSize.x, shadowMapSize.y)); - NzAbstractRenderQueue* renderQueue = m_renderTechnique.GetRenderQueue(); + NzAbstractRenderQueue* renderQueue = m_shadowTechnique.GetRenderQueue(); renderQueue->Clear(); for (const Ndk::EntityHandle& drawable : m_drawables) @@ -131,9 +124,9 @@ namespace Ndk NzSceneData sceneData; sceneData.ambientColor = NzColor(0, 0, 0); sceneData.background = nullptr; - sceneData.viewer = &lightPOV; + sceneData.viewer = nullptr; //< Depth technique doesn't require any viewer - m_renderTechnique.Draw(sceneData); + m_shadowTechnique.Draw(sceneData); } } diff --git a/include/Nazara/Graphics/DepthRenderQueue.hpp b/include/Nazara/Graphics/DepthRenderQueue.hpp new file mode 100644 index 000000000..ec6550494 --- /dev/null +++ b/include/Nazara/Graphics/DepthRenderQueue.hpp @@ -0,0 +1,76 @@ +// Copyright (C) 2015 Jérôme Leclercq +// This file is part of the "Nazara Engine - Graphics module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#pragma once + +#ifndef NAZARA_DEPTHRENDERQUEUE_HPP +#define NAZARA_DEPTHRENDERQUEUE_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +class NAZARA_GRAPHICS_API NzDepthRenderQueue : public NzAbstractRenderQueue +{ + public: + NzDepthRenderQueue() = default; + ~NzDepthRenderQueue() = default; + + void AddBillboard(const NzMaterial* material, const NzVector3f& position, const NzVector2f& size, const NzVector2f& sinCos = NzVector2f(0.f, 1.f), const NzColor& color = NzColor::White) override; + void AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr sinCosPtr = nullptr, NzSparsePtr colorPtr = nullptr) override; + void AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr sinCosPtr, NzSparsePtr alphaPtr) override; + void AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr anglePtr, NzSparsePtr colorPtr = nullptr) override; + void AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr anglePtr, NzSparsePtr alphaPtr) override; + void AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr sinCosPtr = nullptr, NzSparsePtr colorPtr = nullptr) override; + void AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr sinCosPtr, NzSparsePtr alphaPtr) override; + void AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr anglePtr, NzSparsePtr colorPtr = nullptr) override; + void AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr anglePtr, NzSparsePtr alphaPtr) override; + void AddDrawable(const NzDrawable* drawable) override; + void AddMesh(const NzMaterial* material, const NzMeshData& meshData, const NzBoxf& meshAABB, const NzMatrix4f& transformMatrix) override; + void AddSprites(const NzMaterial* material, const NzVertexStruct_XYZ_Color_UV* vertices, unsigned int spriteCount, const NzTexture* overlay = nullptr) override; + + void Clear(bool fully = false); + + struct BillboardData + { + NzColor color; + NzVector3f center; + NzVector2f size; + NzVector2f sinCos; + }; + + struct MeshInstanceEntry + { + NazaraSlot(NzIndexBuffer, OnIndexBufferRelease, indexBufferReleaseSlot); + NazaraSlot(NzVertexBuffer, OnVertexBufferRelease, vertexBufferReleaseSlot); + + std::vector instances; + }; + + struct SpriteChain_XYZ_Color_UV + { + const NzVertexStruct_XYZ_Color_UV* vertices; + unsigned int spriteCount; + }; + + std::map meshes; + std::vector billboards; + std::vector otherDrawables; + std::vector basicSprites; + + private: + bool IsMaterialSuitable(const NzMaterial* material) const; + + void OnIndexBufferInvalidation(const NzIndexBuffer* indexBuffer); + void OnVertexBufferInvalidation(const NzVertexBuffer* vertexBuffer); +}; + +#endif // NAZARA_DEPTHRENDERQUEUE_HPP diff --git a/include/Nazara/Graphics/DepthRenderTechnique.hpp b/include/Nazara/Graphics/DepthRenderTechnique.hpp new file mode 100644 index 000000000..b33a2b6cc --- /dev/null +++ b/include/Nazara/Graphics/DepthRenderTechnique.hpp @@ -0,0 +1,53 @@ +// Copyright (C) 2015 Jérôme Leclercq +// This file is part of the "Nazara Engine - Graphics module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#pragma once + +#ifndef NAZARA_DEPTHRENDERTECHNIQUE_HPP +#define NAZARA_DEPTHRENDERTECHNIQUE_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +class NAZARA_GRAPHICS_API NzDepthRenderTechnique : public NzAbstractRenderTechnique +{ + public: + NzDepthRenderTechnique(); + ~NzDepthRenderTechnique() = default; + + bool Draw(const NzSceneData& sceneData) const override; + + NzAbstractRenderQueue* GetRenderQueue() override; + nzRenderTechniqueType GetType() const override; + + static bool Initialize(); + static void Uninitialize(); + + private: + void DrawBasicSprites(const NzSceneData& sceneData) const; + void DrawBillboards(const NzSceneData& sceneData) const; + void DrawOpaqueModels(const NzSceneData& sceneData) const; + + NzBuffer m_vertexBuffer; + mutable NzDepthRenderQueue m_renderQueue; + NzVertexBuffer m_billboardPointBuffer; + NzVertexBuffer m_spriteBuffer; + + static NzIndexBuffer s_quadIndexBuffer; + static NzMaterialRef s_material; + static NzVertexBuffer s_quadVertexBuffer; + static NzVertexDeclaration s_billboardInstanceDeclaration; + static NzVertexDeclaration s_billboardVertexDeclaration; +}; + +#include + +#endif // NAZARA_DEPTHRENDERTECHNIQUE_HPP diff --git a/include/Nazara/Graphics/DepthRenderTechnique.inl b/include/Nazara/Graphics/DepthRenderTechnique.inl new file mode 100644 index 000000000..ac6b052d0 --- /dev/null +++ b/include/Nazara/Graphics/DepthRenderTechnique.inl @@ -0,0 +1,3 @@ +// Copyright (C) 2015 Jérôme Leclercq +// This file is part of the "Nazara Engine - Graphics module" +// For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Graphics/Enums.hpp b/include/Nazara/Graphics/Enums.hpp index 1e301ecb9..70002d7cf 100644 --- a/include/Nazara/Graphics/Enums.hpp +++ b/include/Nazara/Graphics/Enums.hpp @@ -98,6 +98,7 @@ enum nzRenderTechniqueType nzRenderTechniqueType_AdvancedForward, // NzAdvancedForwardRenderTechnique nzRenderTechniqueType_BasicForward, // NzBasicForwardRenderTechnique nzRenderTechniqueType_DeferredShading, // NzDeferredRenderTechnique + nzRenderTechniqueType_Depth, // NzDepthRenderTechnique nzRenderTechniqueType_LightPrePass, // NzLightPrePassRenderTechnique nzRenderTechniqueType_User, diff --git a/src/Nazara/Graphics/DepthRenderQueue.cpp b/src/Nazara/Graphics/DepthRenderQueue.cpp new file mode 100644 index 000000000..613033015 --- /dev/null +++ b/src/Nazara/Graphics/DepthRenderQueue.cpp @@ -0,0 +1,377 @@ +// Copyright (C) 2015 Jérôme Leclercq +// This file is part of the "Nazara Engine - Graphics module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include +#include +#include +#include + +///TODO: Remplacer les sinus/cosinus par une lookup table (va booster les perfs d'un bon x10) + +void NzDepthRenderQueue::AddBillboard(const NzMaterial* material, const NzVector3f& position, const NzVector2f& size, const NzVector2f& sinCos, const NzColor& color) +{ + NazaraAssert(material, "Invalid material"); + + if (IsMaterialSuitable(material)) + billboards.push_back(BillboardData{color, position, size, sinCos}); +} + +void NzDepthRenderQueue::AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr sinCosPtr, NzSparsePtr colorPtr) +{ + ///DOC: sinCosPtr et colorPtr peuvent être nuls, ils seront remplacés respectivement par Vector2f(0.f, 1.f) et Color::White + NazaraAssert(material, "Invalid material"); + + if (!IsMaterialSuitable(material)) + return; + + NzVector2f defaultSinCos(0.f, 1.f); // sin(0) = 0, cos(0) = 1 + + if (!sinCosPtr) + sinCosPtr.Reset(&defaultSinCos, 0); // L'astuce ici est de mettre le stride sur zéro, rendant le pointeur immobile + + if (!colorPtr) + colorPtr.Reset(&NzColor::White, 0); // Pareil + + unsigned int prevSize = billboards.size(); + billboards.resize(prevSize + count); + + BillboardData* billboardData = &billboards[prevSize]; + for (unsigned int i = 0; i < count; ++i) + { + billboardData->center = *positionPtr++; + billboardData->color = *colorPtr++; + billboardData->sinCos = *sinCosPtr++; + billboardData->size = *sizePtr++; + billboardData++; + } +} + +void NzDepthRenderQueue::AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr sinCosPtr, NzSparsePtr alphaPtr) +{ + ///DOC: sinCosPtr et alphaPtr peuvent être nuls, ils seront remplacés respectivement par Vector2f(0.f, 1.f) et Color::White + NazaraAssert(material, "Invalid material"); + + if (!IsMaterialSuitable(material)) + return; + + NzVector2f defaultSinCos(0.f, 1.f); // sin(0) = 0, cos(0) = 1 + + if (!sinCosPtr) + sinCosPtr.Reset(&defaultSinCos, 0); // L'astuce ici est de mettre le stride sur zéro, rendant le pointeur immobile + + float defaultAlpha = 1.f; + + if (!alphaPtr) + alphaPtr.Reset(&defaultAlpha, 0); // Pareil + + unsigned int prevSize = billboards.size(); + billboards.resize(prevSize + count); + + BillboardData* billboardData = &billboards[prevSize]; + for (unsigned int i = 0; i < count; ++i) + { + billboardData->center = *positionPtr++; + billboardData->color = NzColor(255, 255, 255, static_cast(255.f * (*alphaPtr++))); + billboardData->sinCos = *sinCosPtr++; + billboardData->size = *sizePtr++; + billboardData++; + } +} + +void NzDepthRenderQueue::AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr anglePtr, NzSparsePtr colorPtr) +{ + NazaraAssert(material, "Invalid material"); + + if (!IsMaterialSuitable(material)) + return; + + ///DOC: sinCosPtr et colorPtr peuvent être nuls, ils seront remplacés respectivement par Vector2f(0.f, 1.f) et Color::White + float defaultRotation = 0.f; + + if (!anglePtr) + anglePtr.Reset(&defaultRotation, 0); // L'astuce ici est de mettre le stride sur zéro, rendant le pointeur immobile + + if (!colorPtr) + colorPtr.Reset(&NzColor::White, 0); // Pareil + + unsigned int prevSize = billboards.size(); + billboards.resize(prevSize + count); + + BillboardData* billboardData = &billboards[prevSize]; + for (unsigned int i = 0; i < count; ++i) + { + float sin = std::sin(NzToRadians(*anglePtr)); + float cos = std::cos(NzToRadians(*anglePtr)); + anglePtr++; + + billboardData->center = *positionPtr++; + billboardData->color = *colorPtr++; + billboardData->sinCos.Set(sin, cos); + billboardData->size = *sizePtr++; + billboardData++; + } +} + +void NzDepthRenderQueue::AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr anglePtr, NzSparsePtr alphaPtr) +{ + ///DOC: sinCosPtr et alphaPtr peuvent être nuls, ils seront remplacés respectivement par Vector2f(0.f, 1.f) et Color::White + NazaraAssert(material, "Invalid material"); + + if (!IsMaterialSuitable(material)) + return; + + float defaultRotation = 0.f; + + if (!anglePtr) + anglePtr.Reset(&defaultRotation, 0); // L'astuce ici est de mettre le stride sur zéro, rendant le pointeur immobile + + float defaultAlpha = 1.f; + + if (!alphaPtr) + alphaPtr.Reset(&defaultAlpha, 0); // Pareil + + unsigned int prevSize = billboards.size(); + billboards.resize(prevSize + count); + + BillboardData* billboardData = &billboards[prevSize]; + for (unsigned int i = 0; i < count; ++i) + { + float sin = std::sin(NzToRadians(*anglePtr)); + float cos = std::cos(NzToRadians(*anglePtr)); + anglePtr++; + + billboardData->center = *positionPtr++; + billboardData->color = NzColor(255, 255, 255, static_cast(255.f * (*alphaPtr++))); + billboardData->sinCos.Set(sin, cos); + billboardData->size = *sizePtr++; + billboardData++; + } +} + +void NzDepthRenderQueue::AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr sinCosPtr, NzSparsePtr colorPtr) +{ + ///DOC: sinCosPtr et colorPtr peuvent être nuls, ils seront remplacés respectivement par Vector2f(0.f, 1.f) et Color::White + NazaraAssert(material, "Invalid material"); + + if (!IsMaterialSuitable(material)) + return; + + NzVector2f defaultSinCos(0.f, 1.f); // sin(0) = 0, cos(0) = 1 + + if (!sinCosPtr) + sinCosPtr.Reset(&defaultSinCos, 0); // L'astuce ici est de mettre le stride sur zéro, rendant le pointeur immobile + + if (!colorPtr) + colorPtr.Reset(&NzColor::White, 0); // Pareil + + unsigned int prevSize = billboards.size(); + billboards.resize(prevSize + count); + + BillboardData* billboardData = &billboards[prevSize]; + for (unsigned int i = 0; i < count; ++i) + { + billboardData->center = *positionPtr++; + billboardData->color = *colorPtr++; + billboardData->sinCos = *sinCosPtr++; + billboardData->size.Set(*sizePtr++); + billboardData++; + } +} + +void NzDepthRenderQueue::AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr sinCosPtr, NzSparsePtr alphaPtr) +{ + ///DOC: sinCosPtr et alphaPtr peuvent être nuls, ils seront remplacés respectivement par Vector2f(0.f, 1.f) et Color::White + NazaraAssert(material, "Invalid material"); + + if (!IsMaterialSuitable(material)) + return; + + NzVector2f defaultSinCos(0.f, 1.f); // sin(0) = 0, cos(0) = 1 + + if (!sinCosPtr) + sinCosPtr.Reset(&defaultSinCos, 0); // L'astuce ici est de mettre le stride sur zéro, rendant le pointeur immobile + + float defaultAlpha = 1.f; + + if (!alphaPtr) + alphaPtr.Reset(&defaultAlpha, 0); // Pareil + + unsigned int prevSize = billboards.size(); + billboards.resize(prevSize + count); + + BillboardData* billboardData = &billboards[prevSize]; + for (unsigned int i = 0; i < count; ++i) + { + billboardData->center = *positionPtr++; + billboardData->color = NzColor(255, 255, 255, static_cast(255.f * (*alphaPtr++))); + billboardData->sinCos = *sinCosPtr++; + billboardData->size.Set(*sizePtr++); + billboardData++; + } +} + +void NzDepthRenderQueue::AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr anglePtr, NzSparsePtr colorPtr) +{ + NazaraAssert(material, "Invalid material"); + + if (!IsMaterialSuitable(material)) + return; + + ///DOC: sinCosPtr et colorPtr peuvent être nuls, ils seront remplacés respectivement par Vector2f(0.f, 1.f) et Color::White + float defaultRotation = 0.f; + + if (!anglePtr) + anglePtr.Reset(&defaultRotation, 0); // L'astuce ici est de mettre le stride sur zéro, rendant le pointeur immobile + + if (!colorPtr) + colorPtr.Reset(&NzColor::White, 0); // Pareil + + unsigned int prevSize = billboards.size(); + billboards.resize(prevSize + count); + + BillboardData* billboardData = &billboards[prevSize]; + for (unsigned int i = 0; i < count; ++i) + { + float sin = std::sin(NzToRadians(*anglePtr)); + float cos = std::cos(NzToRadians(*anglePtr)); + anglePtr++; + + billboardData->center = *positionPtr++; + billboardData->color = *colorPtr++; + billboardData->sinCos.Set(sin, cos); + billboardData->size.Set(*sizePtr++); + billboardData++; + } +} + +void NzDepthRenderQueue::AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr anglePtr, NzSparsePtr alphaPtr) +{ + ///DOC: sinCosPtr et alphaPtr peuvent être nuls, ils seront remplacés respectivement par Vector2f(0.f, 1.f) et Color::White + NazaraAssert(material, "Invalid material"); + + if (!IsMaterialSuitable(material)) + return; + + float defaultRotation = 0.f; + + if (!anglePtr) + anglePtr.Reset(&defaultRotation, 0); // L'astuce ici est de mettre le stride sur zéro, rendant le pointeur immobile + + float defaultAlpha = 1.f; + + if (!alphaPtr) + alphaPtr.Reset(&defaultAlpha, 0); // Pareil + + unsigned int prevSize = billboards.size(); + billboards.resize(prevSize + count); + + BillboardData* billboardData = &billboards[prevSize]; + for (unsigned int i = 0; i < count; ++i) + { + float sin = std::sin(NzToRadians(*anglePtr)); + float cos = std::cos(NzToRadians(*anglePtr)); + anglePtr++; + + billboardData->center = *positionPtr++; + billboardData->color = NzColor(255, 255, 255, static_cast(255.f * (*alphaPtr++))); + billboardData->sinCos.Set(sin, cos); + billboardData->size.Set(*sizePtr++); + billboardData++; + } +} + +void NzDepthRenderQueue::AddDrawable(const NzDrawable* drawable) +{ + #if NAZARA_GRAPHICS_SAFE + if (!drawable) + { + NazaraError("Invalid drawable"); + return; + } + #endif + + otherDrawables.push_back(drawable); +} + +void NzDepthRenderQueue::AddMesh(const NzMaterial* material, const NzMeshData& meshData, const NzBoxf& meshAABB, const NzMatrix4f& transformMatrix) +{ + NazaraAssert(material, "Invalid material"); + + if (!IsMaterialSuitable(material)) + return; + + auto it = meshes.find(meshData); + if (it == meshes.end()) + { + MeshInstanceEntry instanceEntry; + + if (meshData.indexBuffer) + instanceEntry.indexBufferReleaseSlot.Connect(meshData.indexBuffer->OnIndexBufferRelease, this, &NzDepthRenderQueue::OnIndexBufferInvalidation); + + instanceEntry.vertexBufferReleaseSlot.Connect(meshData.vertexBuffer->OnVertexBufferRelease, this, &NzDepthRenderQueue::OnVertexBufferInvalidation); + + it = meshes.insert(std::make_pair(meshData, std::move(instanceEntry))).first; + } + + std::vector& instances = it->second.instances; + instances.push_back(transformMatrix); + + // Avons-nous suffisamment d'instances pour que le coût d'utilisation de l'instancing soit payé ? + //if (instances.size() >= NAZARA_GRAPHICS_INSTANCING_MIN_INSTANCES_COUNT) + // entry.instancingEnabled = true; // Apparemment oui, activons l'instancing avec ce matériau +} + +void NzDepthRenderQueue::AddSprites(const NzMaterial* material, const NzVertexStruct_XYZ_Color_UV* vertices, unsigned int spriteCount, const NzTexture* overlay) +{ + NazaraAssert(material, "Invalid material"); + + if (!IsMaterialSuitable(material)) + return; + + basicSprites.push_back(SpriteChain_XYZ_Color_UV({vertices, spriteCount})); +} + +void NzDepthRenderQueue::Clear(bool fully) +{ + NzAbstractRenderQueue::Clear(fully); + + basicSprites.clear(); + billboards.clear(); + otherDrawables.clear(); + + if (fully) + meshes.clear(); +} + +bool NzDepthRenderQueue::IsMaterialSuitable(const NzMaterial* material) const +{ + NazaraAssert(material, "Invalid material"); + + return material->IsEnabled(nzRendererParameter_DepthBuffer) && material->IsEnabled(nzRendererParameter_DepthWrite); +} + +void NzDepthRenderQueue::OnIndexBufferInvalidation(const NzIndexBuffer* indexBuffer) +{ + for (auto it = meshes.begin(); it != meshes.end();) + { + const NzMeshData& renderData = it->first; + if (renderData.indexBuffer == indexBuffer) + it = meshes.erase(it); + else + ++it; + } +} + +void NzDepthRenderQueue::OnVertexBufferInvalidation(const NzVertexBuffer* vertexBuffer) +{ + for (auto it = meshes.begin(); it != meshes.end();) + { + const NzMeshData& renderData = it->first; + if (renderData.vertexBuffer == vertexBuffer) + it = meshes.erase(it); + else + ++it; + } +} + diff --git a/src/Nazara/Graphics/DepthRenderTechnique.cpp b/src/Nazara/Graphics/DepthRenderTechnique.cpp new file mode 100644 index 000000000..c6da59276 --- /dev/null +++ b/src/Nazara/Graphics/DepthRenderTechnique.cpp @@ -0,0 +1,363 @@ +// Copyright (C) 2015 Jérôme Leclercq +// This file is part of the "Nazara Engine - Graphics module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace +{ + struct BillboardPoint + { + NzColor color; + NzVector3f position; + NzVector2f size; + NzVector2f sinCos; // must follow `size` (both will be sent as a Vector4f) + NzVector2f uv; + }; + + static_assert(NzOffsetOf(BillboardPoint, sinCos) - NzOffsetOf(BillboardPoint, size) == sizeof(NzVector2f), "size and sinCos members should be packed"); + + unsigned int s_maxQuads = std::numeric_limits::max()/6; + unsigned int s_vertexBufferSize = 4*1024*1024; // 4 MiB +} + +NzDepthRenderTechnique::NzDepthRenderTechnique() : +m_vertexBuffer(nzBufferType_Vertex) +{ + NzErrorFlags flags(nzErrorFlag_ThrowException, true); + + m_vertexBuffer.Create(s_vertexBufferSize, nzDataStorage_Hardware, nzBufferUsage_Dynamic); + + m_billboardPointBuffer.Reset(&s_billboardVertexDeclaration, &m_vertexBuffer); + m_spriteBuffer.Reset(NzVertexDeclaration::Get(nzVertexLayout_XYZ_Color_UV), &m_vertexBuffer); +} + +bool NzDepthRenderTechnique::Draw(const NzSceneData& sceneData) const +{ + NzRenderer::Enable(nzRendererParameter_DepthBuffer, true); + NzRenderer::Enable(nzRendererParameter_DepthWrite, true); + NzRenderer::Clear(nzRendererBuffer_Depth); + + // Just in case the background does render depth + if (sceneData.background) + sceneData.background->Draw(sceneData.viewer); + + if (!m_renderQueue.meshes.empty()) + DrawOpaqueModels(sceneData); + + if (!m_renderQueue.basicSprites.empty()) + DrawBasicSprites(sceneData); + + if (!m_renderQueue.billboards.empty()) + DrawBillboards(sceneData); + + // Other custom drawables + for (const NzDrawable* drawable : m_renderQueue.otherDrawables) + drawable->Draw(); + + return true; +} + +NzAbstractRenderQueue* NzDepthRenderTechnique::GetRenderQueue() +{ + return &m_renderQueue; +} + +nzRenderTechniqueType NzDepthRenderTechnique::GetType() const +{ + return nzRenderTechniqueType_BasicForward; +} + +bool NzDepthRenderTechnique::Initialize() +{ + try + { + NzErrorFlags flags(nzErrorFlag_ThrowException, true); + + s_quadIndexBuffer.Reset(false, s_maxQuads*6, nzDataStorage_Hardware, nzBufferUsage_Static); + + NzBufferMapper mapper(s_quadIndexBuffer, nzBufferAccess_WriteOnly); + nzUInt16* indices = static_cast(mapper.GetPointer()); + + for (unsigned int i = 0; i < s_maxQuads; ++i) + { + *indices++ = i*4 + 0; + *indices++ = i*4 + 2; + *indices++ = i*4 + 1; + + *indices++ = i*4 + 2; + *indices++ = i*4 + 3; + *indices++ = i*4 + 1; + } + + mapper.Unmap(); // Inutile de garder le buffer ouvert plus longtemps + + // Quad buffer (utilisé pour l'instancing de billboard et de sprites) + //Note: Les UV sont calculés dans le shader + s_quadVertexBuffer.Reset(NzVertexDeclaration::Get(nzVertexLayout_XY), 4, nzDataStorage_Hardware, nzBufferUsage_Static); + + float vertices[2*4] = { + -0.5f, -0.5f, + 0.5f, -0.5f, + -0.5f, 0.5f, + 0.5f, 0.5f, + }; + + s_quadVertexBuffer.FillRaw(vertices, 0, sizeof(vertices)); + + // Déclaration lors du rendu des billboards par sommet + s_billboardVertexDeclaration.EnableComponent(nzVertexComponent_Color, nzComponentType_Color, NzOffsetOf(BillboardPoint, color)); + s_billboardVertexDeclaration.EnableComponent(nzVertexComponent_Position, nzComponentType_Float3, NzOffsetOf(BillboardPoint, position)); + s_billboardVertexDeclaration.EnableComponent(nzVertexComponent_TexCoord, nzComponentType_Float2, NzOffsetOf(BillboardPoint, uv)); + s_billboardVertexDeclaration.EnableComponent(nzVertexComponent_Userdata0, nzComponentType_Float4, NzOffsetOf(BillboardPoint, size)); // Englobe sincos + + // Declaration utilisée lors du rendu des billboards par instancing + // L'avantage ici est la copie directe (std::memcpy) des données de la RenderQueue vers le buffer GPU + s_billboardInstanceDeclaration.EnableComponent(nzVertexComponent_InstanceData0, nzComponentType_Float3, NzOffsetOf(NzForwardRenderQueue::BillboardData, center)); + s_billboardInstanceDeclaration.EnableComponent(nzVertexComponent_InstanceData1, nzComponentType_Float4, NzOffsetOf(NzForwardRenderQueue::BillboardData, size)); // Englobe sincos + s_billboardInstanceDeclaration.EnableComponent(nzVertexComponent_InstanceData2, nzComponentType_Color, NzOffsetOf(NzForwardRenderQueue::BillboardData, color)); + + // Material + s_material = NzMaterial::New(); + s_material->Enable(nzRendererParameter_ColorWrite, false); + s_material->Enable(nzRendererParameter_FaceCulling, false); + } + catch (const std::exception& e) + { + NazaraError("Failed to initialise: " + NzString(e.what())); + return false; + } + + return true; +} + +void NzDepthRenderTechnique::Uninitialize() +{ + s_material.Reset(); + s_quadIndexBuffer.Reset(); + s_quadVertexBuffer.Reset(); +} + +void NzDepthRenderTechnique::DrawBasicSprites(const NzSceneData& sceneData) const +{ + NzRenderer::SetIndexBuffer(&s_quadIndexBuffer); + NzRenderer::SetMatrix(nzMatrixType_World, NzMatrix4f::Identity()); + NzRenderer::SetVertexBuffer(&m_spriteBuffer); + + auto& spriteChainVector = m_renderQueue.basicSprites; + unsigned int spriteChainCount = spriteChainVector.size(); + if (spriteChainCount > 0) + { + s_material->Apply(); + + unsigned int spriteChain = 0; // Quelle chaîne de sprite traitons-nous + unsigned int spriteChainOffset = 0; // À quel offset dans la dernière chaîne nous sommes-nous arrêtés + + do + { + // On ouvre le buffer en écriture + NzBufferMapper vertexMapper(m_spriteBuffer, nzBufferAccess_DiscardAndWrite); + NzVertexStruct_XYZ_Color_UV* vertices = reinterpret_cast(vertexMapper.GetPointer()); + + unsigned int spriteCount = 0; + unsigned int maxSpriteCount = std::min(s_maxQuads, m_spriteBuffer.GetVertexCount()/4); + + do + { + NzDepthRenderQueue::SpriteChain_XYZ_Color_UV& currentChain = spriteChainVector[spriteChain]; + unsigned int count = std::min(maxSpriteCount - spriteCount, currentChain.spriteCount - spriteChainOffset); + + std::memcpy(vertices, currentChain.vertices + spriteChainOffset*4, 4*count*sizeof(NzVertexStruct_XYZ_Color_UV)); + vertices += count*4; + + spriteCount += count; + spriteChainOffset += count; + + // Avons-nous traité la chaîne entière ? + if (spriteChainOffset == currentChain.spriteCount) + { + spriteChain++; + spriteChainOffset = 0; + } + } + while (spriteCount < maxSpriteCount && spriteChain < spriteChainCount); + + vertexMapper.Unmap(); + + NzRenderer::DrawIndexedPrimitives(nzPrimitiveMode_TriangleList, 0, spriteCount*6); + } + while (spriteChain < spriteChainCount); + + spriteChainVector.clear(); + } +} + +void NzDepthRenderTechnique::DrawBillboards(const NzSceneData& sceneData) const +{ + if (NzRenderer::HasCapability(nzRendererCap_Instancing)) + { + NzVertexBuffer* instanceBuffer = NzRenderer::GetInstanceBuffer(); + instanceBuffer->SetVertexDeclaration(&s_billboardInstanceDeclaration); + + NzRenderer::SetVertexBuffer(&s_quadVertexBuffer); + + auto& billboardVector = m_renderQueue.billboards; + unsigned int billboardCount = billboardVector.size(); + if (billboardCount > 0) + { + s_material->Apply(nzShaderFlags_Billboard | nzShaderFlags_Instancing); + + const NzDepthRenderQueue::BillboardData* data = &billboardVector[0]; + unsigned int maxBillboardPerDraw = instanceBuffer->GetVertexCount(); + do + { + unsigned int renderedBillboardCount = std::min(billboardCount, maxBillboardPerDraw); + billboardCount -= renderedBillboardCount; + + instanceBuffer->Fill(data, 0, renderedBillboardCount, true); + data += renderedBillboardCount; + + NzRenderer::DrawPrimitivesInstanced(renderedBillboardCount, nzPrimitiveMode_TriangleStrip, 0, 4); + } + while (billboardCount > 0); + + billboardVector.clear(); + } + } + else + { + NzRenderer::SetIndexBuffer(&s_quadIndexBuffer); + NzRenderer::SetVertexBuffer(&m_billboardPointBuffer); + + auto& billboardVector = m_renderQueue.billboards; + + unsigned int billboardCount = billboardVector.size(); + if (billboardCount > 0) + { + s_material->Apply(nzShaderFlags_Billboard); + + const NzDepthRenderQueue::BillboardData* data = &billboardVector[0]; + unsigned int maxBillboardPerDraw = std::min(s_maxQuads, m_billboardPointBuffer.GetVertexCount()/4); + + do + { + unsigned int renderedBillboardCount = std::min(billboardCount, maxBillboardPerDraw); + billboardCount -= renderedBillboardCount; + + NzBufferMapper vertexMapper(m_billboardPointBuffer, nzBufferAccess_DiscardAndWrite, 0, renderedBillboardCount*4); + BillboardPoint* vertices = reinterpret_cast(vertexMapper.GetPointer()); + + for (unsigned int i = 0; i < renderedBillboardCount; ++i) + { + const NzDepthRenderQueue::BillboardData& billboard = *data++; + + vertices->color = billboard.color; + vertices->position = billboard.center; + vertices->sinCos = billboard.sinCos; + vertices->size = billboard.size; + vertices->uv.Set(0.f, 1.f); + vertices++; + + vertices->color = billboard.color; + vertices->position = billboard.center; + vertices->sinCos = billboard.sinCos; + vertices->size = billboard.size; + vertices->uv.Set(1.f, 1.f); + vertices++; + + vertices->color = billboard.color; + vertices->position = billboard.center; + vertices->sinCos = billboard.sinCos; + vertices->size = billboard.size; + vertices->uv.Set(0.f, 0.f); + vertices++; + + vertices->color = billboard.color; + vertices->position = billboard.center; + vertices->sinCos = billboard.sinCos; + vertices->size = billboard.size; + vertices->uv.Set(1.f, 0.f); + vertices++; + } + + vertexMapper.Unmap(); + + NzRenderer::DrawIndexedPrimitives(nzPrimitiveMode_TriangleList, 0, renderedBillboardCount*6); + } + while (billboardCount > 0); + + billboardVector.clear(); + } + } +} + +void NzDepthRenderTechnique::DrawOpaqueModels(const NzSceneData& sceneData) const +{ + s_material->Apply(); + + for (auto& meshIt : m_renderQueue.meshes) + { + const NzMeshData& meshData = meshIt.first; + auto& meshEntry = meshIt.second; + + std::vector& instances = meshEntry.instances; + if (!instances.empty()) + { + const NzIndexBuffer* indexBuffer = meshData.indexBuffer; + const NzVertexBuffer* vertexBuffer = meshData.vertexBuffer; + + // Gestion du draw call avant la boucle de rendu + NzRenderer::DrawCall drawFunc; + NzRenderer::DrawCallInstanced instancedDrawFunc; + unsigned int indexCount; + + if (indexBuffer) + { + drawFunc = NzRenderer::DrawIndexedPrimitives; + instancedDrawFunc = NzRenderer::DrawIndexedPrimitivesInstanced; + indexCount = indexBuffer->GetIndexCount(); + } + else + { + drawFunc = NzRenderer::DrawPrimitives; + instancedDrawFunc = NzRenderer::DrawPrimitivesInstanced; + indexCount = vertexBuffer->GetVertexCount(); + } + + NzRenderer::SetIndexBuffer(indexBuffer); + NzRenderer::SetVertexBuffer(vertexBuffer); + + // Sans instancing, on doit effectuer un draw call pour chaque instance + // Cela reste néanmoins plus rapide que l'instancing en dessous d'un certain nombre d'instances + // À cause du temps de modification du buffer d'instancing + for (const NzMatrix4f& matrix : instances) + { + NzRenderer::SetMatrix(nzMatrixType_World, matrix); + drawFunc(meshData.primitiveMode, 0, indexCount); + } + instances.clear(); + } + } +} + +NzIndexBuffer NzDepthRenderTechnique::s_quadIndexBuffer; +NzMaterialRef NzDepthRenderTechnique::s_material; +NzVertexBuffer NzDepthRenderTechnique::s_quadVertexBuffer; +NzVertexDeclaration NzDepthRenderTechnique::s_billboardInstanceDeclaration; +NzVertexDeclaration NzDepthRenderTechnique::s_billboardVertexDeclaration; diff --git a/src/Nazara/Graphics/Graphics.cpp b/src/Nazara/Graphics/Graphics.cpp index 691423019..f81de8fce 100644 --- a/src/Nazara/Graphics/Graphics.cpp +++ b/src/Nazara/Graphics/Graphics.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -88,6 +89,12 @@ bool NzGraphics::Initialize() NzLoaders_Texture_Register(); // RenderTechniques + if (!NzDepthRenderTechnique::Initialize()) + { + NazaraError("Failed to initialize Depth Rendering"); + return false; + } + if (!NzForwardRenderTechnique::Initialize()) { NazaraError("Failed to initialize Forward Rendering"); @@ -164,6 +171,7 @@ void NzGraphics::Uninitialize() NzLoaders_Texture_Unregister(); NzDeferredRenderTechnique::Uninitialize(); + NzDepthRenderTechnique::Uninitialize(); NzForwardRenderTechnique::Uninitialize(); NzSkinningManager::Uninitialize(); NzParticleRenderer::Uninitialize(); diff --git a/src/Nazara/Graphics/RenderTechniques.cpp b/src/Nazara/Graphics/RenderTechniques.cpp index 820700451..9a96ac71e 100644 --- a/src/Nazara/Graphics/RenderTechniques.cpp +++ b/src/Nazara/Graphics/RenderTechniques.cpp @@ -15,6 +15,7 @@ namespace { "Advanced Forward", "Basic Forward", + "Depth Pass", "Deferred Shading", "Light Pre-Pass", "User" From b7c5283c4e85eca4cc605ded4d7c0fed0ac541eb Mon Sep 17 00:00:00 2001 From: Lynix Date: Wed, 17 Jun 2015 14:32:18 +0200 Subject: [PATCH 04/37] Graphics/Sprite: Fix compilation in debug Former-commit-id: 233f8ebe775e268b72808ecd0770956651e717f6 --- include/Nazara/Graphics/Sprite.inl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/Nazara/Graphics/Sprite.inl b/include/Nazara/Graphics/Sprite.inl index 7b7cb5b24..1ce1cf534 100644 --- a/include/Nazara/Graphics/Sprite.inl +++ b/include/Nazara/Graphics/Sprite.inl @@ -121,7 +121,7 @@ inline void NzSprite::SetTextureCoords(const NzRectf& coords) inline void NzSprite::SetTextureRect(const NzRectui& rect) { - NazaraAssert(material, "Sprite has no material"); + NazaraAssert(m_material, "Sprite has no material"); NazaraAssert(m_material->HasDiffuseMap(), "Sprite material has no diffuse map"); NzTexture* diffuseMap = m_material->GetDiffuseMap(); From e89b87044d8b58069d5423948a2645b54cd0c3c0 Mon Sep 17 00:00:00 2001 From: Lynix Date: Wed, 17 Jun 2015 14:32:32 +0200 Subject: [PATCH 05/37] Graphics: Fix some comments Former-commit-id: df6d080b1ce251b7fe5707ddbb4e31773ba9035d --- src/Nazara/Graphics/ForwardRenderQueue.cpp | 16 ++++++++-------- src/Nazara/Graphics/ForwardRenderTechnique.cpp | 4 +++- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/src/Nazara/Graphics/ForwardRenderQueue.cpp b/src/Nazara/Graphics/ForwardRenderQueue.cpp index 10469b1a5..fffd8372a 100644 --- a/src/Nazara/Graphics/ForwardRenderQueue.cpp +++ b/src/Nazara/Graphics/ForwardRenderQueue.cpp @@ -32,7 +32,7 @@ void NzForwardRenderQueue::AddBillboards(const NzMaterial* material, unsigned in { NazaraAssert(material, "Invalid material"); - ///DOC: sinCosPtr et colorPtr peuvent être nuls, ils seont remplacés respectivement par Vector2f(0.f, 1.f) et Color::White + ///DOC: sinCosPtr et colorPtr peuvent être nuls, ils seront remplacés respectivement par Vector2f(0.f, 1.f) et Color::White NzVector2f defaultSinCos(0.f, 1.f); // sin(0) = 0, cos(0) = 1 if (!sinCosPtr) @@ -71,7 +71,7 @@ void NzForwardRenderQueue::AddBillboards(const NzMaterial* material, unsigned in { NazaraAssert(material, "Invalid material"); - ///DOC: sinCosPtr et alphaPtr peuvent être nuls, ils seont remplacés respectivement par Vector2f(0.f, 1.f) et Color::White + ///DOC: sinCosPtr et alphaPtr peuvent être nuls, ils seront remplacés respectivement par Vector2f(0.f, 1.f) et Color::White NzVector2f defaultSinCos(0.f, 1.f); // sin(0) = 0, cos(0) = 1 if (!sinCosPtr) @@ -112,7 +112,7 @@ void NzForwardRenderQueue::AddBillboards(const NzMaterial* material, unsigned in { NazaraAssert(material, "Invalid material"); - ///DOC: sinCosPtr et colorPtr peuvent être nuls, ils seont remplacés respectivement par Vector2f(0.f, 1.f) et Color::White + ///DOC: sinCosPtr et colorPtr peuvent être nuls, ils seront remplacés respectivement par Vector2f(0.f, 1.f) et Color::White float defaultRotation = 0.f; if (!anglePtr) @@ -155,7 +155,7 @@ void NzForwardRenderQueue::AddBillboards(const NzMaterial* material, unsigned in { NazaraAssert(material, "Invalid material"); - ///DOC: sinCosPtr et alphaPtr peuvent être nuls, ils seont remplacés respectivement par Vector2f(0.f, 1.f) et Color::White + ///DOC: sinCosPtr et alphaPtr peuvent être nuls, ils seront remplacés respectivement par Vector2f(0.f, 1.f) et Color::White float defaultRotation = 0.f; if (!anglePtr) @@ -200,7 +200,7 @@ void NzForwardRenderQueue::AddBillboards(const NzMaterial* material, unsigned in { NazaraAssert(material, "Invalid material"); - ///DOC: sinCosPtr et colorPtr peuvent être nuls, ils seont remplacés respectivement par Vector2f(0.f, 1.f) et Color::White + ///DOC: sinCosPtr et colorPtr peuvent être nuls, ils seront remplacés respectivement par Vector2f(0.f, 1.f) et Color::White NzVector2f defaultSinCos(0.f, 1.f); // sin(0) = 0, cos(0) = 1 if (!sinCosPtr) @@ -239,7 +239,7 @@ void NzForwardRenderQueue::AddBillboards(const NzMaterial* material, unsigned in { NazaraAssert(material, "Invalid material"); - ///DOC: sinCosPtr et alphaPtr peuvent être nuls, ils seont remplacés respectivement par Vector2f(0.f, 1.f) et Color::White + ///DOC: sinCosPtr et alphaPtr peuvent être nuls, ils seront remplacés respectivement par Vector2f(0.f, 1.f) et Color::White NzVector2f defaultSinCos(0.f, 1.f); // sin(0) = 0, cos(0) = 1 if (!sinCosPtr) @@ -280,7 +280,7 @@ void NzForwardRenderQueue::AddBillboards(const NzMaterial* material, unsigned in { NazaraAssert(material, "Invalid material"); - ///DOC: sinCosPtr et colorPtr peuvent être nuls, ils seont remplacés respectivement par Vector2f(0.f, 1.f) et Color::White + ///DOC: sinCosPtr et colorPtr peuvent être nuls, ils seront remplacés respectivement par Vector2f(0.f, 1.f) et Color::White float defaultRotation = 0.f; if (!anglePtr) @@ -323,7 +323,7 @@ void NzForwardRenderQueue::AddBillboards(const NzMaterial* material, unsigned in { NazaraAssert(material, "Invalid material"); - ///DOC: sinCosPtr et alphaPtr peuvent être nuls, ils seont remplacés respectivement par Vector2f(0.f, 1.f) et Color::White + ///DOC: sinCosPtr et alphaPtr peuvent être nuls, ils seront remplacés respectivement par Vector2f(0.f, 1.f) et Color::White float defaultRotation = 0.f; if (!anglePtr) diff --git a/src/Nazara/Graphics/ForwardRenderTechnique.cpp b/src/Nazara/Graphics/ForwardRenderTechnique.cpp index ed36853d0..37e9efdde 100644 --- a/src/Nazara/Graphics/ForwardRenderTechnique.cpp +++ b/src/Nazara/Graphics/ForwardRenderTechnique.cpp @@ -27,10 +27,12 @@ namespace NzColor color; NzVector3f position; NzVector2f size; - NzVector2f sinCos; // doit suivre size + NzVector2f sinCos; // must follow `size` (both will be sent as a Vector4f) NzVector2f uv; }; + static_assert(NzOffsetOf(BillboardPoint, sinCos) - NzOffsetOf(BillboardPoint, size) == sizeof(NzVector2f), "size and sinCos members should be packed"); + unsigned int s_maxQuads = std::numeric_limits::max()/6; unsigned int s_vertexBufferSize = 4*1024*1024; // 4 MiB } From 80208b0dc59dc17db96c60d8782f33977994462a Mon Sep 17 00:00:00 2001 From: Lynix Date: Wed, 17 Jun 2015 23:32:48 +0200 Subject: [PATCH 06/37] Core/OffsetOf: Remove constexpr (cannot be used because of reinterpret_cast) Former-commit-id: 78142eb9033a1969f20055b2cecf1bc78152e896 --- include/Nazara/Core/OffsetOf.hpp | 3 ++- src/Nazara/Graphics/DepthRenderTechnique.cpp | 2 -- src/Nazara/Graphics/ForwardRenderTechnique.cpp | 2 -- 3 files changed, 2 insertions(+), 5 deletions(-) diff --git a/include/Nazara/Core/OffsetOf.hpp b/include/Nazara/Core/OffsetOf.hpp index 4f13abacf..870481627 100644 --- a/include/Nazara/Core/OffsetOf.hpp +++ b/include/Nazara/Core/OffsetOf.hpp @@ -14,8 +14,9 @@ template T NzImplGetClassType(M T::*); template M NzImplGetMemberType(M T::*); template -constexpr std::size_t NzImplOffsetOf() +std::size_t NzImplOffsetOf() { + ///FIXME: reinterpret_cast is not allowed in constexpr functions return reinterpret_cast(&((static_cast(0))->*M)); } diff --git a/src/Nazara/Graphics/DepthRenderTechnique.cpp b/src/Nazara/Graphics/DepthRenderTechnique.cpp index c6da59276..9fe00be37 100644 --- a/src/Nazara/Graphics/DepthRenderTechnique.cpp +++ b/src/Nazara/Graphics/DepthRenderTechnique.cpp @@ -31,8 +31,6 @@ namespace NzVector2f uv; }; - static_assert(NzOffsetOf(BillboardPoint, sinCos) - NzOffsetOf(BillboardPoint, size) == sizeof(NzVector2f), "size and sinCos members should be packed"); - unsigned int s_maxQuads = std::numeric_limits::max()/6; unsigned int s_vertexBufferSize = 4*1024*1024; // 4 MiB } diff --git a/src/Nazara/Graphics/ForwardRenderTechnique.cpp b/src/Nazara/Graphics/ForwardRenderTechnique.cpp index 37e9efdde..656f34d5d 100644 --- a/src/Nazara/Graphics/ForwardRenderTechnique.cpp +++ b/src/Nazara/Graphics/ForwardRenderTechnique.cpp @@ -31,8 +31,6 @@ namespace NzVector2f uv; }; - static_assert(NzOffsetOf(BillboardPoint, sinCos) - NzOffsetOf(BillboardPoint, size) == sizeof(NzVector2f), "size and sinCos members should be packed"); - unsigned int s_maxQuads = std::numeric_limits::max()/6; unsigned int s_vertexBufferSize = 4*1024*1024; // 4 MiB } From 35066a3451bc972f79b3226fc937b03bf114fe4b Mon Sep 17 00:00:00 2001 From: Lynix Date: Wed, 17 Jun 2015 23:35:06 +0200 Subject: [PATCH 07/37] Math/Sphere: Fix (Squared)Distance Former-commit-id: d91c0d6e8a193e47c3ed45babaf3b83bf1cbe7ee --- include/Nazara/Math/Sphere.inl | 10 ++++------ include/Nazara/Math/Vector3.hpp | 3 +++ include/Nazara/Math/Vector3.inl | 18 ++++++++++++++++++ 3 files changed, 25 insertions(+), 6 deletions(-) diff --git a/include/Nazara/Math/Sphere.inl b/include/Nazara/Math/Sphere.inl index f8ece724c..f617d28e2 100644 --- a/include/Nazara/Math/Sphere.inl +++ b/include/Nazara/Math/Sphere.inl @@ -68,14 +68,13 @@ bool NzSphere::Contains(const NzVector3& point) const template T NzSphere::Distance(T X, T Y, T Z) const { - NzVector3 distance(X-x, Y-y, Z-z); - return distance.GetLength(); + return Distance({X, Y, Z}); } template T NzSphere::Distance(const NzVector3& point) const { - return Distance(point.x, point.y, point.z); + return NzVector3f::Distance(point, GetPosition()) - radius; } template @@ -249,14 +248,13 @@ NzSphere& NzSphere::Set(const NzSphere& sphere) template T NzSphere::SquaredDistance(T X, T Y, T Z) const { - NzVector3 distance(X-x, Y-y, Z-z); - return distance.GetSquaredLength(); + return SquaredDistance({X, Y, Z}); } template T NzSphere::SquaredDistance(const NzVector3& point) const { - return SquaredDistance(point.x, point.y, point.z); + return NzVector3f::Distance(point, GetPosition()) - radius * radius; } template diff --git a/include/Nazara/Math/Vector3.hpp b/include/Nazara/Math/Vector3.hpp index 14cd41b0a..f180816b2 100644 --- a/include/Nazara/Math/Vector3.hpp +++ b/include/Nazara/Math/Vector3.hpp @@ -103,12 +103,15 @@ class NzVector3 static NzVector3 Backward(); static NzVector3 CrossProduct(const NzVector3& vec1, const NzVector3& vec2); static T DotProduct(const NzVector3& vec1, const NzVector3& vec2); + static T Distance(const NzVector3& vec1, const NzVector3& vec2); + static float Distancef(const NzVector3& vec1, const NzVector3& vec2); static NzVector3 Down(); static NzVector3 Forward(); static NzVector3 Left(); static NzVector3 Lerp(const NzVector3& from, const NzVector3& to, T interpolation); static NzVector3 Normalize(const NzVector3& vec); static NzVector3 Right(); + static T SquaredDistance(const NzVector3& vec1, const NzVector3& vec2); static NzVector3 Unit(); static NzVector3 UnitX(); static NzVector3 UnitY(); diff --git a/include/Nazara/Math/Vector3.inl b/include/Nazara/Math/Vector3.inl index a2f0ed35c..0d6d10cf5 100644 --- a/include/Nazara/Math/Vector3.inl +++ b/include/Nazara/Math/Vector3.inl @@ -567,6 +567,18 @@ NzVector3 NzVector3::Backward() return vector; } +template +T NzVector3::Distance(const NzVector3& vec1, const NzVector3& vec2) +{ + return vec1.Distance(vec2); +} + +template +float NzVector3::Distancef(const NzVector3& vec1, const NzVector3& vec2) +{ + return vec1.Distancef(vec2); +} + template NzVector3 NzVector3::Down() { @@ -615,6 +627,12 @@ NzVector3 NzVector3::Right() return vector; } +template +T NzVector3::SquaredDistance(const NzVector3& vec1, const NzVector3& vec2) +{ + return vec1.SquaredDistance(vec2); +} + template NzVector3 NzVector3::Unit() { From 763701df7fc09dcd4ff16c918101f0162812ef14 Mon Sep 17 00:00:00 2001 From: Lynix Date: Wed, 17 Jun 2015 23:36:53 +0200 Subject: [PATCH 08/37] Graphics/Material: Inline class Former-commit-id: 7cd8b7a00c87adf087dae7d0fb8d955747cf82d1 --- include/Nazara/Graphics/Material.hpp | 148 ++++----- include/Nazara/Graphics/Material.inl | 468 ++++++++++++++++++++++++++ src/Nazara/Graphics/Material.cpp | 480 --------------------------- 3 files changed, 542 insertions(+), 554 deletions(-) diff --git a/include/Nazara/Graphics/Material.hpp b/include/Nazara/Graphics/Material.hpp index 59f8f800a..87f6ed615 100644 --- a/include/Nazara/Graphics/Material.hpp +++ b/include/Nazara/Graphics/Material.hpp @@ -53,90 +53,90 @@ class NAZARA_GRAPHICS_API NzMaterial : public NzRefCounted, public NzResource friend class NzGraphics; public: - NzMaterial(); - NzMaterial(const NzMaterial& material); - ~NzMaterial(); + inline NzMaterial(); + inline NzMaterial(const NzMaterial& material); + inline ~NzMaterial(); const NzShader* Apply(nzUInt32 shaderFlags = 0, nzUInt8 textureUnit = 0, nzUInt8* lastUsedUnit = nullptr) const; - void Enable(nzRendererParameter renderParameter, bool enable); - void EnableAlphaTest(bool alphaTest); - void EnableDepthSorting(bool depthSorting); - void EnableLighting(bool lighting); - void EnableTransform(bool transform); + inline void Enable(nzRendererParameter renderParameter, bool enable); + inline void EnableAlphaTest(bool alphaTest); + inline void EnableDepthSorting(bool depthSorting); + inline void EnableLighting(bool lighting); + inline void EnableTransform(bool transform); - NzTexture* GetAlphaMap() const; - float GetAlphaThreshold() const; - NzColor GetAmbientColor() const; - nzRendererComparison GetDepthFunc() const; - NzColor GetDiffuseColor() const; - NzTexture* GetDiffuseMap() const; - NzTextureSampler& GetDiffuseSampler(); - const NzTextureSampler& GetDiffuseSampler() const; - nzBlendFunc GetDstBlend() const; - NzTexture* GetEmissiveMap() const; - nzFaceSide GetFaceCulling() const; - nzFaceFilling GetFaceFilling() const; - NzTexture* GetHeightMap() const; - NzTexture* GetNormalMap() const; - const NzRenderStates& GetRenderStates() const; - const NzUberShader* GetShader() const; - const NzUberShaderInstance* GetShaderInstance(nzUInt32 flags = nzShaderFlags_None) const; - float GetShininess() const; - NzColor GetSpecularColor() const; - NzTexture* GetSpecularMap() const; - NzTextureSampler& GetSpecularSampler(); - const NzTextureSampler& GetSpecularSampler() const; - nzBlendFunc GetSrcBlend() const; + inline NzTexture* GetAlphaMap() const; + inline float GetAlphaThreshold() const; + inline NzColor GetAmbientColor() const; + inline nzRendererComparison GetDepthFunc() const; + inline NzColor GetDiffuseColor() const; + inline NzTexture* GetDiffuseMap() const; + inline NzTextureSampler& GetDiffuseSampler(); + inline const NzTextureSampler& GetDiffuseSampler() const; + inline nzBlendFunc GetDstBlend() const; + inline NzTexture* GetEmissiveMap() const; + inline nzFaceSide GetFaceCulling() const; + inline nzFaceFilling GetFaceFilling() const; + inline NzTexture* GetHeightMap() const; + inline NzTexture* GetNormalMap() const; + inline const NzRenderStates& GetRenderStates() const; + inline const NzUberShader* GetShader() const; + inline const NzUberShaderInstance* GetShaderInstance(nzUInt32 flags = nzShaderFlags_None) const; + inline float GetShininess() const; + inline NzColor GetSpecularColor() const; + inline NzTexture* GetSpecularMap() const; + inline NzTextureSampler& GetSpecularSampler(); + inline const NzTextureSampler& GetSpecularSampler() const; + inline nzBlendFunc GetSrcBlend() const; - bool HasAlphaMap() const; - bool HasDiffuseMap() const; - bool HasEmissiveMap() const; - bool HasHeightMap() const; - bool HasNormalMap() const; - bool HasSpecularMap() const; + inline bool HasAlphaMap() const; + inline bool HasDiffuseMap() const; + inline bool HasEmissiveMap() const; + inline bool HasHeightMap() const; + inline bool HasNormalMap() const; + inline bool HasSpecularMap() const; - bool IsAlphaTestEnabled() const; - bool IsDepthSortingEnabled() const; - bool IsEnabled(nzRendererParameter renderParameter) const; - bool IsLightingEnabled() const; - bool IsTransformEnabled() const; + inline bool IsAlphaTestEnabled() const; + inline bool IsDepthSortingEnabled() const; + inline bool IsEnabled(nzRendererParameter renderParameter) const; + inline bool IsLightingEnabled() const; + inline bool IsTransformEnabled() const; - bool LoadFromFile(const NzString& filePath, const NzMaterialParams& params = NzMaterialParams()); - bool LoadFromMemory(const void* data, std::size_t size, const NzMaterialParams& params = NzMaterialParams()); - bool LoadFromStream(NzInputStream& stream, const NzMaterialParams& params = NzMaterialParams()); + inline bool LoadFromFile(const NzString& filePath, const NzMaterialParams& params = NzMaterialParams()); + inline bool LoadFromMemory(const void* data, std::size_t size, const NzMaterialParams& params = NzMaterialParams()); + inline bool LoadFromStream(NzInputStream& stream, const NzMaterialParams& params = NzMaterialParams()); void Reset(); - bool SetAlphaMap(const NzString& textureName); - void SetAlphaMap(NzTextureRef alphaMap); - void SetAlphaThreshold(float alphaThreshold); - void SetAmbientColor(const NzColor& ambient); - void SetDepthFunc(nzRendererComparison depthFunc); - void SetDiffuseColor(const NzColor& diffuse); - bool SetDiffuseMap(const NzString& textureName); - void SetDiffuseMap(NzTextureRef diffuseMap); - void SetDiffuseSampler(const NzTextureSampler& sampler); - void SetDstBlend(nzBlendFunc func); - bool SetEmissiveMap(const NzString& textureName); - void SetEmissiveMap(NzTextureRef textureName); - void SetFaceCulling(nzFaceSide faceSide); - void SetFaceFilling(nzFaceFilling filling); - bool SetHeightMap(const NzString& textureName); - void SetHeightMap(NzTextureRef textureName); - bool SetNormalMap(const NzString& textureName); - void SetNormalMap(NzTextureRef textureName); - void SetRenderStates(const NzRenderStates& states); - void SetShader(NzUberShaderConstRef uberShader); - bool SetShader(const NzString& uberShaderName); - void SetShininess(float shininess); - void SetSpecularColor(const NzColor& specular); - bool SetSpecularMap(const NzString& textureName); - void SetSpecularMap(NzTextureRef specularMap); - void SetSpecularSampler(const NzTextureSampler& sampler); - void SetSrcBlend(nzBlendFunc func); + inline bool SetAlphaMap(const NzString& textureName); + inline void SetAlphaMap(NzTextureRef alphaMap); + inline void SetAlphaThreshold(float alphaThreshold); + inline void SetAmbientColor(const NzColor& ambient); + inline void SetDepthFunc(nzRendererComparison depthFunc); + inline void SetDiffuseColor(const NzColor& diffuse); + inline bool SetDiffuseMap(const NzString& textureName); + inline void SetDiffuseMap(NzTextureRef diffuseMap); + inline void SetDiffuseSampler(const NzTextureSampler& sampler); + inline void SetDstBlend(nzBlendFunc func); + inline bool SetEmissiveMap(const NzString& textureName); + inline void SetEmissiveMap(NzTextureRef textureName); + inline void SetFaceCulling(nzFaceSide faceSide); + inline void SetFaceFilling(nzFaceFilling filling); + inline bool SetHeightMap(const NzString& textureName); + inline void SetHeightMap(NzTextureRef textureName); + inline bool SetNormalMap(const NzString& textureName); + inline void SetNormalMap(NzTextureRef textureName); + inline void SetRenderStates(const NzRenderStates& states); + inline void SetShader(NzUberShaderConstRef uberShader); + inline bool SetShader(const NzString& uberShaderName); + inline void SetShininess(float shininess); + inline void SetSpecularColor(const NzColor& specular); + inline bool SetSpecularMap(const NzString& textureName); + inline void SetSpecularMap(NzTextureRef specularMap); + inline void SetSpecularSampler(const NzTextureSampler& sampler); + inline void SetSrcBlend(nzBlendFunc func); - NzMaterial& operator=(const NzMaterial& material); + inline NzMaterial& operator=(const NzMaterial& material); static NzMaterialRef GetDefault(); template static NzMaterialRef New(Args&&... args); @@ -155,7 +155,7 @@ class NAZARA_GRAPHICS_API NzMaterial : public NzRefCounted, public NzResource void Copy(const NzMaterial& material); void GenerateShader(nzUInt32 flags) const; - void InvalidateShaders(); + inline void InvalidateShaders(); static bool Initialize(); static void Uninitialize(); diff --git a/include/Nazara/Graphics/Material.inl b/include/Nazara/Graphics/Material.inl index 08c3d9b2d..aed3f2ceb 100644 --- a/include/Nazara/Graphics/Material.inl +++ b/include/Nazara/Graphics/Material.inl @@ -5,6 +5,474 @@ #include #include +inline NzMaterial::NzMaterial() +{ + Reset(); +} + +inline NzMaterial::NzMaterial(const NzMaterial& material) : + NzRefCounted(), + NzResource(material) +{ + Copy(material); +} + +inline NzMaterial::~NzMaterial() +{ + OnMaterialRelease(this); +} + +inline void NzMaterial::Enable(nzRendererParameter renderParameter, bool enable) +{ + NazaraAssert(parameter <= nzRendererParameter_Max, "Renderer parameter out of enum"); + + m_states.parameters[renderParameter] = enable; +} + +inline void NzMaterial::EnableAlphaTest(bool alphaTest) +{ + m_alphaTestEnabled = alphaTest; + + InvalidateShaders(); +} + +inline void NzMaterial::EnableDepthSorting(bool depthSorting) +{ + m_depthSortingEnabled = depthSorting; +} + +inline void NzMaterial::EnableLighting(bool lighting) +{ + m_lightingEnabled = lighting; + + InvalidateShaders(); +} + +inline void NzMaterial::EnableTransform(bool transform) +{ + m_transformEnabled = transform; + + InvalidateShaders(); +} + +inline NzTexture* NzMaterial::GetAlphaMap() const +{ + return m_alphaMap; +} + +inline float NzMaterial::GetAlphaThreshold() const +{ + return m_alphaThreshold; +} + +inline NzColor NzMaterial::GetAmbientColor() const +{ + return m_ambientColor; +} + +inline nzRendererComparison NzMaterial::GetDepthFunc() const +{ + return m_states.depthFunc; +} + +inline NzColor NzMaterial::GetDiffuseColor() const +{ + return m_diffuseColor; +} + +inline NzTextureSampler& NzMaterial::GetDiffuseSampler() +{ + return m_diffuseSampler; +} + +inline const NzTextureSampler& NzMaterial::GetDiffuseSampler() const +{ + return m_diffuseSampler; +} + +NzTexture* NzMaterial::GetDiffuseMap() const +{ + return m_diffuseMap; +} + +inline nzBlendFunc NzMaterial::GetDstBlend() const +{ + return m_states.dstBlend; +} + +inline NzTexture* NzMaterial::GetEmissiveMap() const +{ + return m_emissiveMap; +} + +inline nzFaceSide NzMaterial::GetFaceCulling() const +{ + return m_states.faceCulling; +} + +inline nzFaceFilling NzMaterial::GetFaceFilling() const +{ + return m_states.faceFilling; +} + +inline NzTexture* NzMaterial::GetHeightMap() const +{ + return m_heightMap; +} + +inline NzTexture* NzMaterial::GetNormalMap() const +{ + return m_normalMap; +} + +inline const NzRenderStates& NzMaterial::GetRenderStates() const +{ + return m_states; +} + +inline const NzUberShader* NzMaterial::GetShader() const +{ + return m_uberShader; +} + +inline const NzUberShaderInstance* NzMaterial::GetShaderInstance(nzUInt32 flags) const +{ + const ShaderInstance& instance = m_shaders[flags]; + if (!instance.uberInstance) + GenerateShader(flags); + + return instance.uberInstance; +} + +inline float NzMaterial::GetShininess() const +{ + return m_shininess; +} + +inline NzColor NzMaterial::GetSpecularColor() const +{ + return m_specularColor; +} + +inline NzTexture* NzMaterial::GetSpecularMap() const +{ + return m_specularMap; +} + +inline NzTextureSampler& NzMaterial::GetSpecularSampler() +{ + return m_specularSampler; +} + +inline const NzTextureSampler& NzMaterial::GetSpecularSampler() const +{ + return m_specularSampler; +} + +inline nzBlendFunc NzMaterial::GetSrcBlend() const +{ + return m_states.srcBlend; +} + +inline bool NzMaterial::HasAlphaMap() const +{ + return m_alphaMap.IsValid(); +} + +inline bool NzMaterial::HasDiffuseMap() const +{ + return m_diffuseMap.IsValid(); +} + +inline bool NzMaterial::HasEmissiveMap() const +{ + return m_emissiveMap.IsValid(); +} + +inline bool NzMaterial::HasHeightMap() const +{ + return m_heightMap.IsValid(); +} + +inline bool NzMaterial::HasNormalMap() const +{ + return m_normalMap.IsValid(); +} + +inline bool NzMaterial::HasSpecularMap() const +{ + return m_specularMap.IsValid(); +} + +inline bool NzMaterial::IsAlphaTestEnabled() const +{ + return m_alphaTestEnabled; +} + +inline bool NzMaterial::IsDepthSortingEnabled() const +{ + return m_depthSortingEnabled; +} + +inline bool NzMaterial::IsEnabled(nzRendererParameter parameter) const +{ + NazaraAssert(parameter <= nzRendererParameter_Max, "Renderer parameter out of enum"); + + return m_states.parameters[parameter]; +} + +inline bool NzMaterial::IsLightingEnabled() const +{ + return m_lightingEnabled; +} + +inline bool NzMaterial::IsTransformEnabled() const +{ + return m_transformEnabled; +} + +inline bool NzMaterial::LoadFromFile(const NzString& filePath, const NzMaterialParams& params) +{ + return NzMaterialLoader::LoadFromFile(this, filePath, params); +} + +inline bool NzMaterial::LoadFromMemory(const void* data, std::size_t size, const NzMaterialParams& params) +{ + return NzMaterialLoader::LoadFromMemory(this, data, size, params); +} + +inline bool NzMaterial::LoadFromStream(NzInputStream& stream, const NzMaterialParams& params) +{ + return NzMaterialLoader::LoadFromStream(this, stream, params); +} + +inline bool NzMaterial::SetAlphaMap(const NzString& textureName) +{ + NzTextureRef texture = NzTextureLibrary::Query(textureName); + if (!texture) + { + texture = NzTextureManager::Get(textureName); + if (!texture) + return false; + } + + SetAlphaMap(std::move(texture)); + return true; +} + +inline void NzMaterial::SetAlphaMap(NzTextureRef alphaMap) +{ + m_alphaMap = std::move(alphaMap); + + InvalidateShaders(); +} + +inline void NzMaterial::SetAlphaThreshold(float alphaThreshold) +{ + m_alphaThreshold = alphaThreshold; +} + +inline void NzMaterial::SetAmbientColor(const NzColor& ambient) +{ + m_ambientColor = ambient; +} + +inline void NzMaterial::SetDepthFunc(nzRendererComparison depthFunc) +{ + m_states.depthFunc = depthFunc; +} + +inline void NzMaterial::SetDiffuseColor(const NzColor& diffuse) +{ + m_diffuseColor = diffuse; +} + +inline bool NzMaterial::SetDiffuseMap(const NzString& textureName) +{ + NzTextureRef texture = NzTextureLibrary::Query(textureName); + if (!texture) + { + texture = NzTextureManager::Get(textureName); + if (!texture) + return false; + } + + SetDiffuseMap(std::move(texture)); + return true; +} + +inline void NzMaterial::SetDiffuseMap(NzTextureRef diffuseMap) +{ + m_diffuseMap = std::move(diffuseMap); + + InvalidateShaders(); +} + +inline void NzMaterial::SetDiffuseSampler(const NzTextureSampler& sampler) +{ + m_diffuseSampler = sampler; +} + +inline void NzMaterial::SetDstBlend(nzBlendFunc func) +{ + m_states.dstBlend = func; +} + +inline bool NzMaterial::SetEmissiveMap(const NzString& textureName) +{ + NzTextureRef texture = NzTextureLibrary::Query(textureName); + if (!texture) + { + texture = NzTextureManager::Get(textureName); + if (!texture) + return false; + } + + SetEmissiveMap(std::move(texture)); + return true; +} + +inline void NzMaterial::SetEmissiveMap(NzTextureRef emissiveMap) +{ + m_emissiveMap = std::move(emissiveMap); + + InvalidateShaders(); +} + +inline void NzMaterial::SetFaceCulling(nzFaceSide faceSide) +{ + m_states.faceCulling = faceSide; +} + +inline void NzMaterial::SetFaceFilling(nzFaceFilling filling) +{ + m_states.faceFilling = filling; +} + +inline bool NzMaterial::SetHeightMap(const NzString& textureName) +{ + NzTextureRef texture = NzTextureLibrary::Query(textureName); + if (!texture) + { + texture = NzTextureManager::Get(textureName); + if (!texture) + return false; + } + + SetHeightMap(std::move(texture)); + return true; +} + +inline void NzMaterial::SetHeightMap(NzTextureRef heightMap) +{ + m_heightMap = std::move(heightMap); + + InvalidateShaders(); +} + +inline bool NzMaterial::SetNormalMap(const NzString& textureName) +{ + NzTextureRef texture = NzTextureLibrary::Query(textureName); + if (!texture) + { + texture = NzTextureManager::Get(textureName); + if (!texture) + return false; + } + + SetNormalMap(std::move(texture)); + return true; +} + +inline void NzMaterial::SetNormalMap(NzTextureRef normalMap) +{ + m_normalMap = std::move(normalMap); + + InvalidateShaders(); +} + +inline void NzMaterial::SetRenderStates(const NzRenderStates& states) +{ + m_states = states; +} + +inline void NzMaterial::SetShader(NzUberShaderConstRef uberShader) +{ + m_uberShader = std::move(uberShader); + + InvalidateShaders(); +} + +inline bool NzMaterial::SetShader(const NzString& uberShaderName) +{ + NzUberShaderConstRef uberShader = NzUberShaderLibrary::Get(uberShaderName); + if (!uberShader) + return false; + + SetShader(std::move(uberShader)); + return true; +} + +inline void NzMaterial::SetShininess(float shininess) +{ + m_shininess = shininess; +} + +inline void NzMaterial::SetSpecularColor(const NzColor& specular) +{ + m_specularColor = specular; +} + +inline bool NzMaterial::SetSpecularMap(const NzString& textureName) +{ + NzTextureRef texture = NzTextureLibrary::Query(textureName); + if (!texture) + { + texture = NzTextureManager::Get(textureName); + if (!texture) + return false; + } + + SetSpecularMap(std::move(texture)); + return true; +} + +inline void NzMaterial::SetSpecularMap(NzTextureRef specularMap) +{ + m_specularMap = std::move(specularMap); + + InvalidateShaders(); +} + +inline void NzMaterial::SetSpecularSampler(const NzTextureSampler& sampler) +{ + m_specularSampler = sampler; +} + +inline void NzMaterial::SetSrcBlend(nzBlendFunc func) +{ + m_states.srcBlend = func; +} + +inline NzMaterial& NzMaterial::operator=(const NzMaterial& material) +{ + NzResource::operator=(material); + + Copy(material); + return *this; +} + +inline NzMaterialRef NzMaterial::GetDefault() +{ + return s_defaultMaterial; +} + +inline void NzMaterial::InvalidateShaders() +{ + for (ShaderInstance& instance : m_shaders) + instance.uberInstance = nullptr; +} + template NzMaterialRef NzMaterial::New(Args&&... args) { diff --git a/src/Nazara/Graphics/Material.cpp b/src/Nazara/Graphics/Material.cpp index ce569a127..382cf4d2c 100644 --- a/src/Nazara/Graphics/Material.cpp +++ b/src/Nazara/Graphics/Material.cpp @@ -41,23 +41,6 @@ bool NzMaterialParams::IsValid() const return true; } -NzMaterial::NzMaterial() -{ - Reset(); -} - -NzMaterial::NzMaterial(const NzMaterial& material) : -NzRefCounted(), -NzResource(material) -{ - Copy(material); -} - -NzMaterial::~NzMaterial() -{ - OnMaterialRelease(this); -} - const NzShader* NzMaterial::Apply(nzUInt32 shaderFlags, nzUInt8 textureUnit, nzUInt8* lastUsedUnit) const { const ShaderInstance& instance = m_shaders[shaderFlags]; @@ -137,242 +120,6 @@ const NzShader* NzMaterial::Apply(nzUInt32 shaderFlags, nzUInt8 textureUnit, nzU return instance.shader; } -void NzMaterial::Enable(nzRendererParameter renderParameter, bool enable) -{ - #ifdef NAZARA_DEBUG - if (renderParameter > nzRendererParameter_Max) - { - NazaraError("Renderer parameter out of enum"); - return; - } - #endif - - m_states.parameters[renderParameter] = enable; -} - -void NzMaterial::EnableAlphaTest(bool alphaTest) -{ - m_alphaTestEnabled = alphaTest; - - InvalidateShaders(); -} - -void NzMaterial::EnableDepthSorting(bool depthSorting) -{ - m_depthSortingEnabled = depthSorting; -} - -void NzMaterial::EnableLighting(bool lighting) -{ - m_lightingEnabled = lighting; - - InvalidateShaders(); -} - -void NzMaterial::EnableTransform(bool transform) -{ - m_transformEnabled = transform; - - InvalidateShaders(); -} - -NzTexture* NzMaterial::GetAlphaMap() const -{ - return m_alphaMap; -} - -float NzMaterial::GetAlphaThreshold() const -{ - return m_alphaThreshold; -} - -NzColor NzMaterial::GetAmbientColor() const -{ - return m_ambientColor; -} - -nzRendererComparison NzMaterial::GetDepthFunc() const -{ - return m_states.depthFunc; -} - -NzColor NzMaterial::GetDiffuseColor() const -{ - return m_diffuseColor; -} - -NzTextureSampler& NzMaterial::GetDiffuseSampler() -{ - return m_diffuseSampler; -} - -const NzTextureSampler& NzMaterial::GetDiffuseSampler() const -{ - return m_diffuseSampler; -} - -NzTexture* NzMaterial::GetDiffuseMap() const -{ - return m_diffuseMap; -} - -nzBlendFunc NzMaterial::GetDstBlend() const -{ - return m_states.dstBlend; -} - -NzTexture* NzMaterial::GetEmissiveMap() const -{ - return m_emissiveMap; -} - -nzFaceSide NzMaterial::GetFaceCulling() const -{ - return m_states.faceCulling; -} - -nzFaceFilling NzMaterial::GetFaceFilling() const -{ - return m_states.faceFilling; -} - -NzTexture* NzMaterial::GetHeightMap() const -{ - return m_heightMap; -} - -NzTexture* NzMaterial::GetNormalMap() const -{ - return m_normalMap; -} - -const NzRenderStates& NzMaterial::GetRenderStates() const -{ - return m_states; -} - -const NzUberShader* NzMaterial::GetShader() const -{ - return m_uberShader; -} - -const NzUberShaderInstance* NzMaterial::GetShaderInstance(nzUInt32 flags) const -{ - const ShaderInstance& instance = m_shaders[flags]; - if (!instance.uberInstance) - GenerateShader(flags); - - return instance.uberInstance; -} - -float NzMaterial::GetShininess() const -{ - return m_shininess; -} - -NzColor NzMaterial::GetSpecularColor() const -{ - return m_specularColor; -} - -NzTexture* NzMaterial::GetSpecularMap() const -{ - return m_specularMap; -} - -NzTextureSampler& NzMaterial::GetSpecularSampler() -{ - return m_specularSampler; -} - -const NzTextureSampler& NzMaterial::GetSpecularSampler() const -{ - return m_specularSampler; -} - -nzBlendFunc NzMaterial::GetSrcBlend() const -{ - return m_states.srcBlend; -} - -bool NzMaterial::HasAlphaMap() const -{ - return m_alphaMap.IsValid(); -} - -bool NzMaterial::HasDiffuseMap() const -{ - return m_diffuseMap.IsValid(); -} - -bool NzMaterial::HasEmissiveMap() const -{ - return m_emissiveMap.IsValid(); -} - -bool NzMaterial::HasHeightMap() const -{ - return m_heightMap.IsValid(); -} - -bool NzMaterial::HasNormalMap() const -{ - return m_normalMap.IsValid(); -} - -bool NzMaterial::HasSpecularMap() const -{ - return m_specularMap.IsValid(); -} - -bool NzMaterial::IsAlphaTestEnabled() const -{ - return m_alphaTestEnabled; -} - -bool NzMaterial::IsDepthSortingEnabled() const -{ - return m_depthSortingEnabled; -} - -bool NzMaterial::IsEnabled(nzRendererParameter parameter) const -{ - #ifdef NAZARA_DEBUG - if (parameter > nzRendererParameter_Max) - { - NazaraError("Renderer parameter out of enum"); - return false; - } - #endif - - return m_states.parameters[parameter]; -} - -bool NzMaterial::IsLightingEnabled() const -{ - return m_lightingEnabled; -} - -bool NzMaterial::IsTransformEnabled() const -{ - return m_transformEnabled; -} - -bool NzMaterial::LoadFromFile(const NzString& filePath, const NzMaterialParams& params) -{ - return NzMaterialLoader::LoadFromFile(this, filePath, params); -} - -bool NzMaterial::LoadFromMemory(const void* data, std::size_t size, const NzMaterialParams& params) -{ - return NzMaterialLoader::LoadFromMemory(this, data, size, params); -} - -bool NzMaterial::LoadFromStream(NzInputStream& stream, const NzMaterialParams& params) -{ - return NzMaterialLoader::LoadFromStream(this, stream, params); -} - void NzMaterial::Reset() { OnMaterialReset(this); @@ -406,227 +153,6 @@ void NzMaterial::Reset() SetShader("Basic"); } -bool NzMaterial::SetAlphaMap(const NzString& textureName) -{ - NzTextureRef texture = NzTextureLibrary::Query(textureName); - if (!texture) - { - texture = NzTextureManager::Get(textureName); - if (!texture) - return false; - } - - SetAlphaMap(std::move(texture)); - return true; -} - -void NzMaterial::SetAlphaMap(NzTextureRef alphaMap) -{ - m_alphaMap = std::move(alphaMap); - - InvalidateShaders(); -} - -void NzMaterial::SetAlphaThreshold(float alphaThreshold) -{ - m_alphaThreshold = alphaThreshold; -} - -void NzMaterial::SetAmbientColor(const NzColor& ambient) -{ - m_ambientColor = ambient; -} - -void NzMaterial::SetDepthFunc(nzRendererComparison depthFunc) -{ - m_states.depthFunc = depthFunc; -} - -void NzMaterial::SetDiffuseColor(const NzColor& diffuse) -{ - m_diffuseColor = diffuse; -} - -bool NzMaterial::SetDiffuseMap(const NzString& textureName) -{ - NzTextureRef texture = NzTextureLibrary::Query(textureName); - if (!texture) - { - texture = NzTextureManager::Get(textureName); - if (!texture) - return false; - } - - SetDiffuseMap(std::move(texture)); - return true; -} - -void NzMaterial::SetDiffuseMap(NzTextureRef diffuseMap) -{ - m_diffuseMap = std::move(diffuseMap); - - InvalidateShaders(); -} - -void NzMaterial::SetDiffuseSampler(const NzTextureSampler& sampler) -{ - m_diffuseSampler = sampler; -} - -void NzMaterial::SetDstBlend(nzBlendFunc func) -{ - m_states.dstBlend = func; -} - -bool NzMaterial::SetEmissiveMap(const NzString& textureName) -{ - NzTextureRef texture = NzTextureLibrary::Query(textureName); - if (!texture) - { - texture = NzTextureManager::Get(textureName); - if (!texture) - return false; - } - - SetEmissiveMap(std::move(texture)); - return true; -} - -void NzMaterial::SetEmissiveMap(NzTextureRef emissiveMap) -{ - m_emissiveMap = std::move(emissiveMap); - - InvalidateShaders(); -} - -void NzMaterial::SetFaceCulling(nzFaceSide faceSide) -{ - m_states.faceCulling = faceSide; -} - -void NzMaterial::SetFaceFilling(nzFaceFilling filling) -{ - m_states.faceFilling = filling; -} - -bool NzMaterial::SetHeightMap(const NzString& textureName) -{ - NzTextureRef texture = NzTextureLibrary::Query(textureName); - if (!texture) - { - texture = NzTextureManager::Get(textureName); - if (!texture) - return false; - } - - SetHeightMap(std::move(texture)); - return true; -} - -void NzMaterial::SetHeightMap(NzTextureRef heightMap) -{ - m_heightMap = std::move(heightMap); - - InvalidateShaders(); -} - -bool NzMaterial::SetNormalMap(const NzString& textureName) -{ - NzTextureRef texture = NzTextureLibrary::Query(textureName); - if (!texture) - { - texture = NzTextureManager::Get(textureName); - if (!texture) - return false; - } - - SetNormalMap(std::move(texture)); - return true; -} - -void NzMaterial::SetNormalMap(NzTextureRef normalMap) -{ - m_normalMap = std::move(normalMap); - - InvalidateShaders(); -} - -void NzMaterial::SetRenderStates(const NzRenderStates& states) -{ - m_states = states; -} - -void NzMaterial::SetShader(NzUberShaderConstRef uberShader) -{ - m_uberShader = std::move(uberShader); - - InvalidateShaders(); -} - -bool NzMaterial::SetShader(const NzString& uberShaderName) -{ - NzUberShaderConstRef uberShader = NzUberShaderLibrary::Get(uberShaderName); - if (!uberShader) - return false; - - SetShader(std::move(uberShader)); - return true; -} - -void NzMaterial::SetShininess(float shininess) -{ - m_shininess = shininess; -} - -void NzMaterial::SetSpecularColor(const NzColor& specular) -{ - m_specularColor = specular; -} - -bool NzMaterial::SetSpecularMap(const NzString& textureName) -{ - NzTextureRef texture = NzTextureLibrary::Query(textureName); - if (!texture) - { - texture = NzTextureManager::Get(textureName); - if (!texture) - return false; - } - - SetSpecularMap(std::move(texture)); - return true; -} - -void NzMaterial::SetSpecularMap(NzTextureRef specularMap) -{ - m_specularMap = std::move(specularMap); - - InvalidateShaders(); -} - -void NzMaterial::SetSpecularSampler(const NzTextureSampler& sampler) -{ - m_specularSampler = sampler; -} - -void NzMaterial::SetSrcBlend(nzBlendFunc func) -{ - m_states.srcBlend = func; -} - -NzMaterial& NzMaterial::operator=(const NzMaterial& material) -{ - NzResource::operator=(material); - - Copy(material); - return *this; -} - -NzMaterialRef NzMaterial::GetDefault() -{ - return s_defaultMaterial; -} - void NzMaterial::Copy(const NzMaterial& material) { // Copie des états de base @@ -702,12 +228,6 @@ void NzMaterial::GenerateShader(nzUInt32 flags) const #undef CacheUniform } -void NzMaterial::InvalidateShaders() -{ - for (ShaderInstance& instance : m_shaders) - instance.uberInstance = nullptr; -} - bool NzMaterial::Initialize() { if (!NzMaterialLibrary::Initialize()) From ac8578c510c54cb5edcc82888bfe96ab165ca5fe Mon Sep 17 00:00:00 2001 From: Lynix Date: Thu, 18 Jun 2015 00:03:38 +0200 Subject: [PATCH 09/37] Graphics/Material: Add shadow support The real fun will be in the shader Former-commit-id: e29e98cbf3c35e4cf14c68852e03dc9da1df0ff1 --- include/Nazara/Graphics/Material.hpp | 6 ++++++ include/Nazara/Graphics/Material.inl | 24 ++++++++++++++++++++++++ src/Nazara/Graphics/Material.cpp | 1 + 3 files changed, 31 insertions(+) diff --git a/include/Nazara/Graphics/Material.hpp b/include/Nazara/Graphics/Material.hpp index 87f6ed615..2d09c2f35 100644 --- a/include/Nazara/Graphics/Material.hpp +++ b/include/Nazara/Graphics/Material.hpp @@ -63,6 +63,8 @@ class NAZARA_GRAPHICS_API NzMaterial : public NzRefCounted, public NzResource inline void EnableAlphaTest(bool alphaTest); inline void EnableDepthSorting(bool depthSorting); inline void EnableLighting(bool lighting); + inline void EnableShadowCasting(bool castShadows); + inline void EnableShadowReceive(bool receiveShadows); inline void EnableTransform(bool transform); inline NzTexture* GetAlphaMap() const; @@ -100,6 +102,8 @@ class NAZARA_GRAPHICS_API NzMaterial : public NzRefCounted, public NzResource inline bool IsDepthSortingEnabled() const; inline bool IsEnabled(nzRendererParameter renderParameter) const; inline bool IsLightingEnabled() const; + inline bool IsShadowCastingEnabled() const; + inline bool IsShadowReceiveEnabled() const; inline bool IsTransformEnabled() const; inline bool LoadFromFile(const NzString& filePath, const NzMaterialParams& params = NzMaterialParams()); @@ -177,6 +181,8 @@ class NAZARA_GRAPHICS_API NzMaterial : public NzRefCounted, public NzResource bool m_alphaTestEnabled; bool m_depthSortingEnabled; bool m_lightingEnabled; + bool m_shadowCastingEnabled; + bool m_shadowReceiveEnabled; bool m_transformEnabled; float m_alphaThreshold; float m_shininess; diff --git a/include/Nazara/Graphics/Material.inl b/include/Nazara/Graphics/Material.inl index aed3f2ceb..93cca4bb0 100644 --- a/include/Nazara/Graphics/Material.inl +++ b/include/Nazara/Graphics/Material.inl @@ -38,6 +38,7 @@ inline void NzMaterial::EnableAlphaTest(bool alphaTest) inline void NzMaterial::EnableDepthSorting(bool depthSorting) { + // Has no influence on shaders m_depthSortingEnabled = depthSorting; } @@ -48,6 +49,19 @@ inline void NzMaterial::EnableLighting(bool lighting) InvalidateShaders(); } +inline void NzMaterial::EnableShadowCasting(bool castShadows) +{ + // Has no influence on shaders + m_shadowCastingEnabled = castShadows; +} + +inline void NzMaterial::EnableShadowReceive(bool receiveShadows) +{ + m_shadowReceiveEnabled = receiveShadows; + + InvalidateShaders(); +} + inline void NzMaterial::EnableTransform(bool transform) { m_transformEnabled = transform; @@ -226,6 +240,16 @@ inline bool NzMaterial::IsLightingEnabled() const return m_lightingEnabled; } +inline bool NzMaterial::IsShadowCastingEnabled() const +{ + return m_shadowCastingEnabled; +} + +inline bool NzMaterial::IsShadowReceiveEnabled() const +{ + return m_shadowReceiveEnabled; +} + inline bool NzMaterial::IsTransformEnabled() const { return m_transformEnabled; diff --git a/src/Nazara/Graphics/Material.cpp b/src/Nazara/Graphics/Material.cpp index 382cf4d2c..e6cd9ff1b 100644 --- a/src/Nazara/Graphics/Material.cpp +++ b/src/Nazara/Graphics/Material.cpp @@ -195,6 +195,7 @@ void NzMaterial::GenerateShader(nzUInt32 flags) const list.SetParameter("LIGHTING", m_lightingEnabled); list.SetParameter("NORMAL_MAPPING", m_normalMap.IsValid()); list.SetParameter("PARALLAX_MAPPING", m_heightMap.IsValid()); + list.SetParameter("SHADOW_MAPPING", m_shadowReceiveEnabled); list.SetParameter("SPECULAR_MAPPING", m_specularMap.IsValid()); list.SetParameter("TEXTURE_MAPPING", m_alphaMap.IsValid() || m_diffuseMap.IsValid() || m_emissiveMap.IsValid() || m_normalMap.IsValid() || m_heightMap.IsValid() || m_specularMap.IsValid() || From 8472578e422eb4218b843463f7912c83dedcf0a9 Mon Sep 17 00:00:00 2001 From: Lynix Date: Thu, 18 Jun 2015 12:09:51 +0200 Subject: [PATCH 10/37] Graphics/Material: Fix compilation error Former-commit-id: 1cb87781afd8de0f6aaf4f6cbac861d5a1f8f717 --- include/Nazara/Graphics/Material.inl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/Nazara/Graphics/Material.inl b/include/Nazara/Graphics/Material.inl index 93cca4bb0..23a9433f5 100644 --- a/include/Nazara/Graphics/Material.inl +++ b/include/Nazara/Graphics/Material.inl @@ -24,7 +24,7 @@ inline NzMaterial::~NzMaterial() inline void NzMaterial::Enable(nzRendererParameter renderParameter, bool enable) { - NazaraAssert(parameter <= nzRendererParameter_Max, "Renderer parameter out of enum"); + NazaraAssert(renderParameter <= nzRendererParameter_Max, "Renderer parameter out of enum"); m_states.parameters[renderParameter] = enable; } From 286de8b5382a5a3c5ae76135e26f45893f7764b3 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 21 Jun 2015 13:10:03 +0200 Subject: [PATCH 11/37] Graphics/Material: Fix debug build Former-commit-id: eccbb4c2a0d9ab1a5d9d942087809c0079a422c1 --- include/Nazara/Graphics/Material.inl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/Nazara/Graphics/Material.inl b/include/Nazara/Graphics/Material.inl index 93cca4bb0..23a9433f5 100644 --- a/include/Nazara/Graphics/Material.inl +++ b/include/Nazara/Graphics/Material.inl @@ -24,7 +24,7 @@ inline NzMaterial::~NzMaterial() inline void NzMaterial::Enable(nzRendererParameter renderParameter, bool enable) { - NazaraAssert(parameter <= nzRendererParameter_Max, "Renderer parameter out of enum"); + NazaraAssert(renderParameter <= nzRendererParameter_Max, "Renderer parameter out of enum"); m_states.parameters[renderParameter] = enable; } From 1593b7969fc50cb320b9037235c94e9b0a18b787 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 21 Jun 2015 13:11:03 +0200 Subject: [PATCH 12/37] Graphics/Material: Fix shadow states initialize/copy/parameter Former-commit-id: efe926baa3a5f00e04e7443b3463730e0d16edf7 --- src/Nazara/Graphics/Material.cpp | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/src/Nazara/Graphics/Material.cpp b/src/Nazara/Graphics/Material.cpp index e6cd9ff1b..bc8b5a002 100644 --- a/src/Nazara/Graphics/Material.cpp +++ b/src/Nazara/Graphics/Material.cpp @@ -142,6 +142,8 @@ void NzMaterial::Reset() m_diffuseColor = NzColor::White; m_diffuseSampler = NzTextureSampler(); m_lightingEnabled = true; + m_shadowCastingEnabled = true; + m_shadowReceiveEnabled = true; m_shininess = 50.f; m_specularColor = NzColor::White; m_specularSampler = NzTextureSampler(); @@ -156,18 +158,20 @@ void NzMaterial::Reset() void NzMaterial::Copy(const NzMaterial& material) { // Copie des états de base - m_alphaTestEnabled = material.m_alphaTestEnabled; - m_alphaThreshold = material.m_alphaThreshold; - m_ambientColor = material.m_ambientColor; - m_depthSortingEnabled = material.m_depthSortingEnabled; - m_diffuseColor = material.m_diffuseColor; - m_diffuseSampler = material.m_diffuseSampler; - m_lightingEnabled = material.m_lightingEnabled; - m_shininess = material.m_shininess; - m_specularColor = material.m_specularColor; - m_specularSampler = material.m_specularSampler; - m_states = material.m_states; - m_transformEnabled = material.m_transformEnabled; + m_alphaTestEnabled = material.m_alphaTestEnabled; + m_alphaThreshold = material.m_alphaThreshold; + m_ambientColor = material.m_ambientColor; + m_depthSortingEnabled = material.m_depthSortingEnabled; + m_diffuseColor = material.m_diffuseColor; + m_diffuseSampler = material.m_diffuseSampler; + m_lightingEnabled = material.m_lightingEnabled; + m_shininess = material.m_shininess; + m_shadowCastingEnabled = material.m_shadowCastingEnabled; + m_shadowReceiveEnabled = material.m_shadowReceiveEnabled; + m_specularColor = material.m_specularColor; + m_specularSampler = material.m_specularSampler; + m_states = material.m_states; + m_transformEnabled = material.m_transformEnabled; // Copie des références de texture m_alphaMap = material.m_alphaMap; @@ -301,8 +305,8 @@ bool NzMaterial::Initialize() vertexShader.Set(reinterpret_cast(compatibilityVertexShader), sizeof(compatibilityVertexShader)); } - uberShader->SetShader(nzShaderStage_Fragment, fragmentShader, "FLAG_DEFERRED FLAG_TEXTUREOVERLAY ALPHA_MAPPING ALPHA_TEST AUTO_TEXCOORDS DIFFUSE_MAPPING EMISSIVE_MAPPING LIGHTING NORMAL_MAPPING PARALLAX_MAPPING SPECULAR_MAPPING"); - uberShader->SetShader(nzShaderStage_Vertex, vertexShader, "FLAG_BILLBOARD FLAG_DEFERRED FLAG_INSTANCING FLAG_VERTEXCOLOR COMPUTE_TBNMATRIX LIGHTING PARALLAX_MAPPING TEXTURE_MAPPING TRANSFORM UNIFORM_VERTEX_DEPTH"); + uberShader->SetShader(nzShaderStage_Fragment, fragmentShader, "FLAG_DEFERRED FLAG_TEXTUREOVERLAY ALPHA_MAPPING ALPHA_TEST AUTO_TEXCOORDS DIFFUSE_MAPPING EMISSIVE_MAPPING LIGHTING NORMAL_MAPPING PARALLAX_MAPPING SHADOW_MAPPING SPECULAR_MAPPING"); + uberShader->SetShader(nzShaderStage_Vertex, vertexShader, "FLAG_BILLBOARD FLAG_DEFERRED FLAG_INSTANCING FLAG_VERTEXCOLOR COMPUTE_TBNMATRIX LIGHTING PARALLAX_MAPPING SHADOW_MAPPING TEXTURE_MAPPING TRANSFORM UNIFORM_VERTEX_DEPTH"); NzUberShaderLibrary::Register("PhongLighting", uberShader); } From 685f8c99da15814b423894fa1e684521a0db4f7f Mon Sep 17 00:00:00 2001 From: Lynix Date: Mon, 22 Jun 2015 13:36:34 +0200 Subject: [PATCH 13/37] Sdk/RenderSystem: Fix code duplication (merge fail) Former-commit-id: ac552375a50d333b53b11c435c88e647a7cd0817 --- SDK/src/NDK/Systems/RenderSystem.cpp | 31 ---------------------------- 1 file changed, 31 deletions(-) diff --git a/SDK/src/NDK/Systems/RenderSystem.cpp b/SDK/src/NDK/Systems/RenderSystem.cpp index e5ef93907..03da11d8d 100644 --- a/SDK/src/NDK/Systems/RenderSystem.cpp +++ b/SDK/src/NDK/Systems/RenderSystem.cpp @@ -48,37 +48,6 @@ namespace Ndk m_lights.Remove(entity); } - void RenderSystem::OnEntityRemoved(Entity* entity) - { - m_cameras.Remove(entity); - m_drawables.Remove(entity); - m_lights.Remove(entity); - } - - void RenderSystem::OnEntityValidation(Entity* entity, bool justAdded) - { - if (entity->HasComponent() && entity->HasComponent()) - { - m_cameras.Insert(entity); - std::sort(m_cameras.begin(), m_cameras.end(), [](const EntityHandle& handle1, const EntityHandle& handle2) - { - return handle1->GetComponent().GetLayer() < handle2->GetComponent().GetLayer(); - }); - } - else - m_cameras.Remove(entity); - - if (entity->HasComponent() && entity->HasComponent()) - m_drawables.Insert(entity); - else - m_drawables.Remove(entity); - - if (entity->HasComponent() && entity->HasComponent()) - m_lights.Insert(entity); - else - m_lights.Remove(entity); - } - void RenderSystem::OnUpdate(float elapsedTime) { UpdateShadowMaps(); From 7dd4965f9a0cc66a710b66658477f6c3ffe8879e Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 26 Jun 2015 14:05:50 +0200 Subject: [PATCH 14/37] Math/Matrix4: Fix cotangent in projection matrix Former-commit-id: 57ccfc4fd2a1a8245272328204afa6590a5cb3fb --- include/Nazara/Math/Algorithm.hpp | 4 ++++ include/Nazara/Math/Matrix4.inl | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/include/Nazara/Math/Algorithm.hpp b/include/Nazara/Math/Algorithm.hpp index 070d048aa..0d0776746 100644 --- a/include/Nazara/Math/Algorithm.hpp +++ b/include/Nazara/Math/Algorithm.hpp @@ -16,6 +16,10 @@ #define M_PI 3.141592653589793238462643 #endif +#ifndef M_PI_2 +#define M_PI_2 1.5707963267948966192313217 +#endif + #ifndef M_SQRT2 #define M_SQRT2 1.4142135623730950488016887 #endif diff --git a/include/Nazara/Math/Matrix4.inl b/include/Nazara/Math/Matrix4.inl index 694ef446a..6816bbd72 100644 --- a/include/Nazara/Math/Matrix4.inl +++ b/include/Nazara/Math/Matrix4.inl @@ -623,7 +623,7 @@ NzMatrix4& NzMatrix4::MakePerspective(T angle, T ratio, T zNear, T zFar) angle = NzDegreeToRadian(angle/F(2.0)); #endif - T yScale = F(1.0) / std::tan(angle); + T yScale = std::tan(M_PI_2 - angle); Set(yScale / ratio, F(0.0), F(0.0), F(0.0), F(0.0), yScale, F(0.0), F(0.0), From d93229a9acd942a96347693c6dbd13b26e08dcd9 Mon Sep 17 00:00:00 2001 From: Lynix Date: Tue, 30 Jun 2015 20:44:01 +0200 Subject: [PATCH 15/37] Fix compilation error Former-commit-id: 5f264fc941898921da408b836c385d4073ebe3ae --- SDK/src/NDK/Systems/RenderSystem.cpp | 1 - src/Nazara/Graphics/DepthRenderTechnique.cpp | 1 - 2 files changed, 2 deletions(-) diff --git a/SDK/src/NDK/Systems/RenderSystem.cpp b/SDK/src/NDK/Systems/RenderSystem.cpp index dfeb04928..e5057dc66 100644 --- a/SDK/src/NDK/Systems/RenderSystem.cpp +++ b/SDK/src/NDK/Systems/RenderSystem.cpp @@ -3,7 +3,6 @@ // For conditions of distribution and use, see copyright notice in Prerequesites.hpp #include -#include #include #include #include diff --git a/src/Nazara/Graphics/DepthRenderTechnique.cpp b/src/Nazara/Graphics/DepthRenderTechnique.cpp index 9fe00be37..e76b0c981 100644 --- a/src/Nazara/Graphics/DepthRenderTechnique.cpp +++ b/src/Nazara/Graphics/DepthRenderTechnique.cpp @@ -6,7 +6,6 @@ #include #include #include -#include #include #include #include From 34e8271d24ecf20527281ec66b317098d9239916 Mon Sep 17 00:00:00 2001 From: Lynix Date: Tue, 30 Jun 2015 20:44:37 +0200 Subject: [PATCH 16/37] Fix warnings Former-commit-id: 42f2d38f7bf5143d91da6a0fa7dc7d3b88ce56ea --- include/Nazara/Math/Matrix4.inl | 2 +- src/Nazara/Graphics/DepthRenderQueue.cpp | 2 ++ src/Nazara/Graphics/DepthRenderTechnique.cpp | 6 ++++++ 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/include/Nazara/Math/Matrix4.inl b/include/Nazara/Math/Matrix4.inl index 6816bbd72..ac140fe9a 100644 --- a/include/Nazara/Math/Matrix4.inl +++ b/include/Nazara/Math/Matrix4.inl @@ -623,7 +623,7 @@ NzMatrix4& NzMatrix4::MakePerspective(T angle, T ratio, T zNear, T zFar) angle = NzDegreeToRadian(angle/F(2.0)); #endif - T yScale = std::tan(M_PI_2 - angle); + T yScale = std::tan(T(M_PI_2) - angle); Set(yScale / ratio, F(0.0), F(0.0), F(0.0), F(0.0), yScale, F(0.0), F(0.0), diff --git a/src/Nazara/Graphics/DepthRenderQueue.cpp b/src/Nazara/Graphics/DepthRenderQueue.cpp index 613033015..e038c3bbd 100644 --- a/src/Nazara/Graphics/DepthRenderQueue.cpp +++ b/src/Nazara/Graphics/DepthRenderQueue.cpp @@ -297,6 +297,7 @@ void NzDepthRenderQueue::AddDrawable(const NzDrawable* drawable) void NzDepthRenderQueue::AddMesh(const NzMaterial* material, const NzMeshData& meshData, const NzBoxf& meshAABB, const NzMatrix4f& transformMatrix) { NazaraAssert(material, "Invalid material"); + NazaraUnused(meshAABB); if (!IsMaterialSuitable(material)) return; @@ -325,6 +326,7 @@ void NzDepthRenderQueue::AddMesh(const NzMaterial* material, const NzMeshData& m void NzDepthRenderQueue::AddSprites(const NzMaterial* material, const NzVertexStruct_XYZ_Color_UV* vertices, unsigned int spriteCount, const NzTexture* overlay) { NazaraAssert(material, "Invalid material"); + NazaraUnused(overlay); if (!IsMaterialSuitable(material)) return; diff --git a/src/Nazara/Graphics/DepthRenderTechnique.cpp b/src/Nazara/Graphics/DepthRenderTechnique.cpp index e76b0c981..6ec9dfaf3 100644 --- a/src/Nazara/Graphics/DepthRenderTechnique.cpp +++ b/src/Nazara/Graphics/DepthRenderTechnique.cpp @@ -153,6 +153,8 @@ void NzDepthRenderTechnique::Uninitialize() void NzDepthRenderTechnique::DrawBasicSprites(const NzSceneData& sceneData) const { + NazaraUnused(sceneData); + NzRenderer::SetIndexBuffer(&s_quadIndexBuffer); NzRenderer::SetMatrix(nzMatrixType_World, NzMatrix4f::Identity()); NzRenderer::SetVertexBuffer(&m_spriteBuffer); @@ -207,6 +209,8 @@ void NzDepthRenderTechnique::DrawBasicSprites(const NzSceneData& sceneData) cons void NzDepthRenderTechnique::DrawBillboards(const NzSceneData& sceneData) const { + NazaraUnused(sceneData); + if (NzRenderer::HasCapability(nzRendererCap_Instancing)) { NzVertexBuffer* instanceBuffer = NzRenderer::GetInstanceBuffer(); @@ -306,6 +310,8 @@ void NzDepthRenderTechnique::DrawBillboards(const NzSceneData& sceneData) const void NzDepthRenderTechnique::DrawOpaqueModels(const NzSceneData& sceneData) const { + NazaraUnused(sceneData); + s_material->Apply(); for (auto& meshIt : m_renderQueue.meshes) From bdb6554bc8cd24cebfdc586b25d72523002087d1 Mon Sep 17 00:00:00 2001 From: Lynix Date: Tue, 30 Jun 2015 20:47:08 +0200 Subject: [PATCH 17/37] Graphics/DepthRenderQueue: Make use of shadow casting parameter Former-commit-id: cf15775c67a5d4245d344d001847b9fb1ffe7432 --- src/Nazara/Graphics/DepthRenderQueue.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Nazara/Graphics/DepthRenderQueue.cpp b/src/Nazara/Graphics/DepthRenderQueue.cpp index e038c3bbd..9b5a2c170 100644 --- a/src/Nazara/Graphics/DepthRenderQueue.cpp +++ b/src/Nazara/Graphics/DepthRenderQueue.cpp @@ -350,7 +350,7 @@ bool NzDepthRenderQueue::IsMaterialSuitable(const NzMaterial* material) const { NazaraAssert(material, "Invalid material"); - return material->IsEnabled(nzRendererParameter_DepthBuffer) && material->IsEnabled(nzRendererParameter_DepthWrite); + return material->IsEnabled(nzRendererParameter_DepthBuffer) && material->IsEnabled(nzRendererParameter_DepthWrite) && material->IsShadowCastingEnabled(); } void NzDepthRenderQueue::OnIndexBufferInvalidation(const NzIndexBuffer* indexBuffer) From 2c4a35b2d1d1ec6ebd94803c59ed1fa8530bc865 Mon Sep 17 00:00:00 2001 From: Lynix Date: Tue, 30 Jun 2015 20:47:39 +0200 Subject: [PATCH 18/37] Graphics/Light: Add move constructor/operator Former-commit-id: d2823b5bae913fc0d218f6aaf067ee29812a6cbf --- include/Nazara/Graphics/Light.hpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/Nazara/Graphics/Light.hpp b/include/Nazara/Graphics/Light.hpp index a28a86c17..a473b031d 100644 --- a/include/Nazara/Graphics/Light.hpp +++ b/include/Nazara/Graphics/Light.hpp @@ -22,6 +22,7 @@ class NAZARA_GRAPHICS_API NzLight : public NzRenderable public: NzLight(nzLightType type = nzLightType_Point); inline NzLight(const NzLight& light); + NzLight(NzLight&& light) = default; ~NzLight() = default; void AddToRenderQueue(NzAbstractRenderQueue* renderQueue, const NzMatrix4f& transformMatrix) const override; @@ -63,6 +64,7 @@ class NAZARA_GRAPHICS_API NzLight : public NzRenderable void UpdateBoundingVolume(const NzMatrix4f& transformMatrix) override; NzLight& operator=(const NzLight& light); + NzLight& operator=(NzLight&& light) = default; private: void MakeBoundingVolume() const override; From 529673ebc1b7215db2b016131e226d2890c0d501 Mon Sep 17 00:00:00 2001 From: Lynix Date: Tue, 30 Jun 2015 20:48:46 +0200 Subject: [PATCH 19/37] Graphics/Light: Make shadow map format/size parametrable Former-commit-id: 8151d71d58ab760584c0ace1e0686c44bab9d3b2 --- include/Nazara/Graphics/Light.hpp | 7 ++++++ include/Nazara/Graphics/Light.inl | 41 ++++++++++++++++++++++++++++++- src/Nazara/Graphics/Light.cpp | 4 ++- 3 files changed, 50 insertions(+), 2 deletions(-) diff --git a/include/Nazara/Graphics/Light.hpp b/include/Nazara/Graphics/Light.hpp index a473b031d..5d42c0961 100644 --- a/include/Nazara/Graphics/Light.hpp +++ b/include/Nazara/Graphics/Light.hpp @@ -49,6 +49,8 @@ class NAZARA_GRAPHICS_API NzLight : public NzRenderable inline float GetOuterAngleTangent() const; inline float GetRadius() const; inline NzTextureRef GetShadowMap() const; + inline nzPixelFormat GetShadowMapFormat() const; + inline const NzVector2ui& GetShadowMapSize() const; inline bool IsShadowCastingEnabled() const; @@ -60,6 +62,8 @@ class NAZARA_GRAPHICS_API NzLight : public NzRenderable inline void SetLightType(nzLightType type); inline void SetOuterAngle(float outerAngle); inline void SetRadius(float radius); + inline void SetShadowMapFormat(nzPixelFormat shadowFormat); + inline void SetShadowMapSize(const NzVector2ui& size); void UpdateBoundingVolume(const NzMatrix4f& transformMatrix) override; @@ -68,10 +72,13 @@ class NAZARA_GRAPHICS_API NzLight : public NzRenderable private: void MakeBoundingVolume() const override; + inline void InvalidateShadowMap(); void UpdateShadowMap() const; nzLightType m_type; + nzPixelFormat m_shadowMapFormat; NzColor m_color; + NzVector2ui m_shadowMapSize; mutable NzTextureRef m_shadowMap; bool m_shadowCastingEnabled; mutable bool m_shadowMapUpdated; diff --git a/include/Nazara/Graphics/Light.inl b/include/Nazara/Graphics/Light.inl index f0f7600ff..b5408ce43 100644 --- a/include/Nazara/Graphics/Light.inl +++ b/include/Nazara/Graphics/Light.inl @@ -8,7 +8,9 @@ inline NzLight::NzLight(const NzLight& light) : NzRenderable(light), m_type(light.m_type), +m_shadowMapFormat(light.m_shadowMapFormat), m_color(light.m_color), +m_shadowMapSize(light.m_shadowMapSize), m_shadowCastingEnabled(light.m_shadowCastingEnabled), m_shadowMapUpdated(false), m_ambientFactor(light.m_ambientFactor), @@ -96,6 +98,16 @@ inline NzTextureRef NzLight::GetShadowMap() const return m_shadowMap; } +inline nzPixelFormat NzLight::GetShadowMapFormat() const +{ + return m_shadowMapFormat; +} + +inline const NzVector2ui& NzLight::GetShadowMapSize() const +{ + return m_shadowMapSize; +} + inline bool NzLight::IsShadowCastingEnabled() const { return m_shadowCastingEnabled; @@ -130,6 +142,8 @@ inline void NzLight::SetInnerAngle(float innerAngle) inline void NzLight::SetLightType(nzLightType type) { m_type = type; + + InvalidateShadowMap(); } inline void NzLight::SetOuterAngle(float outerAngle) @@ -150,6 +164,24 @@ inline void NzLight::SetRadius(float radius) InvalidateBoundingVolume(); } +inline void NzLight::SetShadowMapFormat(nzPixelFormat shadowFormat) +{ + NazaraAssert(NzPixelFormat::GetType(shadowFormat) == nzPixelFormatType_Depth, "Shadow format type is not a depth format"); + + m_shadowMapFormat = shadowFormat; + + InvalidateShadowMap(); +} + +inline void NzLight::SetShadowMapSize(const NzVector2ui& size) +{ + NazaraAssert(size.x > 0 && size.y > 0, "Shadow map size must have a positive size"); + + m_shadowMapSize = size; + + InvalidateShadowMap(); +} + inline NzLight& NzLight::operator=(const NzLight& light) { NzRenderable::operator=(light); @@ -166,10 +198,17 @@ inline NzLight& NzLight::operator=(const NzLight& light) m_outerAngleTangent = light.m_outerAngleTangent; m_radius = light.m_radius; m_shadowCastingEnabled = light.m_shadowCastingEnabled; - m_shadowMapUpdated = false; + m_shadowMapFormat = light.m_shadowMapFormat; + m_shadowMapSize = light.m_shadowMapSize; m_type = light.m_type; + InvalidateShadowMap(); return *this; } +inline void NzLight::InvalidateShadowMap() +{ + m_shadowMapUpdated = false; +} + #include diff --git a/src/Nazara/Graphics/Light.cpp b/src/Nazara/Graphics/Light.cpp index ee0e233ca..be93fd055 100644 --- a/src/Nazara/Graphics/Light.cpp +++ b/src/Nazara/Graphics/Light.cpp @@ -17,6 +17,8 @@ NzLight::NzLight(nzLightType type) : m_type(type), +m_shadowMapFormat(nzPixelFormat_Depth16), +m_shadowMapSize(512, 512), m_shadowCastingEnabled(false), m_shadowMapUpdated(false) { @@ -186,7 +188,7 @@ void NzLight::UpdateShadowMap() const if (!m_shadowMap) m_shadowMap = NzTexture::New(); - m_shadowMap->Create(nzImageType_2D, nzPixelFormat_Depth16, 256, 256); + m_shadowMap->Create((m_type == nzLightType_Point) ? nzImageType_Cubemap : nzImageType_2D, m_shadowMapFormat, m_shadowMapSize.x, m_shadowMapSize.y); } else m_shadowMap.Reset(); From 9a7c356f75b7c00c1b9cd576082b7a2b2c22d143 Mon Sep 17 00:00:00 2001 From: Lynix Date: Thu, 2 Jul 2015 12:24:04 +0200 Subject: [PATCH 20/37] Graphics/Material: Fix texture getters Former-commit-id: 00799529501c489498c4afd7e42195157b74ba22 --- include/Nazara/Graphics/Material.hpp | 12 ++++++------ include/Nazara/Graphics/Material.inl | 12 ++++++------ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/include/Nazara/Graphics/Material.hpp b/include/Nazara/Graphics/Material.hpp index 2d09c2f35..e199d2439 100644 --- a/include/Nazara/Graphics/Material.hpp +++ b/include/Nazara/Graphics/Material.hpp @@ -67,26 +67,26 @@ class NAZARA_GRAPHICS_API NzMaterial : public NzRefCounted, public NzResource inline void EnableShadowReceive(bool receiveShadows); inline void EnableTransform(bool transform); - inline NzTexture* GetAlphaMap() const; + inline const NzTextureRef& GetAlphaMap() const; inline float GetAlphaThreshold() const; inline NzColor GetAmbientColor() const; inline nzRendererComparison GetDepthFunc() const; inline NzColor GetDiffuseColor() const; - inline NzTexture* GetDiffuseMap() const; + inline const NzTextureRef& GetDiffuseMap() const; inline NzTextureSampler& GetDiffuseSampler(); inline const NzTextureSampler& GetDiffuseSampler() const; inline nzBlendFunc GetDstBlend() const; - inline NzTexture* GetEmissiveMap() const; + inline const NzTextureRef& GetEmissiveMap() const; inline nzFaceSide GetFaceCulling() const; inline nzFaceFilling GetFaceFilling() const; - inline NzTexture* GetHeightMap() const; - inline NzTexture* GetNormalMap() const; + inline const NzTextureRef& GetHeightMap() const; + inline const NzTextureRef& GetNormalMap() const; inline const NzRenderStates& GetRenderStates() const; inline const NzUberShader* GetShader() const; inline const NzUberShaderInstance* GetShaderInstance(nzUInt32 flags = nzShaderFlags_None) const; inline float GetShininess() const; inline NzColor GetSpecularColor() const; - inline NzTexture* GetSpecularMap() const; + inline const NzTextureRef& GetSpecularMap() const; inline NzTextureSampler& GetSpecularSampler(); inline const NzTextureSampler& GetSpecularSampler() const; inline nzBlendFunc GetSrcBlend() const; diff --git a/include/Nazara/Graphics/Material.inl b/include/Nazara/Graphics/Material.inl index 23a9433f5..9fb3851de 100644 --- a/include/Nazara/Graphics/Material.inl +++ b/include/Nazara/Graphics/Material.inl @@ -69,7 +69,7 @@ inline void NzMaterial::EnableTransform(bool transform) InvalidateShaders(); } -inline NzTexture* NzMaterial::GetAlphaMap() const +inline const NzTextureRef& NzMaterial::GetAlphaMap() const { return m_alphaMap; } @@ -104,7 +104,7 @@ inline const NzTextureSampler& NzMaterial::GetDiffuseSampler() const return m_diffuseSampler; } -NzTexture* NzMaterial::GetDiffuseMap() const +const NzTextureRef& NzMaterial::GetDiffuseMap() const { return m_diffuseMap; } @@ -114,7 +114,7 @@ inline nzBlendFunc NzMaterial::GetDstBlend() const return m_states.dstBlend; } -inline NzTexture* NzMaterial::GetEmissiveMap() const +inline const NzTextureRef& NzMaterial::GetEmissiveMap() const { return m_emissiveMap; } @@ -129,12 +129,12 @@ inline nzFaceFilling NzMaterial::GetFaceFilling() const return m_states.faceFilling; } -inline NzTexture* NzMaterial::GetHeightMap() const +inline const NzTextureRef& NzMaterial::GetHeightMap() const { return m_heightMap; } -inline NzTexture* NzMaterial::GetNormalMap() const +inline const NzTextureRef& NzMaterial::GetNormalMap() const { return m_normalMap; } @@ -168,7 +168,7 @@ inline NzColor NzMaterial::GetSpecularColor() const return m_specularColor; } -inline NzTexture* NzMaterial::GetSpecularMap() const +inline const NzTextureRef& NzMaterial::GetSpecularMap() const { return m_specularMap; } From 1398ed7ebc4c0f6a7b44b7e924587efb6fa0d441 Mon Sep 17 00:00:00 2001 From: Lynix Date: Thu, 2 Jul 2015 13:01:23 +0200 Subject: [PATCH 21/37] Core/ObjectRef: Remove static_assert Former-commit-id: 5050ce7a786053725d7e18fcc943bfb2ce3fee69 --- include/Nazara/Core/ObjectRef.hpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/include/Nazara/Core/ObjectRef.hpp b/include/Nazara/Core/ObjectRef.hpp index 35d016f90..7137eb7ee 100644 --- a/include/Nazara/Core/ObjectRef.hpp +++ b/include/Nazara/Core/ObjectRef.hpp @@ -14,8 +14,6 @@ template class NzObjectRef { - static_assert(std::is_base_of::value, "ObjectRef shall only be used with RefCounted-derived type"); - public: NzObjectRef(); NzObjectRef(T* object); From c0ee9d04b5f9ca2763022c24797ad3c5090599d9 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 5 Jul 2015 23:23:17 +0200 Subject: [PATCH 22/37] Graphics/Material: Add depth material parameter Former-commit-id: 980888e12e5d8c8cf280c6a62592068cfab49d2e --- include/Nazara/Graphics/Material.hpp | 4 ++++ include/Nazara/Graphics/Material.inl | 15 +++++++++++++++ src/Nazara/Graphics/Material.cpp | 20 ++++++++++---------- 3 files changed, 29 insertions(+), 10 deletions(-) diff --git a/include/Nazara/Graphics/Material.hpp b/include/Nazara/Graphics/Material.hpp index e199d2439..bdd6e8fcc 100644 --- a/include/Nazara/Graphics/Material.hpp +++ b/include/Nazara/Graphics/Material.hpp @@ -71,6 +71,7 @@ class NAZARA_GRAPHICS_API NzMaterial : public NzRefCounted, public NzResource inline float GetAlphaThreshold() const; inline NzColor GetAmbientColor() const; inline nzRendererComparison GetDepthFunc() const; + inline const NzMaterialRef& GetDepthMaterial() const; inline NzColor GetDiffuseColor() const; inline const NzTextureRef& GetDiffuseMap() const; inline NzTextureSampler& GetDiffuseSampler(); @@ -92,6 +93,7 @@ class NAZARA_GRAPHICS_API NzMaterial : public NzRefCounted, public NzResource inline nzBlendFunc GetSrcBlend() const; inline bool HasAlphaMap() const; + inline bool HasDepthMaterial() const; inline bool HasDiffuseMap() const; inline bool HasEmissiveMap() const; inline bool HasHeightMap() const; @@ -117,6 +119,7 @@ class NAZARA_GRAPHICS_API NzMaterial : public NzRefCounted, public NzResource inline void SetAlphaThreshold(float alphaThreshold); inline void SetAmbientColor(const NzColor& ambient); inline void SetDepthFunc(nzRendererComparison depthFunc); + inline void SetDepthMaterial(NzMaterialRef depthMaterial); inline void SetDiffuseColor(const NzColor& diffuse); inline bool SetDiffuseMap(const NzString& textureName); inline void SetDiffuseMap(NzTextureRef diffuseMap); @@ -167,6 +170,7 @@ class NAZARA_GRAPHICS_API NzMaterial : public NzRefCounted, public NzResource NzColor m_ambientColor; NzColor m_diffuseColor; NzColor m_specularColor; + NzMaterialRef m_depthMaterial; //< Materialception NzRenderStates m_states; NzTextureSampler m_diffuseSampler; NzTextureSampler m_specularSampler; diff --git a/include/Nazara/Graphics/Material.inl b/include/Nazara/Graphics/Material.inl index 9fb3851de..7bfb4d196 100644 --- a/include/Nazara/Graphics/Material.inl +++ b/include/Nazara/Graphics/Material.inl @@ -89,6 +89,11 @@ inline nzRendererComparison NzMaterial::GetDepthFunc() const return m_states.depthFunc; } +inline const NzMaterialRef& NzMaterial::GetDepthMaterial() const +{ + return m_depthMaterial; +} + inline NzColor NzMaterial::GetDiffuseColor() const { return m_diffuseColor; @@ -193,6 +198,11 @@ inline bool NzMaterial::HasAlphaMap() const return m_alphaMap.IsValid(); } +inline bool NzMaterial::HasDepthMaterial() const +{ + return m_depthMaterial.IsValid(); +} + inline bool NzMaterial::HasDiffuseMap() const { return m_diffuseMap.IsValid(); @@ -306,6 +316,11 @@ inline void NzMaterial::SetDepthFunc(nzRendererComparison depthFunc) m_states.depthFunc = depthFunc; } +inline void NzMaterial::SetDepthMaterial(NzMaterialRef depthMaterial) +{ + m_depthMaterial = std::move(depthMaterial); +} + inline void NzMaterial::SetDiffuseColor(const NzColor& diffuse) { m_diffuseColor = diffuse; diff --git a/src/Nazara/Graphics/Material.cpp b/src/Nazara/Graphics/Material.cpp index bc8b5a002..b4a64dc11 100644 --- a/src/Nazara/Graphics/Material.cpp +++ b/src/Nazara/Graphics/Material.cpp @@ -125,6 +125,7 @@ void NzMaterial::Reset() OnMaterialReset(this); m_alphaMap.Reset(); + m_depthMaterial.Reset(); m_diffuseMap.Reset(); m_emissiveMap.Reset(); m_heightMap.Reset(); @@ -173,16 +174,15 @@ void NzMaterial::Copy(const NzMaterial& material) m_states = material.m_states; m_transformEnabled = material.m_transformEnabled; - // Copie des références de texture - m_alphaMap = material.m_alphaMap; - m_diffuseMap = material.m_diffuseMap; - m_emissiveMap = material.m_emissiveMap; - m_heightMap = material.m_heightMap; - m_normalMap = material.m_normalMap; - m_specularMap = material.m_specularMap; - - // Copie de la référence vers l'Über-Shader - m_uberShader = material.m_uberShader; + // Copying resources refs + m_alphaMap = material.m_alphaMap; + m_depthMaterial = material.m_depthMaterial; + m_diffuseMap = material.m_diffuseMap; + m_emissiveMap = material.m_emissiveMap; + m_heightMap = material.m_heightMap; + m_normalMap = material.m_normalMap; + m_specularMap = material.m_specularMap; + m_uberShader = material.m_uberShader; // On copie les instances de shader par la même occasion std::memcpy(&m_shaders[0], &material.m_shaders[0], (nzShaderFlags_Max+1)*sizeof(ShaderInstance)); From 5556c3890102b03d3e9b4b61fc84d02beeb40cb2 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 5 Jul 2015 23:25:12 +0200 Subject: [PATCH 23/37] Renderer/RenderTexture: Fix Detach() not removing color targets Former-commit-id: 058d95e1952f2316333be380cb6418c121db4a32 --- src/Nazara/Renderer/RenderTexture.cpp | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/Nazara/Renderer/RenderTexture.cpp b/src/Nazara/Renderer/RenderTexture.cpp index b574de8d9..75d4de01d 100644 --- a/src/Nazara/Renderer/RenderTexture.cpp +++ b/src/Nazara/Renderer/RenderTexture.cpp @@ -154,9 +154,6 @@ bool NzRenderTexture::AttachBuffer(nzAttachmentPoint attachmentPoint, nzUInt8 in InvalidateSize(); InvalidateTargets(); - if (attachmentPoint == nzAttachmentPoint_Color && !m_impl->userDefinedTargets) - m_impl->colorTargets.push_back(index); - return true; } @@ -291,9 +288,6 @@ bool NzRenderTexture::AttachTexture(nzAttachmentPoint attachmentPoint, nzUInt8 i InvalidateSize(); InvalidateTargets(); - if (attachmentPoint == nzAttachmentPoint_Color && !m_impl->userDefinedTargets) - m_impl->colorTargets.push_back(index); - return true; } @@ -828,6 +822,15 @@ void NzRenderTexture::UpdateSize() const void NzRenderTexture::UpdateTargets() const { + if (!m_impl->userDefinedTargets) + { + m_impl->colorTargets.clear(); + + unsigned int colorIndex = 0; + for (unsigned int index = attachmentIndex[nzAttachmentPoint_Color]; index < m_impl->attachments.size(); ++index) + m_impl->colorTargets.push_back(colorIndex++); + } + if (m_impl->colorTargets.empty()) { m_impl->drawBuffers.resize(1); From 68701483148bf855640d39a1ccee6566f8fcf8c4 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 5 Jul 2015 23:26:09 +0200 Subject: [PATCH 24/37] Renderer: Add shader validation Former-commit-id: fa9225b87e6ec2217c3838535531075dfcaaf433 --- include/Nazara/Renderer/OpenGL.hpp | 1 + include/Nazara/Renderer/Shader.hpp | 2 ++ src/Nazara/Renderer/OpenGL.cpp | 2 ++ src/Nazara/Renderer/Renderer.cpp | 8 ++++++++ src/Nazara/Renderer/Shader.cpp | 24 ++++++++++++++++++++++++ 5 files changed, 37 insertions(+) diff --git a/include/Nazara/Renderer/OpenGL.hpp b/include/Nazara/Renderer/OpenGL.hpp index 021252677..64578dae8 100644 --- a/include/Nazara/Renderer/OpenGL.hpp +++ b/include/Nazara/Renderer/OpenGL.hpp @@ -318,6 +318,7 @@ NAZARA_RENDERER_API extern PFNGLUNIFORMMATRIX4DVPROC glUniformMatrix4dv; NAZARA_RENDERER_API extern PFNGLUNIFORMMATRIX4FVPROC glUniformMatrix4fv; NAZARA_RENDERER_API extern PFNGLUNMAPBUFFERPROC glUnmapBuffer; NAZARA_RENDERER_API extern PFNGLUSEPROGRAMPROC glUseProgram; +NAZARA_RENDERER_API extern PFNGLVALIDATEPROGRAMPROC glValidateProgram; NAZARA_RENDERER_API extern PFNGLVERTEXATTRIB4FPROC glVertexAttrib4f; NAZARA_RENDERER_API extern PFNGLVERTEXATTRIBDIVISORPROC glVertexAttribDivisor; NAZARA_RENDERER_API extern PFNGLVERTEXATTRIBPOINTERPROC glVertexAttribPointer; diff --git a/include/Nazara/Renderer/Shader.hpp b/include/Nazara/Renderer/Shader.hpp index 951f01a51..3057943ac 100644 --- a/include/Nazara/Renderer/Shader.hpp +++ b/include/Nazara/Renderer/Shader.hpp @@ -95,6 +95,8 @@ class NAZARA_RENDERER_API NzShader : public NzRefCounted, NzNonCopyable void SendVectorArray(int location, const NzVector4f* vectors, unsigned int count) const; void SendVectorArray(int location, const NzVector4i* vectors, unsigned int count) const; + bool Validate() const; + // Fonctions OpenGL unsigned int GetOpenGLID() const; diff --git a/src/Nazara/Renderer/OpenGL.cpp b/src/Nazara/Renderer/OpenGL.cpp index 5331e902c..cd13021e2 100644 --- a/src/Nazara/Renderer/OpenGL.cpp +++ b/src/Nazara/Renderer/OpenGL.cpp @@ -945,6 +945,7 @@ bool NzOpenGL::Initialize() glUniformMatrix4fv = reinterpret_cast(LoadEntry("glUniformMatrix4fv")); glUnmapBuffer = reinterpret_cast(LoadEntry("glUnmapBuffer")); glUseProgram = reinterpret_cast(LoadEntry("glUseProgram")); + glValidateProgram = reinterpret_cast(LoadEntry("glValidateProgram")); glVertexAttrib4f = reinterpret_cast(LoadEntry("glVertexAttrib4f")); glVertexAttribPointer = reinterpret_cast(LoadEntry("glVertexAttribPointer")); glViewport = reinterpret_cast(LoadEntry("glViewport")); @@ -2384,6 +2385,7 @@ PFNGLUNIFORMMATRIX4DVPROC glUniformMatrix4dv = nullptr; PFNGLUNIFORMMATRIX4FVPROC glUniformMatrix4fv = nullptr; PFNGLUNMAPBUFFERPROC glUnmapBuffer = nullptr; PFNGLUSEPROGRAMPROC glUseProgram = nullptr; +PFNGLVALIDATEPROGRAMPROC glValidateProgram = nullptr; PFNGLVERTEXATTRIB4FPROC glVertexAttrib4f = nullptr; PFNGLVERTEXATTRIBDIVISORPROC glVertexAttribDivisor = nullptr; PFNGLVERTEXATTRIBPOINTERPROC glVertexAttribPointer = nullptr; diff --git a/src/Nazara/Renderer/Renderer.cpp b/src/Nazara/Renderer/Renderer.cpp index ab252a1f1..e9f5d4c60 100644 --- a/src/Nazara/Renderer/Renderer.cpp +++ b/src/Nazara/Renderer/Renderer.cpp @@ -1857,6 +1857,14 @@ bool NzRenderer::EnsureStateUpdate() // Et on termine par envoyer nos états au driver NzOpenGL::ApplyStates(s_states); + #ifdef NAZARA_DEBUG + if (!s_shader->Validate()) + { + NazaraError(NzError::GetLastError()); + return false; + } + #endif + return true; } diff --git a/src/Nazara/Renderer/Shader.cpp b/src/Nazara/Renderer/Shader.cpp index 1b45b9789..91dea1192 100644 --- a/src/Nazara/Renderer/Shader.cpp +++ b/src/Nazara/Renderer/Shader.cpp @@ -748,6 +748,30 @@ void NzShader::SendVectorArray(int location, const NzVector4i* vectors, unsigned } } +bool NzShader::Validate() const +{ + #if NAZARA_RENDERER_SAFE + if (!m_program) + { + NazaraError("Shader is not initialized"); + return false; + } + #endif + + glValidateProgram(m_program); + + GLint success; + glGetProgramiv(m_program, GL_VALIDATE_STATUS, &success); + + if (success == GL_TRUE) + return true; + else + { + NazaraError("Failed to validate shader: " + GetLog()); + return false; + } +} + unsigned int NzShader::GetOpenGLID() const { return m_program; From 1f2e81092741091a72df8bc7bdfabf7f99695133 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 5 Jul 2015 23:43:35 +0200 Subject: [PATCH 25/37] Graphics: Remake DepthRender[Queue|Technique] Former-commit-id: c4d8d4d28d02822273ebe7dca3e468ea156af674 --- include/Nazara/Graphics/DepthRenderQueue.hpp | 40 +- .../Nazara/Graphics/DepthRenderTechnique.hpp | 34 +- src/Nazara/Graphics/DepthRenderQueue.cpp | 332 ++++---------- src/Nazara/Graphics/DepthRenderTechnique.cpp | 409 ++++++++++++------ 4 files changed, 387 insertions(+), 428 deletions(-) diff --git a/include/Nazara/Graphics/DepthRenderQueue.hpp b/include/Nazara/Graphics/DepthRenderQueue.hpp index ec6550494..ed96b7d6b 100644 --- a/include/Nazara/Graphics/DepthRenderQueue.hpp +++ b/include/Nazara/Graphics/DepthRenderQueue.hpp @@ -18,10 +18,10 @@ #include #include -class NAZARA_GRAPHICS_API NzDepthRenderQueue : public NzAbstractRenderQueue +class NAZARA_GRAPHICS_API NzDepthRenderQueue : public NzForwardRenderQueue { public: - NzDepthRenderQueue() = default; + NzDepthRenderQueue(); ~NzDepthRenderQueue() = default; void AddBillboard(const NzMaterial* material, const NzVector3f& position, const NzVector2f& size, const NzVector2f& sinCos = NzVector2f(0.f, 1.f), const NzColor& color = NzColor::White) override; @@ -33,44 +33,16 @@ class NAZARA_GRAPHICS_API NzDepthRenderQueue : public NzAbstractRenderQueue void AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr sinCosPtr, NzSparsePtr alphaPtr) override; void AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr anglePtr, NzSparsePtr colorPtr = nullptr) override; void AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr anglePtr, NzSparsePtr alphaPtr) override; - void AddDrawable(const NzDrawable* drawable) override; + void AddDirectionalLight(const DirectionalLight& light) override; void AddMesh(const NzMaterial* material, const NzMeshData& meshData, const NzBoxf& meshAABB, const NzMatrix4f& transformMatrix) override; + void AddPointLight(const PointLight& light) override; + void AddSpotLight(const SpotLight& light) override; void AddSprites(const NzMaterial* material, const NzVertexStruct_XYZ_Color_UV* vertices, unsigned int spriteCount, const NzTexture* overlay = nullptr) override; - void Clear(bool fully = false); - - struct BillboardData - { - NzColor color; - NzVector3f center; - NzVector2f size; - NzVector2f sinCos; - }; - - struct MeshInstanceEntry - { - NazaraSlot(NzIndexBuffer, OnIndexBufferRelease, indexBufferReleaseSlot); - NazaraSlot(NzVertexBuffer, OnVertexBufferRelease, vertexBufferReleaseSlot); - - std::vector instances; - }; - - struct SpriteChain_XYZ_Color_UV - { - const NzVertexStruct_XYZ_Color_UV* vertices; - unsigned int spriteCount; - }; - - std::map meshes; - std::vector billboards; - std::vector otherDrawables; - std::vector basicSprites; - private: bool IsMaterialSuitable(const NzMaterial* material) const; - void OnIndexBufferInvalidation(const NzIndexBuffer* indexBuffer); - void OnVertexBufferInvalidation(const NzVertexBuffer* vertexBuffer); + NzMaterialRef m_baseMaterial; }; #endif // NAZARA_DEPTHRENDERQUEUE_HPP diff --git a/include/Nazara/Graphics/DepthRenderTechnique.hpp b/include/Nazara/Graphics/DepthRenderTechnique.hpp index b33a2b6cc..9da641c3b 100644 --- a/include/Nazara/Graphics/DepthRenderTechnique.hpp +++ b/include/Nazara/Graphics/DepthRenderTechnique.hpp @@ -12,7 +12,6 @@ #include #include #include -#include #include #include #include @@ -32,22 +31,51 @@ class NAZARA_GRAPHICS_API NzDepthRenderTechnique : public NzAbstractRenderTechni static void Uninitialize(); private: + struct ShaderUniforms; + void DrawBasicSprites(const NzSceneData& sceneData) const; void DrawBillboards(const NzSceneData& sceneData) const; void DrawOpaqueModels(const NzSceneData& sceneData) const; + const ShaderUniforms* GetShaderUniforms(const NzShader* shader) const; + void OnShaderInvalidated(const NzShader* shader) const; + struct LightIndex + { + nzLightType type; + float score; + unsigned int index; + }; + + struct ShaderUniforms + { + NazaraSlot(NzShader, OnShaderUniformInvalidated, shaderUniformInvalidatedSlot); + NazaraSlot(NzShader, OnShaderRelease, shaderReleaseSlot); + + NzLightUniforms lightUniforms; + bool hasLightUniforms; + + /// Moins coûteux en mémoire que de stocker un NzLightUniforms par index de lumière, + /// à voir si ça fonctionne chez tout le monde + int lightOffset; // "Distance" entre Lights[0].type et Lights[1].type + + // Autre uniformes + int eyePosition; + int sceneAmbient; + int textureOverlay; + }; + + mutable std::unordered_map m_shaderUniforms; NzBuffer m_vertexBuffer; mutable NzDepthRenderQueue m_renderQueue; NzVertexBuffer m_billboardPointBuffer; NzVertexBuffer m_spriteBuffer; static NzIndexBuffer s_quadIndexBuffer; - static NzMaterialRef s_material; static NzVertexBuffer s_quadVertexBuffer; static NzVertexDeclaration s_billboardInstanceDeclaration; static NzVertexDeclaration s_billboardVertexDeclaration; }; -#include +#include #endif // NAZARA_DEPTHRENDERTECHNIQUE_HPP diff --git a/src/Nazara/Graphics/DepthRenderQueue.cpp b/src/Nazara/Graphics/DepthRenderQueue.cpp index 9b5a2c170..9ff02dcbd 100644 --- a/src/Nazara/Graphics/DepthRenderQueue.cpp +++ b/src/Nazara/Graphics/DepthRenderQueue.cpp @@ -7,76 +7,58 @@ #include #include -///TODO: Remplacer les sinus/cosinus par une lookup table (va booster les perfs d'un bon x10) +NzDepthRenderQueue::NzDepthRenderQueue() +{ + // Material + m_baseMaterial = NzMaterial::New(); + m_baseMaterial->Enable(nzRendererParameter_ColorWrite, false); + m_baseMaterial->Enable(nzRendererParameter_FaceCulling, false); + //m_baseMaterial->SetFaceCulling(nzFaceSide_Front); +} void NzDepthRenderQueue::AddBillboard(const NzMaterial* material, const NzVector3f& position, const NzVector2f& size, const NzVector2f& sinCos, const NzColor& color) { NazaraAssert(material, "Invalid material"); - if (IsMaterialSuitable(material)) - billboards.push_back(BillboardData{color, position, size, sinCos}); + if (!IsMaterialSuitable(material)) + return; + + if (material->HasDepthMaterial()) + material = material->GetDepthMaterial(); + else + material = m_baseMaterial; + + NzForwardRenderQueue::AddBillboard(material, position, size, sinCos, color); } void NzDepthRenderQueue::AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr sinCosPtr, NzSparsePtr colorPtr) { - ///DOC: sinCosPtr et colorPtr peuvent être nuls, ils seront remplacés respectivement par Vector2f(0.f, 1.f) et Color::White NazaraAssert(material, "Invalid material"); if (!IsMaterialSuitable(material)) return; - NzVector2f defaultSinCos(0.f, 1.f); // sin(0) = 0, cos(0) = 1 + if (material->HasDepthMaterial()) + material = material->GetDepthMaterial(); + else + material = m_baseMaterial; - if (!sinCosPtr) - sinCosPtr.Reset(&defaultSinCos, 0); // L'astuce ici est de mettre le stride sur zéro, rendant le pointeur immobile - - if (!colorPtr) - colorPtr.Reset(&NzColor::White, 0); // Pareil - - unsigned int prevSize = billboards.size(); - billboards.resize(prevSize + count); - - BillboardData* billboardData = &billboards[prevSize]; - for (unsigned int i = 0; i < count; ++i) - { - billboardData->center = *positionPtr++; - billboardData->color = *colorPtr++; - billboardData->sinCos = *sinCosPtr++; - billboardData->size = *sizePtr++; - billboardData++; - } + NzForwardRenderQueue::AddBillboards(material, count, positionPtr, sizePtr, sinCosPtr, colorPtr); } void NzDepthRenderQueue::AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr sinCosPtr, NzSparsePtr alphaPtr) { - ///DOC: sinCosPtr et alphaPtr peuvent être nuls, ils seront remplacés respectivement par Vector2f(0.f, 1.f) et Color::White NazaraAssert(material, "Invalid material"); if (!IsMaterialSuitable(material)) return; - NzVector2f defaultSinCos(0.f, 1.f); // sin(0) = 0, cos(0) = 1 + if (material->HasDepthMaterial()) + material = material->GetDepthMaterial(); + else + material = m_baseMaterial; - if (!sinCosPtr) - sinCosPtr.Reset(&defaultSinCos, 0); // L'astuce ici est de mettre le stride sur zéro, rendant le pointeur immobile - - float defaultAlpha = 1.f; - - if (!alphaPtr) - alphaPtr.Reset(&defaultAlpha, 0); // Pareil - - unsigned int prevSize = billboards.size(); - billboards.resize(prevSize + count); - - BillboardData* billboardData = &billboards[prevSize]; - for (unsigned int i = 0; i < count; ++i) - { - billboardData->center = *positionPtr++; - billboardData->color = NzColor(255, 255, 255, static_cast(255.f * (*alphaPtr++))); - billboardData->sinCos = *sinCosPtr++; - billboardData->size = *sizePtr++; - billboardData++; - } + NzForwardRenderQueue::AddBillboards(material, count, positionPtr, sizePtr, sinCosPtr, alphaPtr); } void NzDepthRenderQueue::AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr anglePtr, NzSparsePtr colorPtr) @@ -86,129 +68,57 @@ void NzDepthRenderQueue::AddBillboards(const NzMaterial* material, unsigned int if (!IsMaterialSuitable(material)) return; - ///DOC: sinCosPtr et colorPtr peuvent être nuls, ils seront remplacés respectivement par Vector2f(0.f, 1.f) et Color::White - float defaultRotation = 0.f; + if (material->HasDepthMaterial()) + material = material->GetDepthMaterial(); + else + material = m_baseMaterial; - if (!anglePtr) - anglePtr.Reset(&defaultRotation, 0); // L'astuce ici est de mettre le stride sur zéro, rendant le pointeur immobile - - if (!colorPtr) - colorPtr.Reset(&NzColor::White, 0); // Pareil - - unsigned int prevSize = billboards.size(); - billboards.resize(prevSize + count); - - BillboardData* billboardData = &billboards[prevSize]; - for (unsigned int i = 0; i < count; ++i) - { - float sin = std::sin(NzToRadians(*anglePtr)); - float cos = std::cos(NzToRadians(*anglePtr)); - anglePtr++; - - billboardData->center = *positionPtr++; - billboardData->color = *colorPtr++; - billboardData->sinCos.Set(sin, cos); - billboardData->size = *sizePtr++; - billboardData++; - } + NzForwardRenderQueue::AddBillboards(material, count, positionPtr, sizePtr, anglePtr, colorPtr); } void NzDepthRenderQueue::AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr anglePtr, NzSparsePtr alphaPtr) { - ///DOC: sinCosPtr et alphaPtr peuvent être nuls, ils seront remplacés respectivement par Vector2f(0.f, 1.f) et Color::White NazaraAssert(material, "Invalid material"); if (!IsMaterialSuitable(material)) return; - float defaultRotation = 0.f; + if (material->HasDepthMaterial()) + material = material->GetDepthMaterial(); + else + material = m_baseMaterial; - if (!anglePtr) - anglePtr.Reset(&defaultRotation, 0); // L'astuce ici est de mettre le stride sur zéro, rendant le pointeur immobile - - float defaultAlpha = 1.f; - - if (!alphaPtr) - alphaPtr.Reset(&defaultAlpha, 0); // Pareil - - unsigned int prevSize = billboards.size(); - billboards.resize(prevSize + count); - - BillboardData* billboardData = &billboards[prevSize]; - for (unsigned int i = 0; i < count; ++i) - { - float sin = std::sin(NzToRadians(*anglePtr)); - float cos = std::cos(NzToRadians(*anglePtr)); - anglePtr++; - - billboardData->center = *positionPtr++; - billboardData->color = NzColor(255, 255, 255, static_cast(255.f * (*alphaPtr++))); - billboardData->sinCos.Set(sin, cos); - billboardData->size = *sizePtr++; - billboardData++; - } + NzForwardRenderQueue::AddBillboards(material, count, positionPtr, sizePtr, anglePtr, alphaPtr); } void NzDepthRenderQueue::AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr sinCosPtr, NzSparsePtr colorPtr) { - ///DOC: sinCosPtr et colorPtr peuvent être nuls, ils seront remplacés respectivement par Vector2f(0.f, 1.f) et Color::White NazaraAssert(material, "Invalid material"); if (!IsMaterialSuitable(material)) return; - NzVector2f defaultSinCos(0.f, 1.f); // sin(0) = 0, cos(0) = 1 + if (material->HasDepthMaterial()) + material = material->GetDepthMaterial(); + else + material = m_baseMaterial; - if (!sinCosPtr) - sinCosPtr.Reset(&defaultSinCos, 0); // L'astuce ici est de mettre le stride sur zéro, rendant le pointeur immobile - - if (!colorPtr) - colorPtr.Reset(&NzColor::White, 0); // Pareil - - unsigned int prevSize = billboards.size(); - billboards.resize(prevSize + count); - - BillboardData* billboardData = &billboards[prevSize]; - for (unsigned int i = 0; i < count; ++i) - { - billboardData->center = *positionPtr++; - billboardData->color = *colorPtr++; - billboardData->sinCos = *sinCosPtr++; - billboardData->size.Set(*sizePtr++); - billboardData++; - } + NzForwardRenderQueue::AddBillboards(material, count, positionPtr, sizePtr, sinCosPtr, colorPtr); } void NzDepthRenderQueue::AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr sinCosPtr, NzSparsePtr alphaPtr) { - ///DOC: sinCosPtr et alphaPtr peuvent être nuls, ils seront remplacés respectivement par Vector2f(0.f, 1.f) et Color::White NazaraAssert(material, "Invalid material"); if (!IsMaterialSuitable(material)) return; - NzVector2f defaultSinCos(0.f, 1.f); // sin(0) = 0, cos(0) = 1 + if (material->HasDepthMaterial()) + material = material->GetDepthMaterial(); + else + material = m_baseMaterial; - if (!sinCosPtr) - sinCosPtr.Reset(&defaultSinCos, 0); // L'astuce ici est de mettre le stride sur zéro, rendant le pointeur immobile - - float defaultAlpha = 1.f; - - if (!alphaPtr) - alphaPtr.Reset(&defaultAlpha, 0); // Pareil - - unsigned int prevSize = billboards.size(); - billboards.resize(prevSize + count); - - BillboardData* billboardData = &billboards[prevSize]; - for (unsigned int i = 0; i < count; ++i) - { - billboardData->center = *positionPtr++; - billboardData->color = NzColor(255, 255, 255, static_cast(255.f * (*alphaPtr++))); - billboardData->sinCos = *sinCosPtr++; - billboardData->size.Set(*sizePtr++); - billboardData++; - } + NzForwardRenderQueue::AddBillboards(material, count, positionPtr, sizePtr, sinCosPtr, alphaPtr); } void NzDepthRenderQueue::AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr anglePtr, NzSparsePtr colorPtr) @@ -218,80 +128,33 @@ void NzDepthRenderQueue::AddBillboards(const NzMaterial* material, unsigned int if (!IsMaterialSuitable(material)) return; - ///DOC: sinCosPtr et colorPtr peuvent être nuls, ils seront remplacés respectivement par Vector2f(0.f, 1.f) et Color::White - float defaultRotation = 0.f; + if (material->HasDepthMaterial()) + material = material->GetDepthMaterial(); + else + material = m_baseMaterial; - if (!anglePtr) - anglePtr.Reset(&defaultRotation, 0); // L'astuce ici est de mettre le stride sur zéro, rendant le pointeur immobile - - if (!colorPtr) - colorPtr.Reset(&NzColor::White, 0); // Pareil - - unsigned int prevSize = billboards.size(); - billboards.resize(prevSize + count); - - BillboardData* billboardData = &billboards[prevSize]; - for (unsigned int i = 0; i < count; ++i) - { - float sin = std::sin(NzToRadians(*anglePtr)); - float cos = std::cos(NzToRadians(*anglePtr)); - anglePtr++; - - billboardData->center = *positionPtr++; - billboardData->color = *colorPtr++; - billboardData->sinCos.Set(sin, cos); - billboardData->size.Set(*sizePtr++); - billboardData++; - } + NzForwardRenderQueue::AddBillboards(material, count, positionPtr, sizePtr, anglePtr, colorPtr); } void NzDepthRenderQueue::AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr anglePtr, NzSparsePtr alphaPtr) { - ///DOC: sinCosPtr et alphaPtr peuvent être nuls, ils seront remplacés respectivement par Vector2f(0.f, 1.f) et Color::White NazaraAssert(material, "Invalid material"); if (!IsMaterialSuitable(material)) return; - float defaultRotation = 0.f; + if (material->HasDepthMaterial()) + material = material->GetDepthMaterial(); + else + material = m_baseMaterial; - if (!anglePtr) - anglePtr.Reset(&defaultRotation, 0); // L'astuce ici est de mettre le stride sur zéro, rendant le pointeur immobile - - float defaultAlpha = 1.f; - - if (!alphaPtr) - alphaPtr.Reset(&defaultAlpha, 0); // Pareil - - unsigned int prevSize = billboards.size(); - billboards.resize(prevSize + count); - - BillboardData* billboardData = &billboards[prevSize]; - for (unsigned int i = 0; i < count; ++i) - { - float sin = std::sin(NzToRadians(*anglePtr)); - float cos = std::cos(NzToRadians(*anglePtr)); - anglePtr++; - - billboardData->center = *positionPtr++; - billboardData->color = NzColor(255, 255, 255, static_cast(255.f * (*alphaPtr++))); - billboardData->sinCos.Set(sin, cos); - billboardData->size.Set(*sizePtr++); - billboardData++; - } + NzForwardRenderQueue::AddBillboards(material, count, positionPtr, sizePtr, anglePtr, alphaPtr); } -void NzDepthRenderQueue::AddDrawable(const NzDrawable* drawable) +void NzDepthRenderQueue::AddDirectionalLight(const DirectionalLight& light) { - #if NAZARA_GRAPHICS_SAFE - if (!drawable) - { - NazaraError("Invalid drawable"); - return; - } - #endif - - otherDrawables.push_back(drawable); + NazaraAssert(false, "Depth render queue doesn't handle lights"); + NazaraUnused(light); } void NzDepthRenderQueue::AddMesh(const NzMaterial* material, const NzMeshData& meshData, const NzBoxf& meshAABB, const NzMatrix4f& transformMatrix) @@ -302,25 +165,24 @@ void NzDepthRenderQueue::AddMesh(const NzMaterial* material, const NzMeshData& m if (!IsMaterialSuitable(material)) return; - auto it = meshes.find(meshData); - if (it == meshes.end()) - { - MeshInstanceEntry instanceEntry; + if (material->HasDepthMaterial()) + material = material->GetDepthMaterial(); + else + material = m_baseMaterial; - if (meshData.indexBuffer) - instanceEntry.indexBufferReleaseSlot.Connect(meshData.indexBuffer->OnIndexBufferRelease, this, &NzDepthRenderQueue::OnIndexBufferInvalidation); + NzForwardRenderQueue::AddMesh(material, meshData, meshAABB, transformMatrix); +} - instanceEntry.vertexBufferReleaseSlot.Connect(meshData.vertexBuffer->OnVertexBufferRelease, this, &NzDepthRenderQueue::OnVertexBufferInvalidation); +void NzDepthRenderQueue::AddPointLight(const PointLight& light) +{ + NazaraAssert(false, "Depth render queue doesn't handle lights"); + NazaraUnused(light); +} - it = meshes.insert(std::make_pair(meshData, std::move(instanceEntry))).first; - } - - std::vector& instances = it->second.instances; - instances.push_back(transformMatrix); - - // Avons-nous suffisamment d'instances pour que le coût d'utilisation de l'instancing soit payé ? - //if (instances.size() >= NAZARA_GRAPHICS_INSTANCING_MIN_INSTANCES_COUNT) - // entry.instancingEnabled = true; // Apparemment oui, activons l'instancing avec ce matériau +void NzDepthRenderQueue::AddSpotLight(const SpotLight& light) +{ + NazaraAssert(false, "Depth render queue doesn't handle lights"); + NazaraUnused(light); } void NzDepthRenderQueue::AddSprites(const NzMaterial* material, const NzVertexStruct_XYZ_Color_UV* vertices, unsigned int spriteCount, const NzTexture* overlay) @@ -331,49 +193,17 @@ void NzDepthRenderQueue::AddSprites(const NzMaterial* material, const NzVertexSt if (!IsMaterialSuitable(material)) return; - basicSprites.push_back(SpriteChain_XYZ_Color_UV({vertices, spriteCount})); -} + if (material->HasDepthMaterial()) + material = material->GetDepthMaterial(); + else + material = m_baseMaterial; -void NzDepthRenderQueue::Clear(bool fully) -{ - NzAbstractRenderQueue::Clear(fully); - - basicSprites.clear(); - billboards.clear(); - otherDrawables.clear(); - - if (fully) - meshes.clear(); + NzForwardRenderQueue::AddSprites(material, vertices, spriteCount, overlay); } bool NzDepthRenderQueue::IsMaterialSuitable(const NzMaterial* material) const { NazaraAssert(material, "Invalid material"); - return material->IsEnabled(nzRendererParameter_DepthBuffer) && material->IsEnabled(nzRendererParameter_DepthWrite) && material->IsShadowCastingEnabled(); + return material->HasDepthMaterial() || (material->IsEnabled(nzRendererParameter_DepthBuffer) && material->IsEnabled(nzRendererParameter_DepthWrite) && material->IsShadowCastingEnabled()); } - -void NzDepthRenderQueue::OnIndexBufferInvalidation(const NzIndexBuffer* indexBuffer) -{ - for (auto it = meshes.begin(); it != meshes.end();) - { - const NzMeshData& renderData = it->first; - if (renderData.indexBuffer == indexBuffer) - it = meshes.erase(it); - else - ++it; - } -} - -void NzDepthRenderQueue::OnVertexBufferInvalidation(const NzVertexBuffer* vertexBuffer) -{ - for (auto it = meshes.begin(); it != meshes.end();) - { - const NzMeshData& renderData = it->first; - if (renderData.vertexBuffer == vertexBuffer) - it = meshes.erase(it); - else - ++it; - } -} - diff --git a/src/Nazara/Graphics/DepthRenderTechnique.cpp b/src/Nazara/Graphics/DepthRenderTechnique.cpp index 6ec9dfaf3..31d63d56a 100644 --- a/src/Nazara/Graphics/DepthRenderTechnique.cpp +++ b/src/Nazara/Graphics/DepthRenderTechnique.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -55,7 +56,7 @@ bool NzDepthRenderTechnique::Draw(const NzSceneData& sceneData) const if (sceneData.background) sceneData.background->Draw(sceneData.viewer); - if (!m_renderQueue.meshes.empty()) + if (!m_renderQueue.opaqueModels.empty()) DrawOpaqueModels(sceneData); if (!m_renderQueue.basicSprites.empty()) @@ -78,7 +79,7 @@ NzAbstractRenderQueue* NzDepthRenderTechnique::GetRenderQueue() nzRenderTechniqueType NzDepthRenderTechnique::GetType() const { - return nzRenderTechniqueType_BasicForward; + return nzRenderTechniqueType_Depth; } bool NzDepthRenderTechnique::Initialize() @@ -129,11 +130,6 @@ bool NzDepthRenderTechnique::Initialize() s_billboardInstanceDeclaration.EnableComponent(nzVertexComponent_InstanceData0, nzComponentType_Float3, NzOffsetOf(NzForwardRenderQueue::BillboardData, center)); s_billboardInstanceDeclaration.EnableComponent(nzVertexComponent_InstanceData1, nzComponentType_Float4, NzOffsetOf(NzForwardRenderQueue::BillboardData, size)); // Englobe sincos s_billboardInstanceDeclaration.EnableComponent(nzVertexComponent_InstanceData2, nzComponentType_Color, NzOffsetOf(NzForwardRenderQueue::BillboardData, color)); - - // Material - s_material = NzMaterial::New(); - s_material->Enable(nzRendererParameter_ColorWrite, false); - s_material->Enable(nzRendererParameter_FaceCulling, false); } catch (const std::exception& e) { @@ -146,7 +142,6 @@ bool NzDepthRenderTechnique::Initialize() void NzDepthRenderTechnique::Uninitialize() { - s_material.Reset(); s_quadIndexBuffer.Reset(); s_quadVertexBuffer.Reset(); } @@ -155,55 +150,101 @@ void NzDepthRenderTechnique::DrawBasicSprites(const NzSceneData& sceneData) cons { NazaraUnused(sceneData); + const NzShader* lastShader = nullptr; + const ShaderUniforms* shaderUniforms = nullptr; + NzRenderer::SetIndexBuffer(&s_quadIndexBuffer); NzRenderer::SetMatrix(nzMatrixType_World, NzMatrix4f::Identity()); NzRenderer::SetVertexBuffer(&m_spriteBuffer); - auto& spriteChainVector = m_renderQueue.basicSprites; - unsigned int spriteChainCount = spriteChainVector.size(); - if (spriteChainCount > 0) + for (auto& matIt : m_renderQueue.basicSprites) { - s_material->Apply(); + const NzMaterial* material = matIt.first; + auto& matEntry = matIt.second; - unsigned int spriteChain = 0; // Quelle chaîne de sprite traitons-nous - unsigned int spriteChainOffset = 0; // À quel offset dans la dernière chaîne nous sommes-nous arrêtés - - do + if (matEntry.enabled) { - // On ouvre le buffer en écriture - NzBufferMapper vertexMapper(m_spriteBuffer, nzBufferAccess_DiscardAndWrite); - NzVertexStruct_XYZ_Color_UV* vertices = reinterpret_cast(vertexMapper.GetPointer()); - - unsigned int spriteCount = 0; - unsigned int maxSpriteCount = std::min(s_maxQuads, m_spriteBuffer.GetVertexCount()/4); - - do + auto& overlayMap = matEntry.overlayMap; + for (auto& overlayIt : overlayMap) { - NzDepthRenderQueue::SpriteChain_XYZ_Color_UV& currentChain = spriteChainVector[spriteChain]; - unsigned int count = std::min(maxSpriteCount - spriteCount, currentChain.spriteCount - spriteChainOffset); + const NzTexture* overlay = overlayIt.first; + auto& spriteChainVector = overlayIt.second.spriteChains; - std::memcpy(vertices, currentChain.vertices + spriteChainOffset*4, 4*count*sizeof(NzVertexStruct_XYZ_Color_UV)); - vertices += count*4; - - spriteCount += count; - spriteChainOffset += count; - - // Avons-nous traité la chaîne entière ? - if (spriteChainOffset == currentChain.spriteCount) + unsigned int spriteChainCount = spriteChainVector.size(); + if (spriteChainCount > 0) { - spriteChain++; - spriteChainOffset = 0; + // On commence par appliquer du matériau (et récupérer le shader ainsi activé) + nzUInt32 flags = nzShaderFlags_VertexColor; + if (overlay) + flags |= nzShaderFlags_TextureOverlay; + + nzUInt8 overlayUnit; + const NzShader* shader = material->Apply(flags, 0, &overlayUnit); + + if (overlay) + { + overlayUnit++; + NzRenderer::SetTexture(overlayUnit, overlay); + NzRenderer::SetTextureSampler(overlayUnit, material->GetDiffuseSampler()); + } + + // Les uniformes sont conservées au sein d'un programme, inutile de les renvoyer tant qu'il ne change pas + if (shader != lastShader) + { + // Index des uniformes dans le shader + shaderUniforms = GetShaderUniforms(shader); + + // Overlay + shader->SendInteger(shaderUniforms->textureOverlay, overlayUnit); + + lastShader = shader; + } + + unsigned int spriteChain = 0; // Quelle chaîne de sprite traitons-nous + unsigned int spriteChainOffset = 0; // À quel offset dans la dernière chaîne nous sommes-nous arrêtés + + do + { + // On ouvre le buffer en écriture + NzBufferMapper vertexMapper(m_spriteBuffer, nzBufferAccess_DiscardAndWrite); + NzVertexStruct_XYZ_Color_UV* vertices = reinterpret_cast(vertexMapper.GetPointer()); + + unsigned int spriteCount = 0; + unsigned int maxSpriteCount = std::min(s_maxQuads, m_spriteBuffer.GetVertexCount()/4); + + do + { + NzForwardRenderQueue::SpriteChain_XYZ_Color_UV& currentChain = spriteChainVector[spriteChain]; + unsigned int count = std::min(maxSpriteCount - spriteCount, currentChain.spriteCount - spriteChainOffset); + + std::memcpy(vertices, currentChain.vertices + spriteChainOffset*4, 4*count*sizeof(NzVertexStruct_XYZ_Color_UV)); + vertices += count*4; + + spriteCount += count; + spriteChainOffset += count; + + // Avons-nous traité la chaîne entière ? + if (spriteChainOffset == currentChain.spriteCount) + { + spriteChain++; + spriteChainOffset = 0; + } + } + while (spriteCount < maxSpriteCount && spriteChain < spriteChainCount); + + vertexMapper.Unmap(); + + NzRenderer::DrawIndexedPrimitives(nzPrimitiveMode_TriangleList, 0, spriteCount*6); + } + while (spriteChain < spriteChainCount); + + spriteChainVector.clear(); } } - while (spriteCount < maxSpriteCount && spriteChain < spriteChainCount); - vertexMapper.Unmap(); - - NzRenderer::DrawIndexedPrimitives(nzPrimitiveMode_TriangleList, 0, spriteCount*6); + // On remet à zéro + matEntry.enabled = false; } - while (spriteChain < spriteChainCount); - - spriteChainVector.clear(); } } @@ -218,27 +259,34 @@ void NzDepthRenderTechnique::DrawBillboards(const NzSceneData& sceneData) const NzRenderer::SetVertexBuffer(&s_quadVertexBuffer); - auto& billboardVector = m_renderQueue.billboards; - unsigned int billboardCount = billboardVector.size(); - if (billboardCount > 0) + for (auto& matIt : m_renderQueue.billboards) { - s_material->Apply(nzShaderFlags_Billboard | nzShaderFlags_Instancing); + const NzMaterial* material = matIt.first; + auto& entry = matIt.second; + auto& billboardVector = entry.billboards; - const NzDepthRenderQueue::BillboardData* data = &billboardVector[0]; - unsigned int maxBillboardPerDraw = instanceBuffer->GetVertexCount(); - do + unsigned int billboardCount = billboardVector.size(); + if (billboardCount > 0) { - unsigned int renderedBillboardCount = std::min(billboardCount, maxBillboardPerDraw); - billboardCount -= renderedBillboardCount; + // On commence par appliquer du matériau + material->Apply(nzShaderFlags_Billboard | nzShaderFlags_Instancing | nzShaderFlags_VertexColor); - instanceBuffer->Fill(data, 0, renderedBillboardCount, true); - data += renderedBillboardCount; + const NzForwardRenderQueue::BillboardData* data = &billboardVector[0]; + unsigned int maxBillboardPerDraw = instanceBuffer->GetVertexCount(); + do + { + unsigned int renderedBillboardCount = std::min(billboardCount, maxBillboardPerDraw); + billboardCount -= renderedBillboardCount; - NzRenderer::DrawPrimitivesInstanced(renderedBillboardCount, nzPrimitiveMode_TriangleStrip, 0, 4); + instanceBuffer->Fill(data, 0, renderedBillboardCount, true); + data += renderedBillboardCount; + + NzRenderer::DrawPrimitivesInstanced(renderedBillboardCount, nzPrimitiveMode_TriangleStrip, 0, 4); + } + while (billboardCount > 0); + + billboardVector.clear(); } - while (billboardCount > 0); - - billboardVector.clear(); } } else @@ -246,64 +294,70 @@ void NzDepthRenderTechnique::DrawBillboards(const NzSceneData& sceneData) const NzRenderer::SetIndexBuffer(&s_quadIndexBuffer); NzRenderer::SetVertexBuffer(&m_billboardPointBuffer); - auto& billboardVector = m_renderQueue.billboards; - - unsigned int billboardCount = billboardVector.size(); - if (billboardCount > 0) + for (auto& matIt : m_renderQueue.billboards) { - s_material->Apply(nzShaderFlags_Billboard); + const NzMaterial* material = matIt.first; + auto& entry = matIt.second; + auto& billboardVector = entry.billboards; - const NzDepthRenderQueue::BillboardData* data = &billboardVector[0]; - unsigned int maxBillboardPerDraw = std::min(s_maxQuads, m_billboardPointBuffer.GetVertexCount()/4); - - do + unsigned int billboardCount = billboardVector.size(); + if (billboardCount > 0) { - unsigned int renderedBillboardCount = std::min(billboardCount, maxBillboardPerDraw); - billboardCount -= renderedBillboardCount; + // On commence par appliquer du matériau + material->Apply(nzShaderFlags_Billboard | nzShaderFlags_VertexColor); - NzBufferMapper vertexMapper(m_billboardPointBuffer, nzBufferAccess_DiscardAndWrite, 0, renderedBillboardCount*4); - BillboardPoint* vertices = reinterpret_cast(vertexMapper.GetPointer()); + const NzForwardRenderQueue::BillboardData* data = &billboardVector[0]; + unsigned int maxBillboardPerDraw = std::min(s_maxQuads, m_billboardPointBuffer.GetVertexCount()/4); - for (unsigned int i = 0; i < renderedBillboardCount; ++i) + do { - const NzDepthRenderQueue::BillboardData& billboard = *data++; + unsigned int renderedBillboardCount = std::min(billboardCount, maxBillboardPerDraw); + billboardCount -= renderedBillboardCount; - vertices->color = billboard.color; - vertices->position = billboard.center; - vertices->sinCos = billboard.sinCos; - vertices->size = billboard.size; - vertices->uv.Set(0.f, 1.f); - vertices++; + NzBufferMapper vertexMapper(m_billboardPointBuffer, nzBufferAccess_DiscardAndWrite, 0, renderedBillboardCount*4); + BillboardPoint* vertices = reinterpret_cast(vertexMapper.GetPointer()); - vertices->color = billboard.color; - vertices->position = billboard.center; - vertices->sinCos = billboard.sinCos; - vertices->size = billboard.size; - vertices->uv.Set(1.f, 1.f); - vertices++; + for (unsigned int i = 0; i < renderedBillboardCount; ++i) + { + const NzForwardRenderQueue::BillboardData& billboard = *data++; - vertices->color = billboard.color; - vertices->position = billboard.center; - vertices->sinCos = billboard.sinCos; - vertices->size = billboard.size; - vertices->uv.Set(0.f, 0.f); - vertices++; + vertices->color = billboard.color; + vertices->position = billboard.center; + vertices->sinCos = billboard.sinCos; + vertices->size = billboard.size; + vertices->uv.Set(0.f, 1.f); + vertices++; - vertices->color = billboard.color; - vertices->position = billboard.center; - vertices->sinCos = billboard.sinCos; - vertices->size = billboard.size; - vertices->uv.Set(1.f, 0.f); - vertices++; + vertices->color = billboard.color; + vertices->position = billboard.center; + vertices->sinCos = billboard.sinCos; + vertices->size = billboard.size; + vertices->uv.Set(1.f, 1.f); + vertices++; + + vertices->color = billboard.color; + vertices->position = billboard.center; + vertices->sinCos = billboard.sinCos; + vertices->size = billboard.size; + vertices->uv.Set(0.f, 0.f); + vertices++; + + vertices->color = billboard.color; + vertices->position = billboard.center; + vertices->sinCos = billboard.sinCos; + vertices->size = billboard.size; + vertices->uv.Set(1.f, 0.f); + vertices++; + } + + vertexMapper.Unmap(); + + NzRenderer::DrawIndexedPrimitives(nzPrimitiveMode_TriangleList, 0, renderedBillboardCount*6); } + while (billboardCount > 0); - vertexMapper.Unmap(); - - NzRenderer::DrawIndexedPrimitives(nzPrimitiveMode_TriangleList, 0, renderedBillboardCount*6); + billboardVector.clear(); } - while (billboardCount > 0); - - billboardVector.clear(); } } } @@ -312,55 +366,130 @@ void NzDepthRenderTechnique::DrawOpaqueModels(const NzSceneData& sceneData) cons { NazaraUnused(sceneData); - s_material->Apply(); - - for (auto& meshIt : m_renderQueue.meshes) + for (auto& matIt : m_renderQueue.opaqueModels) { - const NzMeshData& meshData = meshIt.first; - auto& meshEntry = meshIt.second; + auto& matEntry = matIt.second; - std::vector& instances = meshEntry.instances; - if (!instances.empty()) + if (matEntry.enabled) { - const NzIndexBuffer* indexBuffer = meshData.indexBuffer; - const NzVertexBuffer* vertexBuffer = meshData.vertexBuffer; + NzForwardRenderQueue::MeshInstanceContainer& meshInstances = matEntry.meshMap; - // Gestion du draw call avant la boucle de rendu - NzRenderer::DrawCall drawFunc; - NzRenderer::DrawCallInstanced instancedDrawFunc; - unsigned int indexCount; + if (!meshInstances.empty()) + { + const NzMaterial* material = matIt.first; - if (indexBuffer) - { - drawFunc = NzRenderer::DrawIndexedPrimitives; - instancedDrawFunc = NzRenderer::DrawIndexedPrimitivesInstanced; - indexCount = indexBuffer->GetIndexCount(); - } - else - { - drawFunc = NzRenderer::DrawPrimitives; - instancedDrawFunc = NzRenderer::DrawPrimitivesInstanced; - indexCount = vertexBuffer->GetVertexCount(); + // Nous utilisons de l'instancing que lorsqu'aucune lumière (autre que directionnelle) n'est active + // Ceci car l'instancing n'est pas compatible avec la recherche des lumières les plus proches + // (Le deferred shading n'a pas ce problème) + bool noPointSpotLight = m_renderQueue.pointLights.empty() && m_renderQueue.spotLights.empty(); + bool instancing = m_instancingEnabled && (!material->IsLightingEnabled() || noPointSpotLight) && matEntry.instancingEnabled; + + // On commence par appliquer du matériau (et récupérer le shader ainsi activé) + material->Apply((instancing) ? nzShaderFlags_Instancing : 0); + + // Meshes + for (auto& meshIt : meshInstances) + { + const NzMeshData& meshData = meshIt.first; + auto& meshEntry = meshIt.second; + + std::vector& instances = meshEntry.instances; + if (!instances.empty()) + { + const NzIndexBuffer* indexBuffer = meshData.indexBuffer; + const NzVertexBuffer* vertexBuffer = meshData.vertexBuffer; + + // Gestion du draw call avant la boucle de rendu + NzRenderer::DrawCall drawFunc; + NzRenderer::DrawCallInstanced instancedDrawFunc; + unsigned int indexCount; + + if (indexBuffer) + { + drawFunc = NzRenderer::DrawIndexedPrimitives; + instancedDrawFunc = NzRenderer::DrawIndexedPrimitivesInstanced; + indexCount = indexBuffer->GetIndexCount(); + } + else + { + drawFunc = NzRenderer::DrawPrimitives; + instancedDrawFunc = NzRenderer::DrawPrimitivesInstanced; + indexCount = vertexBuffer->GetVertexCount(); + } + + NzRenderer::SetIndexBuffer(indexBuffer); + NzRenderer::SetVertexBuffer(vertexBuffer); + + if (instancing) + { + // On calcule le nombre d'instances que l'on pourra afficher cette fois-ci (Selon la taille du buffer d'instancing) + NzVertexBuffer* instanceBuffer = NzRenderer::GetInstanceBuffer(); + instanceBuffer->SetVertexDeclaration(NzVertexDeclaration::Get(nzVertexLayout_Matrix4)); + + const NzMatrix4f* instanceMatrices = &instances[0]; + unsigned int instanceCount = instances.size(); + unsigned int maxInstanceCount = instanceBuffer->GetVertexCount(); // Le nombre maximum d'instances en une fois + + while (instanceCount > 0) + { + // On calcule le nombre d'instances que l'on pourra afficher cette fois-ci (Selon la taille du buffer d'instancing) + unsigned int renderedInstanceCount = std::min(instanceCount, maxInstanceCount); + instanceCount -= renderedInstanceCount; + + // On remplit l'instancing buffer avec nos matrices world + instanceBuffer->Fill(instanceMatrices, 0, renderedInstanceCount, true); + instanceMatrices += renderedInstanceCount; + + // Et on affiche + instancedDrawFunc(renderedInstanceCount, meshData.primitiveMode, 0, indexCount); + } + } + else + { + // Sans instancing, on doit effectuer un draw call pour chaque instance + // Cela reste néanmoins plus rapide que l'instancing en dessous d'un certain nombre d'instances + // À cause du temps de modification du buffer d'instancing + for (const NzMatrix4f& matrix : instances) + { + NzRenderer::SetMatrix(nzMatrixType_World, matrix); + drawFunc(meshData.primitiveMode, 0, indexCount); + } + } + instances.clear(); + } + } } - NzRenderer::SetIndexBuffer(indexBuffer); - NzRenderer::SetVertexBuffer(vertexBuffer); - - // Sans instancing, on doit effectuer un draw call pour chaque instance - // Cela reste néanmoins plus rapide que l'instancing en dessous d'un certain nombre d'instances - // À cause du temps de modification du buffer d'instancing - for (const NzMatrix4f& matrix : instances) - { - NzRenderer::SetMatrix(nzMatrixType_World, matrix); - drawFunc(meshData.primitiveMode, 0, indexCount); - } - instances.clear(); + // Et on remet à zéro les données + matEntry.enabled = false; + matEntry.instancingEnabled = false; } } } +const NzDepthRenderTechnique::ShaderUniforms* NzDepthRenderTechnique::GetShaderUniforms(const NzShader* shader) const +{ + auto it = m_shaderUniforms.find(shader); + if (it == m_shaderUniforms.end()) + { + ShaderUniforms uniforms; + uniforms.shaderReleaseSlot.Connect(shader->OnShaderRelease, this, &NzDepthRenderTechnique::OnShaderInvalidated); + uniforms.shaderUniformInvalidatedSlot.Connect(shader->OnShaderUniformInvalidated, this, &NzDepthRenderTechnique::OnShaderInvalidated); + + uniforms.textureOverlay = shader->GetUniformLocation("TextureOverlay"); + + it = m_shaderUniforms.emplace(shader, std::move(uniforms)).first; + } + + return &it->second; +} + +void NzDepthRenderTechnique::OnShaderInvalidated(const NzShader* shader) const +{ + m_shaderUniforms.erase(shader); +} + NzIndexBuffer NzDepthRenderTechnique::s_quadIndexBuffer; -NzMaterialRef NzDepthRenderTechnique::s_material; NzVertexBuffer NzDepthRenderTechnique::s_quadVertexBuffer; NzVertexDeclaration NzDepthRenderTechnique::s_billboardInstanceDeclaration; NzVertexDeclaration NzDepthRenderTechnique::s_billboardVertexDeclaration; From 4d07735b85f1f89a88efcfebaf03e8740bc04801 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 5 Jul 2015 23:56:30 +0200 Subject: [PATCH 26/37] Ndk/Rendersystem: Add point-light shadows generation Former-commit-id: ecf1fb1c83bafddba9e91f31f018e72180893e5c --- SDK/src/NDK/Systems/RenderSystem.cpp | 91 +++++++++++++++++++++------- 1 file changed, 68 insertions(+), 23 deletions(-) diff --git a/SDK/src/NDK/Systems/RenderSystem.cpp b/SDK/src/NDK/Systems/RenderSystem.cpp index e5057dc66..f4c8fe82c 100644 --- a/SDK/src/NDK/Systems/RenderSystem.cpp +++ b/SDK/src/NDK/Systems/RenderSystem.cpp @@ -95,41 +95,86 @@ namespace Ndk if (!m_shadowRT.IsValid()) m_shadowRT.Create(); + NzSceneData dummySceneData; + dummySceneData.ambientColor = NzColor(0, 0, 0); + dummySceneData.background = nullptr; + dummySceneData.viewer = nullptr; //< Depth technique doesn't require any viewer + for (const Ndk::EntityHandle& light : m_lights) { LightComponent& lightComponent = light->GetComponent(); NodeComponent& lightNode = light->GetComponent(); - if (!lightComponent.IsShadowCastingEnabled() || lightComponent.GetLightType() != nzLightType_Spot) + if (!lightComponent.IsShadowCastingEnabled() || lightComponent.GetLightType() == nzLightType_Directional) continue; NzVector2ui shadowMapSize(lightComponent.GetShadowMap()->GetSize()); - m_shadowRT.AttachTexture(nzAttachmentPoint_Depth, 0, lightComponent.GetShadowMap()); - - ///TODO: Cache the matrices in the light? - NzRenderer::SetMatrix(nzMatrixType_Projection, NzMatrix4f::Perspective(lightComponent.GetOuterAngle(), 1.f, 1.f, 1000.f)); - NzRenderer::SetMatrix(nzMatrixType_View, NzMatrix4f::ViewMatrix(lightNode.GetPosition(), lightNode.GetRotation())); - NzRenderer::SetTarget(&m_shadowRT); - NzRenderer::SetViewport(NzRecti(0, 0, shadowMapSize.x, shadowMapSize.y)); - - NzAbstractRenderQueue* renderQueue = m_shadowTechnique.GetRenderQueue(); - renderQueue->Clear(); - - for (const Ndk::EntityHandle& drawable : m_drawables) + switch (lightComponent.GetLightType()) { - GraphicsComponent& graphicsComponent = drawable->GetComponent(); - NodeComponent& drawableNode = drawable->GetComponent(); + case nzLightType_Point: + { + static NzQuaternionf rotations[6] = + { + NzQuaternionf::RotationBetween(NzVector3f::Forward(), NzVector3f::UnitX()), // nzCubemapFace_PositiveX + NzQuaternionf::RotationBetween(NzVector3f::Forward(), -NzVector3f::UnitX()), // nzCubemapFace_NegativeX + NzQuaternionf::RotationBetween(NzVector3f::Forward(), -NzVector3f::UnitY()), // nzCubemapFace_PositiveY + NzQuaternionf::RotationBetween(NzVector3f::Forward(), NzVector3f::UnitY()), // nzCubemapFace_NegativeY + NzQuaternionf::RotationBetween(NzVector3f::Forward(), -NzVector3f::UnitZ()), // nzCubemapFace_PositiveZ + NzQuaternionf::RotationBetween(NzVector3f::Forward(), NzVector3f::UnitZ()) // nzCubemapFace_NegativeZ + }; - graphicsComponent.AddToRenderQueue(renderQueue); + for (unsigned int face = 0; face < 6; ++face) + { + m_shadowRT.AttachTexture(nzAttachmentPoint_Depth, 0, lightComponent.GetShadowMap(), face); + NzRenderer::SetTarget(&m_shadowRT); + NzRenderer::SetViewport(NzRecti(0, 0, shadowMapSize.x, shadowMapSize.y)); + + ///TODO: Cache the matrices in the light? + NzRenderer::SetMatrix(nzMatrixType_Projection, NzMatrix4f::Perspective(NzFromDegrees(90.f), 1.f, 0.1f, lightComponent.GetRadius())); + NzRenderer::SetMatrix(nzMatrixType_View, NzMatrix4f::ViewMatrix(lightNode.GetPosition(), rotations[face])); + + NzAbstractRenderQueue* renderQueue = m_shadowTechnique.GetRenderQueue(); + renderQueue->Clear(); + + ///TODO: Culling + for (const Ndk::EntityHandle& drawable : m_drawables) + { + GraphicsComponent& graphicsComponent = drawable->GetComponent(); + NodeComponent& drawableNode = drawable->GetComponent(); + + graphicsComponent.AddToRenderQueue(renderQueue); + } + + m_shadowTechnique.Draw(dummySceneData); + } + break; + } + + case nzLightType_Spot: + m_shadowRT.AttachTexture(nzAttachmentPoint_Depth, 0, lightComponent.GetShadowMap()); + NzRenderer::SetTarget(&m_shadowRT); + NzRenderer::SetViewport(NzRecti(0, 0, shadowMapSize.x, shadowMapSize.y)); + + ///TODO: Cache the matrices in the light? + NzRenderer::SetMatrix(nzMatrixType_Projection, NzMatrix4f::Perspective(lightComponent.GetOuterAngle()*2.f, 1.f, 0.1f, lightComponent.GetRadius())); + NzRenderer::SetMatrix(nzMatrixType_View, NzMatrix4f::ViewMatrix(lightNode.GetPosition(), lightNode.GetRotation())); + + NzAbstractRenderQueue* renderQueue = m_shadowTechnique.GetRenderQueue(); + renderQueue->Clear(); + + ///TODO: Culling + for (const Ndk::EntityHandle& drawable : m_drawables) + { + GraphicsComponent& graphicsComponent = drawable->GetComponent(); + NodeComponent& drawableNode = drawable->GetComponent(); + + graphicsComponent.AddToRenderQueue(renderQueue); + } + + m_shadowTechnique.Draw(dummySceneData); + break; } - - NzSceneData sceneData; - sceneData.ambientColor = NzColor(0, 0, 0); - sceneData.background = nullptr; - sceneData.viewer = nullptr; //< Depth technique doesn't require any viewer - - m_shadowTechnique.Draw(sceneData); } } From 75972fec36c16f08dd916dd64908b31c1d70b0b0 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 5 Jul 2015 23:57:54 +0200 Subject: [PATCH 27/37] Graphics: Add shadow mapping Former-commit-id: ca404bee246991eab98df35396e3010ec5165c43 --- .../Nazara/Graphics/AbstractRenderQueue.hpp | 3 + .../Graphics/ForwardRenderTechnique.hpp | 5 +- .../Graphics/ForwardRenderTechnique.inl | 39 +++- include/Nazara/Graphics/Light.hpp | 7 +- .../Graphics/ForwardRenderTechnique.cpp | 22 ++- src/Nazara/Graphics/Light.cpp | 9 + .../Resources/Shaders/PhongLighting/core.frag | 167 +++++++++++++----- .../Shaders/PhongLighting/core.frag.h | 2 +- .../Resources/Shaders/PhongLighting/core.vert | 8 + .../Shaders/PhongLighting/core.vert.h | 2 +- 10 files changed, 206 insertions(+), 58 deletions(-) diff --git a/include/Nazara/Graphics/AbstractRenderQueue.hpp b/include/Nazara/Graphics/AbstractRenderQueue.hpp index e641dcca0..f7e0ad79d 100644 --- a/include/Nazara/Graphics/AbstractRenderQueue.hpp +++ b/include/Nazara/Graphics/AbstractRenderQueue.hpp @@ -68,6 +68,7 @@ class NAZARA_GRAPHICS_API NzAbstractRenderQueue { NzColor color; NzVector3f position; + NzTexture* shadowMap; float ambientFactor; float attenuation; float diffuseFactor; @@ -78,8 +79,10 @@ class NAZARA_GRAPHICS_API NzAbstractRenderQueue struct SpotLight { NzColor color; + NzMatrix4f transformMatrix; NzVector3f direction; NzVector3f position; + NzTexture* shadowMap; float ambientFactor; float attenuation; float diffuseFactor; diff --git a/include/Nazara/Graphics/ForwardRenderTechnique.hpp b/include/Nazara/Graphics/ForwardRenderTechnique.hpp index 766fd6fc9..50f8a43c0 100644 --- a/include/Nazara/Graphics/ForwardRenderTechnique.hpp +++ b/include/Nazara/Graphics/ForwardRenderTechnique.hpp @@ -33,7 +33,7 @@ class NAZARA_GRAPHICS_API NzForwardRenderTechnique : public NzAbstractRenderTech static bool Initialize(); static void Uninitialize(); - private: + protected: struct ShaderUniforms; void ChooseLights(const NzSpheref& object, bool includeDirectionalLights = true) const; @@ -43,7 +43,7 @@ class NAZARA_GRAPHICS_API NzForwardRenderTechnique : public NzAbstractRenderTech void DrawTransparentModels(const NzSceneData& sceneData) const; const ShaderUniforms* GetShaderUniforms(const NzShader* shader) const; void OnShaderInvalidated(const NzShader* shader) const; - void SendLightUniforms(const NzShader* shader, const NzLightUniforms& uniforms, unsigned int index, unsigned int uniformOffset) const; + void SendLightUniforms(const NzShader* shader, const NzLightUniforms& uniforms, unsigned int index, unsigned int uniformOffset, nzUInt8 availableTextureUnit) const; static float ComputeDirectionalLightScore(const NzSpheref& object, const NzAbstractRenderQueue::DirectionalLight& light); static float ComputePointLightScore(const NzSpheref& object, const NzAbstractRenderQueue::PointLight& light); @@ -86,6 +86,7 @@ class NAZARA_GRAPHICS_API NzForwardRenderTechnique : public NzAbstractRenderTech unsigned int m_maxLightPassPerObject; static NzIndexBuffer s_quadIndexBuffer; + static NzTextureSampler s_shadowSampler; static NzVertexBuffer s_quadVertexBuffer; static NzVertexDeclaration s_billboardInstanceDeclaration; static NzVertexDeclaration s_billboardVertexDeclaration; diff --git a/include/Nazara/Graphics/ForwardRenderTechnique.inl b/include/Nazara/Graphics/ForwardRenderTechnique.inl index 8d4d8736b..2e9f46dd4 100644 --- a/include/Nazara/Graphics/ForwardRenderTechnique.inl +++ b/include/Nazara/Graphics/ForwardRenderTechnique.inl @@ -2,8 +2,14 @@ // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp -inline void NzForwardRenderTechnique::SendLightUniforms(const NzShader* shader, const NzLightUniforms& uniforms, unsigned int index, unsigned int uniformOffset) const +#include + +inline void NzForwardRenderTechnique::SendLightUniforms(const NzShader* shader, const NzLightUniforms& uniforms, unsigned int index, unsigned int uniformOffset, nzUInt8 availableTextureUnit) const { + // If anyone got a better idea.. + int dummyCubemap = NzRenderer::GetMaxTextureUnits() - 1; + int dummyTexture = NzRenderer::GetMaxTextureUnits() - 2; + if (index < m_lights.size()) { const LightIndex& lightIndex = m_lights[index]; @@ -30,6 +36,19 @@ inline void NzForwardRenderTechnique::SendLightUniforms(const NzShader* shader, shader->SendVector(uniforms.locations.factors + uniformOffset, NzVector2f(light.ambientFactor, light.diffuseFactor)); shader->SendVector(uniforms.locations.parameters1 + uniformOffset, NzVector4f(light.position, light.attenuation)); shader->SendVector(uniforms.locations.parameters2 + uniformOffset, NzVector4f(0.f, 0.f, 0.f, light.invRadius)); + + shader->SendBoolean(uniforms.locations.shadowMapping + uniformOffset, light.shadowMap != nullptr); + if (light.shadowMap) + { + NzRenderer::SetTexture(availableTextureUnit, light.shadowMap); + NzRenderer::SetTextureSampler(availableTextureUnit, s_shadowSampler); + + shader->SendInteger(uniforms.locations.pointLightShadowMap + index, availableTextureUnit); + } + else + shader->SendInteger(uniforms.locations.pointLightShadowMap + index, dummyCubemap); + + shader->SendInteger(uniforms.locations.spotLightShadowMap + index, dummyTexture); break; } @@ -42,12 +61,30 @@ inline void NzForwardRenderTechnique::SendLightUniforms(const NzShader* shader, shader->SendVector(uniforms.locations.parameters1 + uniformOffset, NzVector4f(light.position, light.attenuation)); shader->SendVector(uniforms.locations.parameters2 + uniformOffset, NzVector4f(light.direction, light.invRadius)); shader->SendVector(uniforms.locations.parameters3 + uniformOffset, NzVector2f(light.innerAngleCosine, light.outerAngleCosine)); + + shader->SendBoolean(uniforms.locations.shadowMapping + uniformOffset, light.shadowMap != nullptr); + if (light.shadowMap) + { + NzRenderer::SetTexture(availableTextureUnit, light.shadowMap); + NzRenderer::SetTextureSampler(availableTextureUnit, s_shadowSampler); + + shader->SendMatrix(uniforms.locations.lightViewProjMatrix + index, light.transformMatrix); + shader->SendInteger(uniforms.locations.spotLightShadowMap + index, availableTextureUnit); + } + else + shader->SendInteger(uniforms.locations.spotLightShadowMap + index, dummyTexture); + + shader->SendInteger(uniforms.locations.pointLightShadowMap + index, dummyCubemap); break; } } } else + { shader->SendInteger(uniforms.locations.type + uniformOffset, -1); //< Disable the light in the shader + shader->SendInteger(uniforms.locations.pointLightShadowMap + index, dummyCubemap); + shader->SendInteger(uniforms.locations.spotLightShadowMap + index, dummyTexture); + } } inline float NzForwardRenderTechnique::ComputeDirectionalLightScore(const NzSpheref& object, const NzAbstractRenderQueue::DirectionalLight& light) diff --git a/include/Nazara/Graphics/Light.hpp b/include/Nazara/Graphics/Light.hpp index 5d42c0961..a8cdaf191 100644 --- a/include/Nazara/Graphics/Light.hpp +++ b/include/Nazara/Graphics/Light.hpp @@ -14,9 +14,6 @@ #include #include -class NzLight; -struct NzLightUniforms; - class NAZARA_GRAPHICS_API NzLight : public NzRenderable { public: @@ -101,9 +98,13 @@ struct NzLightUniforms int type; int color; int factors; + int lightViewProjMatrix; int parameters1; int parameters2; int parameters3; + int pointLightShadowMap; + int shadowMapping; + int spotLightShadowMap; }; bool ubo; diff --git a/src/Nazara/Graphics/ForwardRenderTechnique.cpp b/src/Nazara/Graphics/ForwardRenderTechnique.cpp index 440ad7a5b..b8611feaa 100644 --- a/src/Nazara/Graphics/ForwardRenderTechnique.cpp +++ b/src/Nazara/Graphics/ForwardRenderTechnique.cpp @@ -147,6 +147,9 @@ bool NzForwardRenderTechnique::Initialize() s_billboardInstanceDeclaration.EnableComponent(nzVertexComponent_InstanceData0, nzComponentType_Float3, NzOffsetOf(NzForwardRenderQueue::BillboardData, center)); s_billboardInstanceDeclaration.EnableComponent(nzVertexComponent_InstanceData1, nzComponentType_Float4, NzOffsetOf(NzForwardRenderQueue::BillboardData, size)); // Englobe sincos s_billboardInstanceDeclaration.EnableComponent(nzVertexComponent_InstanceData2, nzComponentType_Color, NzOffsetOf(NzForwardRenderQueue::BillboardData, color)); + + s_shadowSampler.SetFilterMode(nzSamplerFilter_Bilinear); + s_shadowSampler.SetWrapMode(nzSamplerWrap_Clamp); } catch (const std::exception& e) { @@ -475,7 +478,8 @@ void NzForwardRenderTechnique::DrawOpaqueModels(const NzSceneData& sceneData) co bool instancing = m_instancingEnabled && (!material->IsLightingEnabled() || noPointSpotLight) && matEntry.instancingEnabled; // On commence par appliquer du matériau (et récupérer le shader ainsi activé) - const NzShader* shader = material->Apply((instancing) ? nzShaderFlags_Instancing : 0); + nzUInt8 freeTextureUnit; + const NzShader* shader = material->Apply((instancing) ? nzShaderFlags_Instancing : 0, 0, &freeTextureUnit); // Les uniformes sont conservées au sein d'un programme, inutile de les renvoyer tant qu'il ne change pas if (shader != lastShader) @@ -559,7 +563,7 @@ void NzForwardRenderTechnique::DrawOpaqueModels(const NzSceneData& sceneData) co // Sends the uniforms for (unsigned int i = 0; i < NAZARA_GRAPHICS_MAX_LIGHT_PER_PASS; ++i) - SendLightUniforms(shader, shaderUniforms->lightUniforms, lightIndex++, i*shaderUniforms->lightOffset); + SendLightUniforms(shader, shaderUniforms->lightUniforms, lightIndex++, i*shaderUniforms->lightOffset, freeTextureUnit + i); } const NzMatrix4f* instanceMatrices = &instances[0]; @@ -618,7 +622,7 @@ void NzForwardRenderTechnique::DrawOpaqueModels(const NzSceneData& sceneData) co // Sends the light uniforms to the shader for (unsigned int i = 0; i < NAZARA_GRAPHICS_MAX_LIGHT_PER_PASS; ++i) - SendLightUniforms(shader, shaderUniforms->lightUniforms, lightIndex++, shaderUniforms->lightOffset*i); + SendLightUniforms(shader, shaderUniforms->lightUniforms, lightIndex++, shaderUniforms->lightOffset*i, freeTextureUnit + i); // Et on passe à l'affichage drawFunc(meshData.primitiveMode, 0, indexCount); @@ -668,7 +672,8 @@ void NzForwardRenderTechnique::DrawTransparentModels(const NzSceneData& sceneDat const NzMaterial* material = modelData.material; // On commence par appliquer du matériau (et récupérer le shader ainsi activé) - const NzShader* shader = material->Apply(); + nzUInt8 freeTextureUnit; + const NzShader* shader = material->Apply(0, 0, &freeTextureUnit); // Les uniformes sont conservées au sein d'un programme, inutile de les renvoyer tant qu'il ne change pas if (shader != lastShader) @@ -687,7 +692,7 @@ void NzForwardRenderTechnique::DrawTransparentModels(const NzSceneData& sceneDat lightCount = std::min(m_renderQueue.directionalLights.size(), NazaraSuffixMacro(NAZARA_GRAPHICS_MAX_LIGHT_PER_PASS, U)); for (unsigned int i = 0; i < lightCount; ++i) - SendLightUniforms(shader, shaderUniforms->lightUniforms, i, shaderUniforms->lightOffset * i); + SendLightUniforms(shader, shaderUniforms->lightUniforms, i, shaderUniforms->lightOffset * i, freeTextureUnit++); } lastShader = shader; @@ -726,7 +731,7 @@ void NzForwardRenderTechnique::DrawTransparentModels(const NzSceneData& sceneDat ChooseLights(NzSpheref(position, radius), false); for (unsigned int i = lightCount; i < NAZARA_GRAPHICS_MAX_LIGHT_PER_PASS; ++i) - SendLightUniforms(shader, shaderUniforms->lightUniforms, i, shaderUniforms->lightOffset*i); + SendLightUniforms(shader, shaderUniforms->lightUniforms, i, shaderUniforms->lightOffset*i, freeTextureUnit++); } NzRenderer::SetMatrix(nzMatrixType_World, matrix); @@ -758,9 +763,13 @@ const NzForwardRenderTechnique::ShaderUniforms* NzForwardRenderTechnique::GetSha uniforms.lightUniforms.locations.type = type0Location; uniforms.lightUniforms.locations.color = shader->GetUniformLocation("Lights[0].color"); uniforms.lightUniforms.locations.factors = shader->GetUniformLocation("Lights[0].factors"); + uniforms.lightUniforms.locations.lightViewProjMatrix = shader->GetUniformLocation("LightViewProjMatrix[0]"); uniforms.lightUniforms.locations.parameters1 = shader->GetUniformLocation("Lights[0].parameters1"); uniforms.lightUniforms.locations.parameters2 = shader->GetUniformLocation("Lights[0].parameters2"); uniforms.lightUniforms.locations.parameters3 = shader->GetUniformLocation("Lights[0].parameters3"); + uniforms.lightUniforms.locations.pointLightShadowMap = shader->GetUniformLocation("PointLightShadowMap[0]"); + uniforms.lightUniforms.locations.shadowMapping = shader->GetUniformLocation("Lights[0].shadowMapping"); + uniforms.lightUniforms.locations.spotLightShadowMap = shader->GetUniformLocation("SpotLightShadowMap[0]"); } else uniforms.hasLightUniforms = false; @@ -777,6 +786,7 @@ void NzForwardRenderTechnique::OnShaderInvalidated(const NzShader* shader) const } NzIndexBuffer NzForwardRenderTechnique::s_quadIndexBuffer; +NzTextureSampler NzForwardRenderTechnique::s_shadowSampler; NzVertexBuffer NzForwardRenderTechnique::s_quadVertexBuffer; NzVertexDeclaration NzForwardRenderTechnique::s_billboardInstanceDeclaration; NzVertexDeclaration NzForwardRenderTechnique::s_billboardVertexDeclaration; diff --git a/src/Nazara/Graphics/Light.cpp b/src/Nazara/Graphics/Light.cpp index be93fd055..4fc4506e7 100644 --- a/src/Nazara/Graphics/Light.cpp +++ b/src/Nazara/Graphics/Light.cpp @@ -57,6 +57,7 @@ void NzLight::AddToRenderQueue(NzAbstractRenderQueue* renderQueue, const NzMatri light.invRadius = m_invRadius; light.position = transformMatrix.GetTranslation(); light.radius = m_radius; + light.shadowMap = m_shadowMap.Get(); renderQueue->AddPointLight(light); break; @@ -76,6 +77,14 @@ void NzLight::AddToRenderQueue(NzAbstractRenderQueue* renderQueue, const NzMatri light.outerAngleTangent = m_outerAngleTangent; light.position = transformMatrix.GetTranslation(); light.radius = m_radius; + light.shadowMap = m_shadowMap.Get(); + + static NzMatrix4f biasMatrix(0.5f, 0.f, 0.f, 0.f, + 0.f, 0.5f, 0.f, 0.f, + 0.f, 0.f, 0.5f, 0.f, + 0.5f, 0.5f, 0.5f, 1.f); + + light.transformMatrix = NzMatrix4f::ViewMatrix(transformMatrix.GetTranslation(), transformMatrix.GetRotation()) * NzMatrix4f::Perspective(m_outerAngle*2.f, 1.f, 0.1f, m_radius) * biasMatrix; renderQueue->AddSpotLight(light); break; diff --git a/src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.frag b/src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.frag index 80ad84697..e80279b7d 100644 --- a/src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.frag +++ b/src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.frag @@ -8,6 +8,7 @@ layout(early_fragment_tests) in; /********************Entrant********************/ in vec4 vColor; +in vec4 vLightSpacePos[3]; in mat3 vLightToWorld; in vec3 vNormal; in vec2 vTexCoord; @@ -29,10 +30,13 @@ struct Light vec4 parameters1; vec4 parameters2; vec2 parameters3; + bool shadowMapping; }; // Lumières uniform Light Lights[3]; +uniform samplerCube PointLightShadowMap[3]; +uniform sampler2D SpotLightShadowMap[3]; // Matériau uniform sampler2D MaterialAlphaMap; @@ -81,6 +85,32 @@ vec4 EncodeNormal(in vec3 normal) return vec4(vec2(atan(normal.y, normal.x)/kPI, normal.z), 0.0, 0.0); } +float VectorToDepthValue(vec3 vec, float zNear, float zFar) +{ + vec3 absVec = abs(vec); + float localZ = max(absVec.x, max(absVec.y, absVec.z)); + + float normZ = ((zFar + zNear) * localZ - (2.0*zFar*zNear)) / ((zFar - zNear)*localZ); + return (normZ + 1.0) * 0.5; +} + +bool TestShadowDirectional() +{ + ///TODO + return true; +} + +bool TestShadowPoint(int lightIndex, vec3 lightToWorld, float zNear, float zFar) +{ + return texture(PointLightShadowMap[lightIndex], vec3(lightToWorld.x, -lightToWorld.y, -lightToWorld.z)).x >= VectorToDepthValue(lightToWorld, zNear, zFar); +} + +bool TestShadowSpot(int lightIndex) +{ + vec4 lightSpacePos = vLightSpacePos[lightIndex]; + return textureProj(SpotLightShadowMap[lightIndex], lightSpacePos.xyw).x >= (lightSpacePos.z - 0.0005)/lightSpacePos.w; +} + void main() { vec4 diffuseColor = MaterialDiffuse * vColor; @@ -168,6 +198,10 @@ void main() for (int i = 0; i < 3; ++i) { + vec4 lightColor = Lights[i].color; + float lightAmbientFactor = Lights[i].factors.x; + float lightDiffuseFactor = Lights[i].factors.y; + switch (Lights[i].type) { case LIGHT_DIRECTIONAL: @@ -175,75 +209,95 @@ void main() vec3 lightDir = -Lights[i].parameters1.xyz; // Ambient - lightAmbient += Lights[i].color.rgb * Lights[i].factors.x * (MaterialAmbient.rgb + SceneAmbient.rgb); + lightAmbient += lightColor.rgb * lightAmbientFactor * (MaterialAmbient.rgb + SceneAmbient.rgb); // Diffuse float lambert = max(dot(normal, lightDir), 0.0); - lightDiffuse += lambert * Lights[i].color.rgb * Lights[i].factors.y; + lightDiffuse += lambert * lightColor.rgb * lightDiffuseFactor; // Specular vec3 reflection = reflect(-lightDir, normal); float specularFactor = max(dot(reflection, eyeVec), 0.0); specularFactor = pow(specularFactor, MaterialShininess); - lightSpecular += specularFactor * Lights[i].color.rgb; + lightSpecular += specularFactor * lightColor.rgb; break; } case LIGHT_POINT: { - vec3 lightDir = Lights[i].parameters1.xyz - vWorldPos; - float lightDirLength = length(lightDir); - lightDir /= lightDirLength; // Normalisation + vec3 lightPos = Lights[i].parameters1.xyz; + float lightAttenuation = Lights[i].parameters1.w; + float lightInvRadius = Lights[i].parameters2.w; - float att = max(Lights[i].parameters1.w - Lights[i].parameters2.w*lightDirLength, 0.0); + vec3 worldToLight = lightPos - vWorldPos; + float lightDirLength = length(worldToLight); + vec3 lightDir = worldToLight / lightDirLength; // Normalisation + + float att = max(lightAttenuation - lightInvRadius * lightDirLength, 0.0); // Ambient - lightAmbient += att * Lights[i].color.rgb * Lights[i].factors.x * (MaterialAmbient.rgb + SceneAmbient.rgb); + lightAmbient += att * lightColor.rgb * lightAmbientFactor * (MaterialAmbient.rgb + SceneAmbient.rgb); + + #if SHADOW_MAPPING + if (Lights[i].shadowMapping && !TestShadowPoint(i, vWorldPos - lightPos, 0.1, 50.0)) + break; + #endif // Diffuse float lambert = max(dot(normal, lightDir), 0.0); - lightDiffuse += att * lambert * Lights[i].color.rgb * Lights[i].factors.y; + lightDiffuse += att * lambert * lightColor.rgb * lightDiffuseFactor; // Specular vec3 reflection = reflect(-lightDir, normal); float specularFactor = max(dot(reflection, eyeVec), 0.0); specularFactor = pow(specularFactor, MaterialShininess); - lightSpecular += att * specularFactor * Lights[i].color.rgb; + lightSpecular += att * specularFactor * lightColor.rgb; break; } case LIGHT_SPOT: { - vec3 lightDir = Lights[i].parameters1.xyz - vWorldPos; - float lightDirLength = length(lightDir); - lightDir /= lightDirLength; // Normalisation + vec3 lightPos = Lights[i].parameters1.xyz; + vec3 lightDir = Lights[i].parameters2.xyz; + float lightAttenuation = Lights[i].parameters1.w; + float lightInvRadius = Lights[i].parameters2.w; + float lightInnerAngle = Lights[i].parameters3.x; + float lightOuterAngle = Lights[i].parameters3.y; + + vec3 worldToLight = lightPos - vWorldPos; + float lightDistance = length(worldToLight); + worldToLight /= lightDistance; // Normalisation - float att = max(Lights[i].parameters1.w - Lights[i].parameters2.w*lightDirLength, 0.0); + float att = max(lightAttenuation - lightInvRadius * lightDistance, 0.0); // Ambient - lightAmbient += att * Lights[i].color.rgb * Lights[i].factors.x * (MaterialAmbient.rgb + SceneAmbient.rgb); + lightAmbient += att * lightColor.rgb * lightAmbientFactor * (MaterialAmbient.rgb + SceneAmbient.rgb); + + #if SHADOW_MAPPING + if (Lights[i].shadowMapping && !TestShadowSpot(i)) + break; + #endif // Modification de l'atténuation pour gérer le spot - float curAngle = dot(Lights[i].parameters2.xyz, -lightDir); - float outerAngle = Lights[i].parameters3.y; - float innerMinusOuterAngle = Lights[i].parameters3.x - outerAngle; - att *= max((curAngle - outerAngle) / innerMinusOuterAngle, 0.0); + float curAngle = dot(lightDir, -worldToLight); + float innerMinusOuterAngle = lightInnerAngle - lightOuterAngle; + att *= max((curAngle - lightOuterAngle) / innerMinusOuterAngle, 0.0); // Diffuse - float lambert = max(dot(normal, lightDir), 0.0); + float lambert = max(dot(normal, worldToLight), 0.0); - lightDiffuse += att * lambert * Lights[i].color.rgb * Lights[i].factors.y; + lightDiffuse += att * lambert * lightColor.rgb * lightDiffuseFactor; // Specular - vec3 reflection = reflect(-lightDir, normal); + vec3 reflection = reflect(-worldToLight, normal); float specularFactor = max(dot(reflection, eyeVec), 0.0); specularFactor = pow(specularFactor, MaterialShininess); - lightSpecular += att * specularFactor * Lights[i].color.rgb; + lightSpecular += att * specularFactor * lightColor.rgb; break; } @@ -256,61 +310,85 @@ void main() { for (int i = 0; i < 3; ++i) { + vec4 lightColor = Lights[i].color; + float lightAmbientFactor = Lights[i].factors.x; + float lightDiffuseFactor = Lights[i].factors.y; + switch (Lights[i].type) { case LIGHT_DIRECTIONAL: { - vec3 lightDir = normalize(-Lights[i].parameters1.xyz); + vec3 lightDir = -Lights[i].parameters1.xyz; // Ambient - lightAmbient += Lights[i].color.rgb * Lights[i].factors.x * (MaterialAmbient.rgb + SceneAmbient.rgb); + lightAmbient += lightColor.rgb * lightAmbientFactor * (MaterialAmbient.rgb + SceneAmbient.rgb); // Diffuse float lambert = max(dot(normal, lightDir), 0.0); - lightDiffuse += lambert * Lights[i].color.rgb * Lights[i].factors.y; + lightDiffuse += lambert * lightColor.rgb * lightDiffuseFactor; break; } case LIGHT_POINT: { - vec3 lightDir = Lights[i].parameters1.xyz - vWorldPos; - float lightDirLength = length(lightDir); - lightDir /= lightDirLength; // Normalisation + vec3 lightPos = Lights[i].parameters1.xyz; + float lightAttenuation = Lights[i].parameters1.w; + float lightInvRadius = Lights[i].parameters2.w; - float att = max(Lights[i].parameters1.w - Lights[i].parameters2.w*lightDirLength, 0.0); + vec3 worldToLight = lightPos - vWorldPos; + float lightDirLength = length(worldToLight); + vec3 lightDir = worldToLight / lightDirLength; // Normalisation + + float att = max(lightAttenuation - lightInvRadius * lightDirLength, 0.0); // Ambient - lightAmbient += att * Lights[i].color.rgb * Lights[i].factors.x * (MaterialAmbient.rgb + SceneAmbient.rgb); + lightAmbient += att * lightColor.rgb * lightAmbientFactor * (MaterialAmbient.rgb + SceneAmbient.rgb); + + #if SHADOW_MAPPING + if (Lights[i].shadowMapping && !TestShadowPoint(i, vWorldPos - lightPos, 0.1, 1.0 / lightInvRadius)) + break; + #endif // Diffuse float lambert = max(dot(normal, lightDir), 0.0); - lightDiffuse += att * lambert * Lights[i].color.rgb * Lights[i].factors.y; + lightDiffuse += att * lambert * lightColor.rgb * lightDiffuseFactor; break; } case LIGHT_SPOT: { - vec3 lightDir = Lights[i].parameters1.xyz - vWorldPos; - float lightDirLength = length(lightDir); - lightDir /= lightDirLength; // Normalisation + vec3 lightPos = Lights[i].parameters1.xyz; + vec3 lightDir = Lights[i].parameters2.xyz; + float lightAttenuation = Lights[i].parameters1.w; + float lightInvRadius = Lights[i].parameters2.w; + float lightInnerAngle = Lights[i].parameters3.x; + float lightOuterAngle = Lights[i].parameters3.y; + + vec3 worldToLight = lightPos - vWorldPos; + float lightDistance = length(worldToLight); + worldToLight /= lightDistance; // Normalisation - float att = max(Lights[i].parameters1.w - Lights[i].parameters2.w*lightDirLength, 0.0); + float att = max(lightAttenuation - lightInvRadius * lightDistance, 0.0); // Ambient - lightAmbient += att * Lights[i].color.rgb * Lights[i].factors.x * (MaterialAmbient.rgb + SceneAmbient.rgb); + lightAmbient += att * lightColor.rgb * lightAmbientFactor * (MaterialAmbient.rgb + SceneAmbient.rgb); + + #if SHADOW_MAPPING + if (Lights[i].shadowMapping && !TestShadowSpot(i)) + break; + #endif // Modification de l'atténuation pour gérer le spot - float curAngle = dot(Lights[i].parameters2.xyz, -lightDir); - float outerAngle = Lights[i].parameters3.y; - float innerMinusOuterAngle = Lights[i].parameters3.x - outerAngle; - att *= max((curAngle - outerAngle) / innerMinusOuterAngle, 0.0); + float curAngle = dot(lightDir, -worldToLight); + float innerMinusOuterAngle = lightInnerAngle - lightOuterAngle; + att *= max((curAngle - lightOuterAngle) / innerMinusOuterAngle, 0.0); // Diffuse - float lambert = max(dot(normal, lightDir), 0.0); + float lambert = max(dot(normal, worldToLight), 0.0); - lightDiffuse += att * lambert * Lights[i].color.rgb * Lights[i].factors.y; + lightDiffuse += att * lambert * lightColor.rgb * lightDiffuseFactor; } default: @@ -318,7 +396,7 @@ void main() } } } - + lightSpecular *= MaterialSpecular.rgb; #if SPECULAR_MAPPING lightSpecular *= texture(MaterialSpecularMap, texCoord).rgb; // Utiliser l'alpha de MaterialSpecular n'aurait aucun sens @@ -340,3 +418,4 @@ void main() #endif // LIGHTING #endif // FLAG_DEFERRED } + diff --git a/src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.frag.h b/src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.frag.h index 29895eefa..ca82b7284 100644 --- a/src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.frag.h +++ b/src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.frag.h @@ -1 +1 @@ -35,105,102,32,69,65,82,76,89,95,70,82,65,71,77,69,78,84,95,84,69,83,84,83,32,38,38,32,33,65,76,80,72,65,95,84,69,83,84,13,10,108,97,121,111,117,116,40,101,97,114,108,121,95,102,114,97,103,109,101,110,116,95,116,101,115,116,115,41,32,105,110,59,13,10,35,101,110,100,105,102,13,10,13,10,35,100,101,102,105,110,101,32,76,73,71,72,84,95,68,73,82,69,67,84,73,79,78,65,76,32,48,13,10,35,100,101,102,105,110,101,32,76,73,71,72,84,95,80,79,73,78,84,32,49,13,10,35,100,101,102,105,110,101,32,76,73,71,72,84,95,83,80,79,84,32,50,13,10,13,10,47,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,69,110,116,114,97,110,116,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,47,13,10,105,110,32,118,101,99,52,32,118,67,111,108,111,114,59,13,10,105,110,32,109,97,116,51,32,118,76,105,103,104,116,84,111,87,111,114,108,100,59,13,10,105,110,32,118,101,99,51,32,118,78,111,114,109,97,108,59,13,10,105,110,32,118,101,99,50,32,118,84,101,120,67,111,111,114,100,59,13,10,105,110,32,118,101,99,51,32,118,86,105,101,119,68,105,114,59,13,10,105,110,32,118,101,99,51,32,118,87,111,114,108,100,80,111,115,59,13,10,13,10,47,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,83,111,114,116,97,110,116,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,47,13,10,111,117,116,32,118,101,99,52,32,82,101,110,100,101,114,84,97,114,103,101,116,48,59,13,10,111,117,116,32,118,101,99,52,32,82,101,110,100,101,114,84,97,114,103,101,116,49,59,13,10,111,117,116,32,118,101,99,52,32,82,101,110,100,101,114,84,97,114,103,101,116,50,59,13,10,13,10,47,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,85,110,105,102,111,114,109,101,115,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,47,13,10,115,116,114,117,99,116,32,76,105,103,104,116,13,10,123,13,10,9,105,110,116,32,116,121,112,101,59,13,10,9,118,101,99,52,32,99,111,108,111,114,59,13,10,9,118,101,99,50,32,102,97,99,116,111,114,115,59,13,10,13,10,9,118,101,99,52,32,112,97,114,97,109,101,116,101,114,115,49,59,13,10,9,118,101,99,52,32,112,97,114,97,109,101,116,101,114,115,50,59,13,10,9,118,101,99,50,32,112,97,114,97,109,101,116,101,114,115,51,59,13,10,125,59,13,10,13,10,47,47,32,76,117,109,105,195,168,114,101,115,13,10,117,110,105,102,111,114,109,32,76,105,103,104,116,32,76,105,103,104,116,115,91,51,93,59,13,10,13,10,47,47,32,77,97,116,195,169,114,105,97,117,13,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,77,97,116,101,114,105,97,108,65,108,112,104,97,77,97,112,59,13,10,117,110,105,102,111,114,109,32,102,108,111,97,116,32,77,97,116,101,114,105,97,108,65,108,112,104,97,84,104,114,101,115,104,111,108,100,59,13,10,117,110,105,102,111,114,109,32,118,101,99,52,32,77,97,116,101,114,105,97,108,65,109,98,105,101,110,116,59,13,10,117,110,105,102,111,114,109,32,118,101,99,52,32,77,97,116,101,114,105,97,108,68,105,102,102,117,115,101,59,13,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,77,97,116,101,114,105,97,108,68,105,102,102,117,115,101,77,97,112,59,13,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,77,97,116,101,114,105,97,108,69,109,105,115,115,105,118,101,77,97,112,59,13,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,77,97,116,101,114,105,97,108,72,101,105,103,104,116,77,97,112,59,13,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,77,97,116,101,114,105,97,108,78,111,114,109,97,108,77,97,112,59,13,10,117,110,105,102,111,114,109,32,102,108,111,97,116,32,77,97,116,101,114,105,97,108,83,104,105,110,105,110,101,115,115,59,13,10,117,110,105,102,111,114,109,32,118,101,99,52,32,77,97,116,101,114,105,97,108,83,112,101,99,117,108,97,114,59,13,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,77,97,116,101,114,105,97,108,83,112,101,99,117,108,97,114,77,97,112,59,13,10,13,10,47,47,32,65,117,116,114,101,115,13,10,117,110,105,102,111,114,109,32,102,108,111,97,116,32,80,97,114,97,108,108,97,120,66,105,97,115,32,61,32,45,48,46,48,51,59,13,10,117,110,105,102,111,114,109,32,102,108,111,97,116,32,80,97,114,97,108,108,97,120,83,99,97,108,101,32,61,32,48,46,48,50,59,13,10,117,110,105,102,111,114,109,32,118,101,99,50,32,73,110,118,84,97,114,103,101,116,83,105,122,101,59,13,10,117,110,105,102,111,114,109,32,118,101,99,51,32,69,121,101,80,111,115,105,116,105,111,110,59,13,10,117,110,105,102,111,114,109,32,118,101,99,52,32,83,99,101,110,101,65,109,98,105,101,110,116,59,13,10,13,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,84,101,120,116,117,114,101,79,118,101,114,108,97,121,59,13,10,13,10,47,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,70,111,110,99,116,105,111,110,115,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,47,13,10,118,101,99,51,32,70,108,111,97,116,84,111,67,111,108,111,114,40,102,108,111,97,116,32,102,41,13,10,123,13,10,9,118,101,99,51,32,99,111,108,111,114,59,13,10,13,10,9,102,32,42,61,32,50,53,54,46,48,59,13,10,9,99,111,108,111,114,46,120,32,61,32,102,108,111,111,114,40,102,41,59,13,10,13,10,9,102,32,61,32,40,102,32,45,32,99,111,108,111,114,46,120,41,32,42,32,50,53,54,46,48,59,13,10,9,99,111,108,111,114,46,121,32,61,32,102,108,111,111,114,40,102,41,59,13,10,13,10,9,99,111,108,111,114,46,122,32,61,32,102,32,45,32,99,111,108,111,114,46,121,59,13,10,9,99,111,108,111,114,46,120,121,32,42,61,32,48,46,48,48,51,57,48,54,50,53,59,32,47,47,32,42,61,32,49,46,48,47,50,53,54,13,10,13,10,9,114,101,116,117,114,110,32,99,111,108,111,114,59,13,10,125,13,10,13,10,35,100,101,102,105,110,101,32,107,80,73,32,51,46,49,52,49,53,57,50,54,53,51,54,13,10,13,10,118,101,99,52,32,69,110,99,111,100,101,78,111,114,109,97,108,40,105,110,32,118,101,99,51,32,110,111,114,109,97,108,41,13,10,123,13,10,9,47,47,114,101,116,117,114,110,32,118,101,99,52,40,110,111,114,109,97,108,42,48,46,53,32,43,32,48,46,53,44,32,48,46,48,41,59,13,10,9,114,101,116,117,114,110,32,118,101,99,52,40,118,101,99,50,40,97,116,97,110,40,110,111,114,109,97,108,46,121,44,32,110,111,114,109,97,108,46,120,41,47,107,80,73,44,32,110,111,114,109,97,108,46,122,41,44,32,48,46,48,44,32,48,46,48,41,59,13,10,125,13,10,13,10,118,111,105,100,32,109,97,105,110,40,41,13,10,123,13,10,9,118,101,99,52,32,100,105,102,102,117,115,101,67,111,108,111,114,32,61,32,77,97,116,101,114,105,97,108,68,105,102,102,117,115,101,32,42,32,118,67,111,108,111,114,59,13,10,13,10,35,105,102,32,65,85,84,79,95,84,69,88,67,79,79,82,68,83,13,10,9,118,101,99,50,32,116,101,120,67,111,111,114,100,32,61,32,103,108,95,70,114,97,103,67,111,111,114,100,46,120,121,32,42,32,73,110,118,84,97,114,103,101,116,83,105,122,101,59,13,10,35,101,108,115,101,13,10,9,118,101,99,50,32,116,101,120,67,111,111,114,100,32,61,32,118,84,101,120,67,111,111,114,100,59,13,10,35,101,110,100,105,102,13,10,13,10,35,105,102,32,76,73,71,72,84,73,78,71,32,38,38,32,80,65,82,65,76,76,65,88,95,77,65,80,80,73,78,71,13,10,9,102,108,111,97,116,32,104,101,105,103,104,116,32,61,32,116,101,120,116,117,114,101,40,77,97,116,101,114,105,97,108,72,101,105,103,104,116,77,97,112,44,32,116,101,120,67,111,111,114,100,41,46,114,59,13,10,9,102,108,111,97,116,32,118,32,61,32,104,101,105,103,104,116,42,80,97,114,97,108,108,97,120,83,99,97,108,101,32,43,32,80,97,114,97,108,108,97,120,66,105,97,115,59,13,10,13,10,9,118,101,99,51,32,118,105,101,119,68,105,114,32,61,32,110,111,114,109,97,108,105,122,101,40,118,86,105,101,119,68,105,114,41,59,13,10,9,116,101,120,67,111,111,114,100,32,43,61,32,118,32,42,32,118,105,101,119,68,105,114,46,120,121,59,13,10,35,101,110,100,105,102,13,10,13,10,35,105,102,32,68,73,70,70,85,83,69,95,77,65,80,80,73,78,71,13,10,9,100,105,102,102,117,115,101,67,111,108,111,114,32,42,61,32,116,101,120,116,117,114,101,40,77,97,116,101,114,105,97,108,68,105,102,102,117,115,101,77,97,112,44,32,116,101,120,67,111,111,114,100,41,59,13,10,35,101,110,100,105,102,13,10,13,10,35,105,102,32,70,76,65,71,95,84,69,88,84,85,82,69,79,86,69,82,76,65,89,13,10,9,100,105,102,102,117,115,101,67,111,108,111,114,32,42,61,32,116,101,120,116,117,114,101,40,84,101,120,116,117,114,101,79,118,101,114,108,97,121,44,32,116,101,120,67,111,111,114,100,41,59,13,10,35,101,110,100,105,102,13,10,13,10,35,105,102,32,70,76,65,71,95,68,69,70,69,82,82,69,68,13,10,9,35,105,102,32,65,76,80,72,65,95,84,69,83,84,13,10,9,9,47,47,32,73,110,117,116,105,108,101,32,100,101,32,102,97,105,114,101,32,100,101,32,108,39,97,108,112,104,97,45,109,97,112,112,105,110,103,32,115,97,110,115,32,97,108,112,104,97,45,116,101,115,116,32,101,110,32,68,101,102,101,114,114,101,100,32,40,108,39,97,108,112,104,97,32,110,39,101,115,116,32,112,97,115,32,115,97,117,118,101,103,97,114,100,195,169,32,100,97,110,115,32,108,101,32,71,45,66,117,102,102,101,114,41,13,10,9,9,35,105,102,32,65,76,80,72,65,95,77,65,80,80,73,78,71,13,10,9,100,105,102,102,117,115,101,67,111,108,111,114,46,97,32,42,61,32,116,101,120,116,117,114,101,40,77,97,116,101,114,105,97,108,65,108,112,104,97,77,97,112,44,32,116,101,120,67,111,111,114,100,41,46,114,59,13,10,9,9,35,101,110,100,105,102,13,10,9,9,13,10,9,105,102,32,40,100,105,102,102,117,115,101,67,111,108,111,114,46,97,32,60,32,77,97,116,101,114,105,97,108,65,108,112,104,97,84,104,114,101,115,104,111,108,100,41,13,10,9,9,100,105,115,99,97,114,100,59,13,10,9,35,101,110,100,105,102,32,47,47,32,65,76,80,72,65,95,84,69,83,84,13,10,13,10,9,35,105,102,32,76,73,71,72,84,73,78,71,13,10,9,9,35,105,102,32,78,79,82,77,65,76,95,77,65,80,80,73,78,71,13,10,9,118,101,99,51,32,110,111,114,109,97,108,32,61,32,110,111,114,109,97,108,105,122,101,40,118,76,105,103,104,116,84,111,87,111,114,108,100,32,42,32,40,50,46,48,32,42,32,118,101,99,51,40,116,101,120,116,117,114,101,40,77,97,116,101,114,105,97,108,78,111,114,109,97,108,77,97,112,44,32,116,101,120,67,111,111,114,100,41,41,32,45,32,49,46,48,41,41,59,13,10,9,9,35,101,108,115,101,13,10,9,118,101,99,51,32,110,111,114,109,97,108,32,61,32,110,111,114,109,97,108,105,122,101,40,118,78,111,114,109,97,108,41,59,13,10,9,9,35,101,110,100,105,102,32,47,47,32,78,79,82,77,65,76,95,77,65,80,80,73,78,71,13,10,13,10,9,118,101,99,51,32,115,112,101,99,117,108,97,114,67,111,108,111,114,32,61,32,77,97,116,101,114,105,97,108,83,112,101,99,117,108,97,114,46,114,103,98,59,13,10,9,9,35,105,102,32,83,80,69,67,85,76,65,82,95,77,65,80,80,73,78,71,13,10,9,115,112,101,99,117,108,97,114,67,111,108,111,114,32,42,61,32,116,101,120,116,117,114,101,40,77,97,116,101,114,105,97,108,83,112,101,99,117,108,97,114,77,97,112,44,32,116,101,120,67,111,111,114,100,41,46,114,103,98,59,13,10,9,9,35,101,110,100,105,102,13,10,13,10,9,47,42,13,10,9,84,101,120,116,117,114,101,48,58,32,68,105,102,102,117,115,101,32,67,111,108,111,114,32,43,32,83,112,101,99,117,108,97,114,13,10,9,84,101,120,116,117,114,101,49,58,32,78,111,114,109,97,108,32,43,32,83,112,101,99,117,108,97,114,13,10,9,84,101,120,116,117,114,101,50,58,32,69,110,99,111,100,101,100,32,100,101,112,116,104,32,43,32,83,104,105,110,105,110,101,115,115,13,10,9,42,47,13,10,9,82,101,110,100,101,114,84,97,114,103,101,116,48,32,61,32,118,101,99,52,40,100,105,102,102,117,115,101,67,111,108,111,114,46,114,103,98,44,32,100,111,116,40,115,112,101,99,117,108,97,114,67,111,108,111,114,44,32,118,101,99,51,40,48,46,51,44,32,48,46,53,57,44,32,48,46,49,49,41,41,41,59,13,10,9,82,101,110,100,101,114,84,97,114,103,101,116,49,32,61,32,118,101,99,52,40,69,110,99,111,100,101,78,111,114,109,97,108,40,110,111,114,109,97,108,41,41,59,13,10,9,82,101,110,100,101,114,84,97,114,103,101,116,50,32,61,32,118,101,99,52,40,70,108,111,97,116,84,111,67,111,108,111,114,40,103,108,95,70,114,97,103,67,111,111,114,100,46,122,41,44,32,40,77,97,116,101,114,105,97,108,83,104,105,110,105,110,101,115,115,32,61,61,32,48,46,48,41,32,63,32,48,46,48,32,58,32,109,97,120,40,108,111,103,50,40,77,97,116,101,114,105,97,108,83,104,105,110,105,110,101,115,115,41,44,32,48,46,49,41,47,49,48,46,53,41,59,32,47,47,32,104,116,116,112,58,47,47,119,119,119,46,103,117,101,114,114,105,108,108,97,45,103,97,109,101,115,46,99,111,109,47,112,117,98,108,105,99,97,116,105,111,110,115,47,100,114,95,107,122,50,95,114,115,120,95,100,101,118,48,55,46,112,100,102,13,10,9,35,101,108,115,101,32,47,47,32,76,73,71,72,84,73,78,71,13,10,9,82,101,110,100,101,114,84,97,114,103,101,116,48,32,61,32,118,101,99,52,40,100,105,102,102,117,115,101,67,111,108,111,114,46,114,103,98,44,32,48,46,48,41,59,13,10,9,35,101,110,100,105,102,13,10,35,101,108,115,101,32,47,47,32,70,76,65,71,95,68,69,70,69,82,82,69,68,13,10,9,35,105,102,32,65,76,80,72,65,95,77,65,80,80,73,78,71,13,10,9,100,105,102,102,117,115,101,67,111,108,111,114,46,97,32,42,61,32,116,101,120,116,117,114,101,40,77,97,116,101,114,105,97,108,65,108,112,104,97,77,97,112,44,32,116,101,120,67,111,111,114,100,41,46,114,59,13,10,9,35,101,110,100,105,102,13,10,13,10,9,35,105,102,32,65,76,80,72,65,95,84,69,83,84,13,10,9,105,102,32,40,100,105,102,102,117,115,101,67,111,108,111,114,46,97,32,60,32,77,97,116,101,114,105,97,108,65,108,112,104,97,84,104,114,101,115,104,111,108,100,41,13,10,9,9,100,105,115,99,97,114,100,59,13,10,9,35,101,110,100,105,102,13,10,13,10,9,35,105,102,32,76,73,71,72,84,73,78,71,13,10,9,118,101,99,51,32,108,105,103,104,116,65,109,98,105,101,110,116,32,61,32,118,101,99,51,40,48,46,48,41,59,13,10,9,118,101,99,51,32,108,105,103,104,116,68,105,102,102,117,115,101,32,61,32,118,101,99,51,40,48,46,48,41,59,13,10,9,118,101,99,51,32,108,105,103,104,116,83,112,101,99,117,108,97,114,32,61,32,118,101,99,51,40,48,46,48,41,59,13,10,13,10,9,9,35,105,102,32,78,79,82,77,65,76,95,77,65,80,80,73,78,71,13,10,9,118,101,99,51,32,110,111,114,109,97,108,32,61,32,110,111,114,109,97,108,105,122,101,40,118,76,105,103,104,116,84,111,87,111,114,108,100,32,42,32,40,50,46,48,32,42,32,118,101,99,51,40,116,101,120,116,117,114,101,40,77,97,116,101,114,105,97,108,78,111,114,109,97,108,77,97,112,44,32,116,101,120,67,111,111,114,100,41,41,32,45,32,49,46,48,41,41,59,13,10,9,9,35,101,108,115,101,13,10,9,118,101,99,51,32,110,111,114,109,97,108,32,61,32,110,111,114,109,97,108,105,122,101,40,118,78,111,114,109,97,108,41,59,13,10,9,9,35,101,110,100,105,102,13,10,13,10,9,105,102,32,40,77,97,116,101,114,105,97,108,83,104,105,110,105,110,101,115,115,32,62,32,48,46,48,41,13,10,9,123,13,10,9,9,118,101,99,51,32,101,121,101,86,101,99,32,61,32,110,111,114,109,97,108,105,122,101,40,69,121,101,80,111,115,105,116,105,111,110,32,45,32,118,87,111,114,108,100,80,111,115,41,59,13,10,13,10,9,9,102,111,114,32,40,105,110,116,32,105,32,61,32,48,59,32,105,32,60,32,51,59,32,43,43,105,41,13,10,9,9,123,13,10,9,9,9,115,119,105,116,99,104,32,40,76,105,103,104,116,115,91,105,93,46,116,121,112,101,41,13,10,9,9,9,123,13,10,9,9,9,9,99,97,115,101,32,76,73,71,72,84,95,68,73,82,69,67,84,73,79,78,65,76,58,13,10,9,9,9,9,123,13,10,9,9,9,9,9,118,101,99,51,32,108,105,103,104,116,68,105,114,32,61,32,45,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,49,46,120,121,122,59,13,10,13,10,9,9,9,9,9,47,47,32,65,109,98,105,101,110,116,13,10,9,9,9,9,9,108,105,103,104,116,65,109,98,105,101,110,116,32,43,61,32,76,105,103,104,116,115,91,105,93,46,99,111,108,111,114,46,114,103,98,32,42,32,76,105,103,104,116,115,91,105,93,46,102,97,99,116,111,114,115,46,120,32,42,32,40,77,97,116,101,114,105,97,108,65,109,98,105,101,110,116,46,114,103,98,32,43,32,83,99,101,110,101,65,109,98,105,101,110,116,46,114,103,98,41,59,13,10,13,10,9,9,9,9,9,47,47,32,68,105,102,102,117,115,101,13,10,9,9,9,9,9,102,108,111,97,116,32,108,97,109,98,101,114,116,32,61,32,109,97,120,40,100,111,116,40,110,111,114,109,97,108,44,32,108,105,103,104,116,68,105,114,41,44,32,48,46,48,41,59,13,10,13,10,9,9,9,9,9,108,105,103,104,116,68,105,102,102,117,115,101,32,43,61,32,108,97,109,98,101,114,116,32,42,32,76,105,103,104,116,115,91,105,93,46,99,111,108,111,114,46,114,103,98,32,42,32,76,105,103,104,116,115,91,105,93,46,102,97,99,116,111,114,115,46,121,59,13,10,13,10,9,9,9,9,9,47,47,32,83,112,101,99,117,108,97,114,13,10,9,9,9,9,9,118,101,99,51,32,114,101,102,108,101,99,116,105,111,110,32,61,32,114,101,102,108,101,99,116,40,45,108,105,103,104,116,68,105,114,44,32,110,111,114,109,97,108,41,59,13,10,9,9,9,9,9,102,108,111,97,116,32,115,112,101,99,117,108,97,114,70,97,99,116,111,114,32,61,32,109,97,120,40,100,111,116,40,114,101,102,108,101,99,116,105,111,110,44,32,101,121,101,86,101,99,41,44,32,48,46,48,41,59,13,10,9,9,9,9,9,115,112,101,99,117,108,97,114,70,97,99,116,111,114,32,61,32,112,111,119,40,115,112,101,99,117,108,97,114,70,97,99,116,111,114,44,32,77,97,116,101,114,105,97,108,83,104,105,110,105,110,101,115,115,41,59,13,10,13,10,9,9,9,9,9,108,105,103,104,116,83,112,101,99,117,108,97,114,32,43,61,32,115,112,101,99,117,108,97,114,70,97,99,116,111,114,32,42,32,76,105,103,104,116,115,91,105,93,46,99,111,108,111,114,46,114,103,98,59,13,10,9,9,9,9,9,98,114,101,97,107,59,13,10,9,9,9,9,125,13,10,13,10,9,9,9,9,99,97,115,101,32,76,73,71,72,84,95,80,79,73,78,84,58,13,10,9,9,9,9,123,13,10,9,9,9,9,9,118,101,99,51,32,108,105,103,104,116,68,105,114,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,49,46,120,121,122,32,45,32,118,87,111,114,108,100,80,111,115,59,13,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,68,105,114,76,101,110,103,116,104,32,61,32,108,101,110,103,116,104,40,108,105,103,104,116,68,105,114,41,59,13,10,9,9,9,9,9,108,105,103,104,116,68,105,114,32,47,61,32,108,105,103,104,116,68,105,114,76,101,110,103,116,104,59,32,47,47,32,78,111,114,109,97,108,105,115,97,116,105,111,110,13,10,9,9,9,9,9,13,10,9,9,9,9,9,102,108,111,97,116,32,97,116,116,32,61,32,109,97,120,40,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,49,46,119,32,45,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,50,46,119,42,108,105,103,104,116,68,105,114,76,101,110,103,116,104,44,32,48,46,48,41,59,13,10,13,10,9,9,9,9,9,47,47,32,65,109,98,105,101,110,116,13,10,9,9,9,9,9,108,105,103,104,116,65,109,98,105,101,110,116,32,43,61,32,97,116,116,32,42,32,76,105,103,104,116,115,91,105,93,46,99,111,108,111,114,46,114,103,98,32,42,32,76,105,103,104,116,115,91,105,93,46,102,97,99,116,111,114,115,46,120,32,42,32,40,77,97,116,101,114,105,97,108,65,109,98,105,101,110,116,46,114,103,98,32,43,32,83,99,101,110,101,65,109,98,105,101,110,116,46,114,103,98,41,59,13,10,13,10,9,9,9,9,9,47,47,32,68,105,102,102,117,115,101,13,10,9,9,9,9,9,102,108,111,97,116,32,108,97,109,98,101,114,116,32,61,32,109,97,120,40,100,111,116,40,110,111,114,109,97,108,44,32,108,105,103,104,116,68,105,114,41,44,32,48,46,48,41,59,13,10,9,9,9,9,9,13,10,9,9,9,9,9,108,105,103,104,116,68,105,102,102,117,115,101,32,43,61,32,97,116,116,32,42,32,108,97,109,98,101,114,116,32,42,32,76,105,103,104,116,115,91,105,93,46,99,111,108,111,114,46,114,103,98,32,42,32,76,105,103,104,116,115,91,105,93,46,102,97,99,116,111,114,115,46,121,59,13,10,13,10,9,9,9,9,9,47,47,32,83,112,101,99,117,108,97,114,13,10,9,9,9,9,9,118,101,99,51,32,114,101,102,108,101,99,116,105,111,110,32,61,32,114,101,102,108,101,99,116,40,45,108,105,103,104,116,68,105,114,44,32,110,111,114,109,97,108,41,59,13,10,9,9,9,9,9,102,108,111,97,116,32,115,112,101,99,117,108,97,114,70,97,99,116,111,114,32,61,32,109,97,120,40,100,111,116,40,114,101,102,108,101,99,116,105,111,110,44,32,101,121,101,86,101,99,41,44,32,48,46,48,41,59,13,10,9,9,9,9,9,115,112,101,99,117,108,97,114,70,97,99,116,111,114,32,61,32,112,111,119,40,115,112,101,99,117,108,97,114,70,97,99,116,111,114,44,32,77,97,116,101,114,105,97,108,83,104,105,110,105,110,101,115,115,41,59,13,10,13,10,9,9,9,9,9,108,105,103,104,116,83,112,101,99,117,108,97,114,32,43,61,32,97,116,116,32,42,32,115,112,101,99,117,108,97,114,70,97,99,116,111,114,32,42,32,76,105,103,104,116,115,91,105,93,46,99,111,108,111,114,46,114,103,98,59,13,10,9,9,9,9,9,98,114,101,97,107,59,13,10,9,9,9,9,125,13,10,13,10,9,9,9,9,99,97,115,101,32,76,73,71,72,84,95,83,80,79,84,58,13,10,9,9,9,9,123,13,10,9,9,9,9,9,118,101,99,51,32,108,105,103,104,116,68,105,114,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,49,46,120,121,122,32,45,32,118,87,111,114,108,100,80,111,115,59,13,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,68,105,114,76,101,110,103,116,104,32,61,32,108,101,110,103,116,104,40,108,105,103,104,116,68,105,114,41,59,13,10,9,9,9,9,9,108,105,103,104,116,68,105,114,32,47,61,32,108,105,103,104,116,68,105,114,76,101,110,103,116,104,59,32,47,47,32,78,111,114,109,97,108,105,115,97,116,105,111,110,13,10,9,9,9,9,9,13,10,9,9,9,9,9,102,108,111,97,116,32,97,116,116,32,61,32,109,97,120,40,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,49,46,119,32,45,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,50,46,119,42,108,105,103,104,116,68,105,114,76,101,110,103,116,104,44,32,48,46,48,41,59,13,10,13,10,9,9,9,9,9,47,47,32,65,109,98,105,101,110,116,13,10,9,9,9,9,9,108,105,103,104,116,65,109,98,105,101,110,116,32,43,61,32,97,116,116,32,42,32,76,105,103,104,116,115,91,105,93,46,99,111,108,111,114,46,114,103,98,32,42,32,76,105,103,104,116,115,91,105,93,46,102,97,99,116,111,114,115,46,120,32,42,32,40,77,97,116,101,114,105,97,108,65,109,98,105,101,110,116,46,114,103,98,32,43,32,83,99,101,110,101,65,109,98,105,101,110,116,46,114,103,98,41,59,13,10,13,10,9,9,9,9,9,47,47,32,77,111,100,105,102,105,99,97,116,105,111,110,32,100,101,32,108,39,97,116,116,195,169,110,117,97,116,105,111,110,32,112,111,117,114,32,103,195,169,114,101,114,32,108,101,32,115,112,111,116,13,10,9,9,9,9,9,102,108,111,97,116,32,99,117,114,65,110,103,108,101,32,61,32,100,111,116,40,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,50,46,120,121,122,44,32,45,108,105,103,104,116,68,105,114,41,59,13,10,9,9,9,9,9,102,108,111,97,116,32,111,117,116,101,114,65,110,103,108,101,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,51,46,121,59,13,10,9,9,9,9,9,102,108,111,97,116,32,105,110,110,101,114,77,105,110,117,115,79,117,116,101,114,65,110,103,108,101,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,51,46,120,32,45,32,111,117,116,101,114,65,110,103,108,101,59,13,10,9,9,9,9,9,97,116,116,32,42,61,32,109,97,120,40,40,99,117,114,65,110,103,108,101,32,45,32,111,117,116,101,114,65,110,103,108,101,41,32,47,32,105,110,110,101,114,77,105,110,117,115,79,117,116,101,114,65,110,103,108,101,44,32,48,46,48,41,59,13,10,13,10,9,9,9,9,9,47,47,32,68,105,102,102,117,115,101,13,10,9,9,9,9,9,102,108,111,97,116,32,108,97,109,98,101,114,116,32,61,32,109,97,120,40,100,111,116,40,110,111,114,109,97,108,44,32,108,105,103,104,116,68,105,114,41,44,32,48,46,48,41,59,13,10,13,10,9,9,9,9,9,108,105,103,104,116,68,105,102,102,117,115,101,32,43,61,32,97,116,116,32,42,32,108,97,109,98,101,114,116,32,42,32,76,105,103,104,116,115,91,105,93,46,99,111,108,111,114,46,114,103,98,32,42,32,76,105,103,104,116,115,91,105,93,46,102,97,99,116,111,114,115,46,121,59,13,10,13,10,9,9,9,9,9,47,47,32,83,112,101,99,117,108,97,114,13,10,9,9,9,9,9,118,101,99,51,32,114,101,102,108,101,99,116,105,111,110,32,61,32,114,101,102,108,101,99,116,40,45,108,105,103,104,116,68,105,114,44,32,110,111,114,109,97,108,41,59,13,10,9,9,9,9,9,102,108,111,97,116,32,115,112,101,99,117,108,97,114,70,97,99,116,111,114,32,61,32,109,97,120,40,100,111,116,40,114,101,102,108,101,99,116,105,111,110,44,32,101,121,101,86,101,99,41,44,32,48,46,48,41,59,13,10,9,9,9,9,9,115,112,101,99,117,108,97,114,70,97,99,116,111,114,32,61,32,112,111,119,40,115,112,101,99,117,108,97,114,70,97,99,116,111,114,44,32,77,97,116,101,114,105,97,108,83,104,105,110,105,110,101,115,115,41,59,13,10,13,10,9,9,9,9,9,108,105,103,104,116,83,112,101,99,117,108,97,114,32,43,61,32,97,116,116,32,42,32,115,112,101,99,117,108,97,114,70,97,99,116,111,114,32,42,32,76,105,103,104,116,115,91,105,93,46,99,111,108,111,114,46,114,103,98,59,13,10,9,9,9,9,9,98,114,101,97,107,59,13,10,9,9,9,9,125,13,10,9,9,9,9,13,10,9,9,9,9,100,101,102,97,117,108,116,58,13,10,9,9,9,9,9,98,114,101,97,107,59,13,10,9,9,9,125,13,10,9,9,125,13,10,9,125,13,10,9,101,108,115,101,13,10,9,123,13,10,9,9,102,111,114,32,40,105,110,116,32,105,32,61,32,48,59,32,105,32,60,32,51,59,32,43,43,105,41,13,10,9,9,123,13,10,9,9,9,115,119,105,116,99,104,32,40,76,105,103,104,116,115,91,105,93,46,116,121,112,101,41,13,10,9,9,9,123,13,10,9,9,9,9,99,97,115,101,32,76,73,71,72,84,95,68,73,82,69,67,84,73,79,78,65,76,58,13,10,9,9,9,9,123,13,10,9,9,9,9,9,118,101,99,51,32,108,105,103,104,116,68,105,114,32,61,32,110,111,114,109,97,108,105,122,101,40,45,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,49,46,120,121,122,41,59,13,10,13,10,9,9,9,9,9,47,47,32,65,109,98,105,101,110,116,13,10,9,9,9,9,9,108,105,103,104,116,65,109,98,105,101,110,116,32,43,61,32,76,105,103,104,116,115,91,105,93,46,99,111,108,111,114,46,114,103,98,32,42,32,76,105,103,104,116,115,91,105,93,46,102,97,99,116,111,114,115,46,120,32,42,32,40,77,97,116,101,114,105,97,108,65,109,98,105,101,110,116,46,114,103,98,32,43,32,83,99,101,110,101,65,109,98,105,101,110,116,46,114,103,98,41,59,13,10,13,10,9,9,9,9,9,47,47,32,68,105,102,102,117,115,101,13,10,9,9,9,9,9,102,108,111,97,116,32,108,97,109,98,101,114,116,32,61,32,109,97,120,40,100,111,116,40,110,111,114,109,97,108,44,32,108,105,103,104,116,68,105,114,41,44,32,48,46,48,41,59,13,10,13,10,9,9,9,9,9,108,105,103,104,116,68,105,102,102,117,115,101,32,43,61,32,108,97,109,98,101,114,116,32,42,32,76,105,103,104,116,115,91,105,93,46,99,111,108,111,114,46,114,103,98,32,42,32,76,105,103,104,116,115,91,105,93,46,102,97,99,116,111,114,115,46,121,59,13,10,9,9,9,9,9,98,114,101,97,107,59,13,10,9,9,9,9,125,13,10,13,10,9,9,9,9,99,97,115,101,32,76,73,71,72,84,95,80,79,73,78,84,58,13,10,9,9,9,9,123,13,10,9,9,9,9,9,118,101,99,51,32,108,105,103,104,116,68,105,114,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,49,46,120,121,122,32,45,32,118,87,111,114,108,100,80,111,115,59,13,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,68,105,114,76,101,110,103,116,104,32,61,32,108,101,110,103,116,104,40,108,105,103,104,116,68,105,114,41,59,13,10,9,9,9,9,9,108,105,103,104,116,68,105,114,32,47,61,32,108,105,103,104,116,68,105,114,76,101,110,103,116,104,59,32,47,47,32,78,111,114,109,97,108,105,115,97,116,105,111,110,13,10,9,9,9,9,9,13,10,9,9,9,9,9,102,108,111,97,116,32,97,116,116,32,61,32,109,97,120,40,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,49,46,119,32,45,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,50,46,119,42,108,105,103,104,116,68,105,114,76,101,110,103,116,104,44,32,48,46,48,41,59,13,10,13,10,9,9,9,9,9,47,47,32,65,109,98,105,101,110,116,13,10,9,9,9,9,9,108,105,103,104,116,65,109,98,105,101,110,116,32,43,61,32,97,116,116,32,42,32,76,105,103,104,116,115,91,105,93,46,99,111,108,111,114,46,114,103,98,32,42,32,76,105,103,104,116,115,91,105,93,46,102,97,99,116,111,114,115,46,120,32,42,32,40,77,97,116,101,114,105,97,108,65,109,98,105,101,110,116,46,114,103,98,32,43,32,83,99,101,110,101,65,109,98,105,101,110,116,46,114,103,98,41,59,13,10,13,10,9,9,9,9,9,47,47,32,68,105,102,102,117,115,101,13,10,9,9,9,9,9,102,108,111,97,116,32,108,97,109,98,101,114,116,32,61,32,109,97,120,40,100,111,116,40,110,111,114,109,97,108,44,32,108,105,103,104,116,68,105,114,41,44,32,48,46,48,41,59,13,10,9,9,9,9,9,13,10,9,9,9,9,9,108,105,103,104,116,68,105,102,102,117,115,101,32,43,61,32,97,116,116,32,42,32,108,97,109,98,101,114,116,32,42,32,76,105,103,104,116,115,91,105,93,46,99,111,108,111,114,46,114,103,98,32,42,32,76,105,103,104,116,115,91,105,93,46,102,97,99,116,111,114,115,46,121,59,13,10,9,9,9,9,9,98,114,101,97,107,59,13,10,9,9,9,9,125,13,10,13,10,9,9,9,9,99,97,115,101,32,76,73,71,72,84,95,83,80,79,84,58,13,10,9,9,9,9,123,13,10,9,9,9,9,9,118,101,99,51,32,108,105,103,104,116,68,105,114,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,49,46,120,121,122,32,45,32,118,87,111,114,108,100,80,111,115,59,13,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,68,105,114,76,101,110,103,116,104,32,61,32,108,101,110,103,116,104,40,108,105,103,104,116,68,105,114,41,59,13,10,9,9,9,9,9,108,105,103,104,116,68,105,114,32,47,61,32,108,105,103,104,116,68,105,114,76,101,110,103,116,104,59,32,47,47,32,78,111,114,109,97,108,105,115,97,116,105,111,110,13,10,9,9,9,9,9,13,10,9,9,9,9,9,102,108,111,97,116,32,97,116,116,32,61,32,109,97,120,40,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,49,46,119,32,45,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,50,46,119,42,108,105,103,104,116,68,105,114,76,101,110,103,116,104,44,32,48,46,48,41,59,13,10,13,10,9,9,9,9,9,47,47,32,65,109,98,105,101,110,116,13,10,9,9,9,9,9,108,105,103,104,116,65,109,98,105,101,110,116,32,43,61,32,97,116,116,32,42,32,76,105,103,104,116,115,91,105,93,46,99,111,108,111,114,46,114,103,98,32,42,32,76,105,103,104,116,115,91,105,93,46,102,97,99,116,111,114,115,46,120,32,42,32,40,77,97,116,101,114,105,97,108,65,109,98,105,101,110,116,46,114,103,98,32,43,32,83,99,101,110,101,65,109,98,105,101,110,116,46,114,103,98,41,59,13,10,13,10,9,9,9,9,9,47,47,32,77,111,100,105,102,105,99,97,116,105,111,110,32,100,101,32,108,39,97,116,116,195,169,110,117,97,116,105,111,110,32,112,111,117,114,32,103,195,169,114,101,114,32,108,101,32,115,112,111,116,13,10,9,9,9,9,9,102,108,111,97,116,32,99,117,114,65,110,103,108,101,32,61,32,100,111,116,40,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,50,46,120,121,122,44,32,45,108,105,103,104,116,68,105,114,41,59,13,10,9,9,9,9,9,102,108,111,97,116,32,111,117,116,101,114,65,110,103,108,101,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,51,46,121,59,13,10,9,9,9,9,9,102,108,111,97,116,32,105,110,110,101,114,77,105,110,117,115,79,117,116,101,114,65,110,103,108,101,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,51,46,120,32,45,32,111,117,116,101,114,65,110,103,108,101,59,13,10,9,9,9,9,9,97,116,116,32,42,61,32,109,97,120,40,40,99,117,114,65,110,103,108,101,32,45,32,111,117,116,101,114,65,110,103,108,101,41,32,47,32,105,110,110,101,114,77,105,110,117,115,79,117,116,101,114,65,110,103,108,101,44,32,48,46,48,41,59,13,10,13,10,9,9,9,9,9,47,47,32,68,105,102,102,117,115,101,13,10,9,9,9,9,9,102,108,111,97,116,32,108,97,109,98,101,114,116,32,61,32,109,97,120,40,100,111,116,40,110,111,114,109,97,108,44,32,108,105,103,104,116,68,105,114,41,44,32,48,46,48,41,59,13,10,13,10,9,9,9,9,9,108,105,103,104,116,68,105,102,102,117,115,101,32,43,61,32,97,116,116,32,42,32,108,97,109,98,101,114,116,32,42,32,76,105,103,104,116,115,91,105,93,46,99,111,108,111,114,46,114,103,98,32,42,32,76,105,103,104,116,115,91,105,93,46,102,97,99,116,111,114,115,46,121,59,13,10,9,9,9,9,125,13,10,9,9,9,9,13,10,9,9,9,9,100,101,102,97,117,108,116,58,13,10,9,9,9,9,9,98,114,101,97,107,59,13,10,9,9,9,125,13,10,9,9,125,13,10,9,125,13,10,13,10,9,108,105,103,104,116,83,112,101,99,117,108,97,114,32,42,61,32,77,97,116,101,114,105,97,108,83,112,101,99,117,108,97,114,46,114,103,98,59,13,10,9,9,35,105,102,32,83,80,69,67,85,76,65,82,95,77,65,80,80,73,78,71,13,10,9,108,105,103,104,116,83,112,101,99,117,108,97,114,32,42,61,32,116,101,120,116,117,114,101,40,77,97,116,101,114,105,97,108,83,112,101,99,117,108,97,114,77,97,112,44,32,116,101,120,67,111,111,114,100,41,46,114,103,98,59,32,47,47,32,85,116,105,108,105,115,101,114,32,108,39,97,108,112,104,97,32,100,101,32,77,97,116,101,114,105,97,108,83,112,101,99,117,108,97,114,32,110,39,97,117,114,97,105,116,32,97,117,99,117,110,32,115,101,110,115,13,10,9,9,35,101,110,100,105,102,13,10,9,9,13,10,9,118,101,99,51,32,108,105,103,104,116,67,111,108,111,114,32,61,32,40,108,105,103,104,116,65,109,98,105,101,110,116,32,43,32,108,105,103,104,116,68,105,102,102,117,115,101,32,43,32,108,105,103,104,116,83,112,101,99,117,108,97,114,41,59,13,10,9,118,101,99,52,32,102,114,97,103,109,101,110,116,67,111,108,111,114,32,61,32,118,101,99,52,40,108,105,103,104,116,67,111,108,111,114,44,32,49,46,48,41,32,42,32,100,105,102,102,117,115,101,67,111,108,111,114,59,13,10,13,10,9,9,35,105,102,32,69,77,73,83,83,73,86,69,95,77,65,80,80,73,78,71,13,10,9,102,108,111,97,116,32,108,105,103,104,116,73,110,116,101,110,115,105,116,121,32,61,32,100,111,116,40,108,105,103,104,116,67,111,108,111,114,44,32,118,101,99,51,40,48,46,51,44,32,48,46,53,57,44,32,48,46,49,49,41,41,59,13,10,13,10,9,118,101,99,51,32,101,109,105,115,115,105,111,110,67,111,108,111,114,32,61,32,77,97,116,101,114,105,97,108,68,105,102,102,117,115,101,46,114,103,98,32,42,32,116,101,120,116,117,114,101,40,77,97,116,101,114,105,97,108,69,109,105,115,115,105,118,101,77,97,112,44,32,116,101,120,67,111,111,114,100,41,46,114,103,98,59,13,10,9,82,101,110,100,101,114,84,97,114,103,101,116,48,32,61,32,118,101,99,52,40,109,105,120,40,102,114,97,103,109,101,110,116,67,111,108,111,114,46,114,103,98,44,32,101,109,105,115,115,105,111,110,67,111,108,111,114,44,32,99,108,97,109,112,40,49,46,48,32,45,32,51,46,48,42,108,105,103,104,116,73,110,116,101,110,115,105,116,121,44,32,48,46,48,44,32,49,46,48,41,41,44,32,102,114,97,103,109,101,110,116,67,111,108,111,114,46,97,41,59,13,10,9,9,35,101,108,115,101,13,10,9,82,101,110,100,101,114,84,97,114,103,101,116,48,32,61,32,102,114,97,103,109,101,110,116,67,111,108,111,114,59,13,10,9,9,35,101,110,100,105,102,32,47,47,32,69,77,73,83,83,73,86,69,95,77,65,80,80,73,78,71,13,10,9,35,101,108,115,101,13,10,9,82,101,110,100,101,114,84,97,114,103,101,116,48,32,61,32,100,105,102,102,117,115,101,67,111,108,111,114,59,13,10,9,35,101,110,100,105,102,32,47,47,32,76,73,71,72,84,73,78,71,13,10,35,101,110,100,105,102,32,47,47,32,70,76,65,71,95,68,69,70,69,82,82,69,68,13,10,125,13,10, \ No newline at end of file +35,105,102,32,69,65,82,76,89,95,70,82,65,71,77,69,78,84,95,84,69,83,84,83,32,38,38,32,33,65,76,80,72,65,95,84,69,83,84,13,10,108,97,121,111,117,116,40,101,97,114,108,121,95,102,114,97,103,109,101,110,116,95,116,101,115,116,115,41,32,105,110,59,13,10,35,101,110,100,105,102,13,10,13,10,35,100,101,102,105,110,101,32,76,73,71,72,84,95,68,73,82,69,67,84,73,79,78,65,76,32,48,13,10,35,100,101,102,105,110,101,32,76,73,71,72,84,95,80,79,73,78,84,32,49,13,10,35,100,101,102,105,110,101,32,76,73,71,72,84,95,83,80,79,84,32,50,13,10,13,10,47,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,69,110,116,114,97,110,116,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,47,13,10,105,110,32,118,101,99,52,32,118,67,111,108,111,114,59,13,10,105,110,32,118,101,99,52,32,118,76,105,103,104,116,83,112,97,99,101,80,111,115,91,51,93,59,13,10,105,110,32,109,97,116,51,32,118,76,105,103,104,116,84,111,87,111,114,108,100,59,13,10,105,110,32,118,101,99,51,32,118,78,111,114,109,97,108,59,13,10,105,110,32,118,101,99,50,32,118,84,101,120,67,111,111,114,100,59,13,10,105,110,32,118,101,99,51,32,118,86,105,101,119,68,105,114,59,13,10,105,110,32,118,101,99,51,32,118,87,111,114,108,100,80,111,115,59,13,10,13,10,47,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,83,111,114,116,97,110,116,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,47,13,10,111,117,116,32,118,101,99,52,32,82,101,110,100,101,114,84,97,114,103,101,116,48,59,13,10,111,117,116,32,118,101,99,52,32,82,101,110,100,101,114,84,97,114,103,101,116,49,59,13,10,111,117,116,32,118,101,99,52,32,82,101,110,100,101,114,84,97,114,103,101,116,50,59,13,10,13,10,47,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,85,110,105,102,111,114,109,101,115,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,47,13,10,115,116,114,117,99,116,32,76,105,103,104,116,13,10,123,13,10,9,105,110,116,32,116,121,112,101,59,13,10,9,118,101,99,52,32,99,111,108,111,114,59,13,10,9,118,101,99,50,32,102,97,99,116,111,114,115,59,13,10,13,10,9,118,101,99,52,32,112,97,114,97,109,101,116,101,114,115,49,59,13,10,9,118,101,99,52,32,112,97,114,97,109,101,116,101,114,115,50,59,13,10,9,118,101,99,50,32,112,97,114,97,109,101,116,101,114,115,51,59,13,10,9,98,111,111,108,32,115,104,97,100,111,119,77,97,112,112,105,110,103,59,13,10,125,59,13,10,13,10,47,47,32,76,117,109,105,195,168,114,101,115,13,10,117,110,105,102,111,114,109,32,76,105,103,104,116,32,76,105,103,104,116,115,91,51,93,59,13,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,67,117,98,101,32,80,111,105,110,116,76,105,103,104,116,83,104,97,100,111,119,77,97,112,91,51,93,59,13,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,83,112,111,116,76,105,103,104,116,83,104,97,100,111,119,77,97,112,91,51,93,59,13,10,13,10,47,47,32,77,97,116,195,169,114,105,97,117,13,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,77,97,116,101,114,105,97,108,65,108,112,104,97,77,97,112,59,13,10,117,110,105,102,111,114,109,32,102,108,111,97,116,32,77,97,116,101,114,105,97,108,65,108,112,104,97,84,104,114,101,115,104,111,108,100,59,13,10,117,110,105,102,111,114,109,32,118,101,99,52,32,77,97,116,101,114,105,97,108,65,109,98,105,101,110,116,59,13,10,117,110,105,102,111,114,109,32,118,101,99,52,32,77,97,116,101,114,105,97,108,68,105,102,102,117,115,101,59,13,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,77,97,116,101,114,105,97,108,68,105,102,102,117,115,101,77,97,112,59,13,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,77,97,116,101,114,105,97,108,69,109,105,115,115,105,118,101,77,97,112,59,13,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,77,97,116,101,114,105,97,108,72,101,105,103,104,116,77,97,112,59,13,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,77,97,116,101,114,105,97,108,78,111,114,109,97,108,77,97,112,59,13,10,117,110,105,102,111,114,109,32,102,108,111,97,116,32,77,97,116,101,114,105,97,108,83,104,105,110,105,110,101,115,115,59,13,10,117,110,105,102,111,114,109,32,118,101,99,52,32,77,97,116,101,114,105,97,108,83,112,101,99,117,108,97,114,59,13,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,77,97,116,101,114,105,97,108,83,112,101,99,117,108,97,114,77,97,112,59,13,10,13,10,47,47,32,65,117,116,114,101,115,13,10,117,110,105,102,111,114,109,32,102,108,111,97,116,32,80,97,114,97,108,108,97,120,66,105,97,115,32,61,32,45,48,46,48,51,59,13,10,117,110,105,102,111,114,109,32,102,108,111,97,116,32,80,97,114,97,108,108,97,120,83,99,97,108,101,32,61,32,48,46,48,50,59,13,10,117,110,105,102,111,114,109,32,118,101,99,50,32,73,110,118,84,97,114,103,101,116,83,105,122,101,59,13,10,117,110,105,102,111,114,109,32,118,101,99,51,32,69,121,101,80,111,115,105,116,105,111,110,59,13,10,117,110,105,102,111,114,109,32,118,101,99,52,32,83,99,101,110,101,65,109,98,105,101,110,116,59,13,10,13,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,84,101,120,116,117,114,101,79,118,101,114,108,97,121,59,13,10,13,10,47,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,70,111,110,99,116,105,111,110,115,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,47,13,10,118,101,99,51,32,70,108,111,97,116,84,111,67,111,108,111,114,40,102,108,111,97,116,32,102,41,13,10,123,13,10,9,118,101,99,51,32,99,111,108,111,114,59,13,10,13,10,9,102,32,42,61,32,50,53,54,46,48,59,13,10,9,99,111,108,111,114,46,120,32,61,32,102,108,111,111,114,40,102,41,59,13,10,13,10,9,102,32,61,32,40,102,32,45,32,99,111,108,111,114,46,120,41,32,42,32,50,53,54,46,48,59,13,10,9,99,111,108,111,114,46,121,32,61,32,102,108,111,111,114,40,102,41,59,13,10,13,10,9,99,111,108,111,114,46,122,32,61,32,102,32,45,32,99,111,108,111,114,46,121,59,13,10,9,99,111,108,111,114,46,120,121,32,42,61,32,48,46,48,48,51,57,48,54,50,53,59,32,47,47,32,42,61,32,49,46,48,47,50,53,54,13,10,13,10,9,114,101,116,117,114,110,32,99,111,108,111,114,59,13,10,125,13,10,13,10,35,100,101,102,105,110,101,32,107,80,73,32,51,46,49,52,49,53,57,50,54,53,51,54,13,10,13,10,118,101,99,52,32,69,110,99,111,100,101,78,111,114,109,97,108,40,105,110,32,118,101,99,51,32,110,111,114,109,97,108,41,13,10,123,13,10,9,47,47,114,101,116,117,114,110,32,118,101,99,52,40,110,111,114,109,97,108,42,48,46,53,32,43,32,48,46,53,44,32,48,46,48,41,59,13,10,9,114,101,116,117,114,110,32,118,101,99,52,40,118,101,99,50,40,97,116,97,110,40,110,111,114,109,97,108,46,121,44,32,110,111,114,109,97,108,46,120,41,47,107,80,73,44,32,110,111,114,109,97,108,46,122,41,44,32,48,46,48,44,32,48,46,48,41,59,13,10,125,13,10,13,10,102,108,111,97,116,32,86,101,99,116,111,114,84,111,68,101,112,116,104,86,97,108,117,101,40,118,101,99,51,32,118,101,99,44,32,102,108,111,97,116,32,122,78,101,97,114,44,32,102,108,111,97,116,32,122,70,97,114,41,13,10,123,13,10,32,32,32,32,118,101,99,51,32,97,98,115,86,101,99,32,61,32,97,98,115,40,118,101,99,41,59,13,10,32,32,32,32,102,108,111,97,116,32,108,111,99,97,108,90,32,61,32,109,97,120,40,97,98,115,86,101,99,46,120,44,32,109,97,120,40,97,98,115,86,101,99,46,121,44,32,97,98,115,86,101,99,46,122,41,41,59,13,10,13,10,9,102,108,111,97,116,32,110,111,114,109,90,32,61,32,40,40,122,70,97,114,32,43,32,122,78,101,97,114,41,32,42,32,108,111,99,97,108,90,32,45,32,40,50,46,48,42,122,70,97,114,42,122,78,101,97,114,41,41,32,47,32,40,40,122,70,97,114,32,45,32,122,78,101,97,114,41,42,108,111,99,97,108,90,41,59,13,10,9,114,101,116,117,114,110,32,40,110,111,114,109,90,32,43,32,49,46,48,41,32,42,32,48,46,53,59,13,10,125,13,10,13,10,98,111,111,108,32,84,101,115,116,83,104,97,100,111,119,68,105,114,101,99,116,105,111,110,97,108,40,41,13,10,123,13,10,9,47,47,47,84,79,68,79,13,10,9,114,101,116,117,114,110,32,116,114,117,101,59,13,10,125,13,10,13,10,98,111,111,108,32,84,101,115,116,83,104,97,100,111,119,80,111,105,110,116,40,105,110,116,32,108,105,103,104,116,73,110,100,101,120,44,32,118,101,99,51,32,108,105,103,104,116,84,111,87,111,114,108,100,44,32,102,108,111,97,116,32,122,78,101,97,114,44,32,102,108,111,97,116,32,122,70,97,114,41,13,10,123,13,10,9,114,101,116,117,114,110,32,116,101,120,116,117,114,101,40,80,111,105,110,116,76,105,103,104,116,83,104,97,100,111,119,77,97,112,91,108,105,103,104,116,73,110,100,101,120,93,44,32,118,101,99,51,40,108,105,103,104,116,84,111,87,111,114,108,100,46,120,44,32,45,108,105,103,104,116,84,111,87,111,114,108,100,46,121,44,32,45,108,105,103,104,116,84,111,87,111,114,108,100,46,122,41,41,46,120,32,62,61,32,86,101,99,116,111,114,84,111,68,101,112,116,104,86,97,108,117,101,40,108,105,103,104,116,84,111,87,111,114,108,100,44,32,122,78,101,97,114,44,32,122,70,97,114,41,59,13,10,125,13,10,13,10,98,111,111,108,32,84,101,115,116,83,104,97,100,111,119,83,112,111,116,40,105,110,116,32,108,105,103,104,116,73,110,100,101,120,41,13,10,123,13,10,9,118,101,99,52,32,108,105,103,104,116,83,112,97,99,101,80,111,115,32,61,32,118,76,105,103,104,116,83,112,97,99,101,80,111,115,91,108,105,103,104,116,73,110,100,101,120,93,59,13,10,9,114,101,116,117,114,110,32,116,101,120,116,117,114,101,80,114,111,106,40,83,112,111,116,76,105,103,104,116,83,104,97,100,111,119,77,97,112,91,108,105,103,104,116,73,110,100,101,120,93,44,32,108,105,103,104,116,83,112,97,99,101,80,111,115,46,120,121,119,41,46,120,32,62,61,32,40,108,105,103,104,116,83,112,97,99,101,80,111,115,46,122,32,45,32,48,46,48,48,48,53,41,47,108,105,103,104,116,83,112,97,99,101,80,111,115,46,119,59,13,10,125,13,10,13,10,118,111,105,100,32,109,97,105,110,40,41,13,10,123,13,10,9,118,101,99,52,32,100,105,102,102,117,115,101,67,111,108,111,114,32,61,32,77,97,116,101,114,105,97,108,68,105,102,102,117,115,101,32,42,32,118,67,111,108,111,114,59,13,10,13,10,35,105,102,32,65,85,84,79,95,84,69,88,67,79,79,82,68,83,13,10,9,118,101,99,50,32,116,101,120,67,111,111,114,100,32,61,32,103,108,95,70,114,97,103,67,111,111,114,100,46,120,121,32,42,32,73,110,118,84,97,114,103,101,116,83,105,122,101,59,13,10,35,101,108,115,101,13,10,9,118,101,99,50,32,116,101,120,67,111,111,114,100,32,61,32,118,84,101,120,67,111,111,114,100,59,13,10,35,101,110,100,105,102,13,10,13,10,35,105,102,32,76,73,71,72,84,73,78,71,32,38,38,32,80,65,82,65,76,76,65,88,95,77,65,80,80,73,78,71,13,10,9,102,108,111,97,116,32,104,101,105,103,104,116,32,61,32,116,101,120,116,117,114,101,40,77,97,116,101,114,105,97,108,72,101,105,103,104,116,77,97,112,44,32,116,101,120,67,111,111,114,100,41,46,114,59,13,10,9,102,108,111,97,116,32,118,32,61,32,104,101,105,103,104,116,42,80,97,114,97,108,108,97,120,83,99,97,108,101,32,43,32,80,97,114,97,108,108,97,120,66,105,97,115,59,13,10,13,10,9,118,101,99,51,32,118,105,101,119,68,105,114,32,61,32,110,111,114,109,97,108,105,122,101,40,118,86,105,101,119,68,105,114,41,59,13,10,9,116,101,120,67,111,111,114,100,32,43,61,32,118,32,42,32,118,105,101,119,68,105,114,46,120,121,59,13,10,35,101,110,100,105,102,13,10,13,10,35,105,102,32,68,73,70,70,85,83,69,95,77,65,80,80,73,78,71,13,10,9,100,105,102,102,117,115,101,67,111,108,111,114,32,42,61,32,116,101,120,116,117,114,101,40,77,97,116,101,114,105,97,108,68,105,102,102,117,115,101,77,97,112,44,32,116,101,120,67,111,111,114,100,41,59,13,10,35,101,110,100,105,102,13,10,13,10,35,105,102,32,70,76,65,71,95,84,69,88,84,85,82,69,79,86,69,82,76,65,89,13,10,9,100,105,102,102,117,115,101,67,111,108,111,114,32,42,61,32,116,101,120,116,117,114,101,40,84,101,120,116,117,114,101,79,118,101,114,108,97,121,44,32,116,101,120,67,111,111,114,100,41,59,13,10,35,101,110,100,105,102,13,10,13,10,35,105,102,32,70,76,65,71,95,68,69,70,69,82,82,69,68,13,10,9,35,105,102,32,65,76,80,72,65,95,84,69,83,84,13,10,9,9,47,47,32,73,110,117,116,105,108,101,32,100,101,32,102,97,105,114,101,32,100,101,32,108,39,97,108,112,104,97,45,109,97,112,112,105,110,103,32,115,97,110,115,32,97,108,112,104,97,45,116,101,115,116,32,101,110,32,68,101,102,101,114,114,101,100,32,40,108,39,97,108,112,104,97,32,110,39,101,115,116,32,112,97,115,32,115,97,117,118,101,103,97,114,100,195,169,32,100,97,110,115,32,108,101,32,71,45,66,117,102,102,101,114,41,13,10,9,9,35,105,102,32,65,76,80,72,65,95,77,65,80,80,73,78,71,13,10,9,100,105,102,102,117,115,101,67,111,108,111,114,46,97,32,42,61,32,116,101,120,116,117,114,101,40,77,97,116,101,114,105,97,108,65,108,112,104,97,77,97,112,44,32,116,101,120,67,111,111,114,100,41,46,114,59,13,10,9,9,35,101,110,100,105,102,13,10,9,9,13,10,9,105,102,32,40,100,105,102,102,117,115,101,67,111,108,111,114,46,97,32,60,32,77,97,116,101,114,105,97,108,65,108,112,104,97,84,104,114,101,115,104,111,108,100,41,13,10,9,9,100,105,115,99,97,114,100,59,13,10,9,35,101,110,100,105,102,32,47,47,32,65,76,80,72,65,95,84,69,83,84,13,10,13,10,9,35,105,102,32,76,73,71,72,84,73,78,71,13,10,9,9,35,105,102,32,78,79,82,77,65,76,95,77,65,80,80,73,78,71,13,10,9,118,101,99,51,32,110,111,114,109,97,108,32,61,32,110,111,114,109,97,108,105,122,101,40,118,76,105,103,104,116,84,111,87,111,114,108,100,32,42,32,40,50,46,48,32,42,32,118,101,99,51,40,116,101,120,116,117,114,101,40,77,97,116,101,114,105,97,108,78,111,114,109,97,108,77,97,112,44,32,116,101,120,67,111,111,114,100,41,41,32,45,32,49,46,48,41,41,59,13,10,9,9,35,101,108,115,101,13,10,9,118,101,99,51,32,110,111,114,109,97,108,32,61,32,110,111,114,109,97,108,105,122,101,40,118,78,111,114,109,97,108,41,59,13,10,9,9,35,101,110,100,105,102,32,47,47,32,78,79,82,77,65,76,95,77,65,80,80,73,78,71,13,10,13,10,9,118,101,99,51,32,115,112,101,99,117,108,97,114,67,111,108,111,114,32,61,32,77,97,116,101,114,105,97,108,83,112,101,99,117,108,97,114,46,114,103,98,59,13,10,9,9,35,105,102,32,83,80,69,67,85,76,65,82,95,77,65,80,80,73,78,71,13,10,9,115,112,101,99,117,108,97,114,67,111,108,111,114,32,42,61,32,116,101,120,116,117,114,101,40,77,97,116,101,114,105,97,108,83,112,101,99,117,108,97,114,77,97,112,44,32,116,101,120,67,111,111,114,100,41,46,114,103,98,59,13,10,9,9,35,101,110,100,105,102,13,10,13,10,9,47,42,13,10,9,84,101,120,116,117,114,101,48,58,32,68,105,102,102,117,115,101,32,67,111,108,111,114,32,43,32,83,112,101,99,117,108,97,114,13,10,9,84,101,120,116,117,114,101,49,58,32,78,111,114,109,97,108,32,43,32,83,112,101,99,117,108,97,114,13,10,9,84,101,120,116,117,114,101,50,58,32,69,110,99,111,100,101,100,32,100,101,112,116,104,32,43,32,83,104,105,110,105,110,101,115,115,13,10,9,42,47,13,10,9,82,101,110,100,101,114,84,97,114,103,101,116,48,32,61,32,118,101,99,52,40,100,105,102,102,117,115,101,67,111,108,111,114,46,114,103,98,44,32,100,111,116,40,115,112,101,99,117,108,97,114,67,111,108,111,114,44,32,118,101,99,51,40,48,46,51,44,32,48,46,53,57,44,32,48,46,49,49,41,41,41,59,13,10,9,82,101,110,100,101,114,84,97,114,103,101,116,49,32,61,32,118,101,99,52,40,69,110,99,111,100,101,78,111,114,109,97,108,40,110,111,114,109,97,108,41,41,59,13,10,9,82,101,110,100,101,114,84,97,114,103,101,116,50,32,61,32,118,101,99,52,40,70,108,111,97,116,84,111,67,111,108,111,114,40,103,108,95,70,114,97,103,67,111,111,114,100,46,122,41,44,32,40,77,97,116,101,114,105,97,108,83,104,105,110,105,110,101,115,115,32,61,61,32,48,46,48,41,32,63,32,48,46,48,32,58,32,109,97,120,40,108,111,103,50,40,77,97,116,101,114,105,97,108,83,104,105,110,105,110,101,115,115,41,44,32,48,46,49,41,47,49,48,46,53,41,59,32,47,47,32,104,116,116,112,58,47,47,119,119,119,46,103,117,101,114,114,105,108,108,97,45,103,97,109,101,115,46,99,111,109,47,112,117,98,108,105,99,97,116,105,111,110,115,47,100,114,95,107,122,50,95,114,115,120,95,100,101,118,48,55,46,112,100,102,13,10,9,35,101,108,115,101,32,47,47,32,76,73,71,72,84,73,78,71,13,10,9,82,101,110,100,101,114,84,97,114,103,101,116,48,32,61,32,118,101,99,52,40,100,105,102,102,117,115,101,67,111,108,111,114,46,114,103,98,44,32,48,46,48,41,59,13,10,9,35,101,110,100,105,102,13,10,35,101,108,115,101,32,47,47,32,70,76,65,71,95,68,69,70,69,82,82,69,68,13,10,9,35,105,102,32,65,76,80,72,65,95,77,65,80,80,73,78,71,13,10,9,100,105,102,102,117,115,101,67,111,108,111,114,46,97,32,42,61,32,116,101,120,116,117,114,101,40,77,97,116,101,114,105,97,108,65,108,112,104,97,77,97,112,44,32,116,101,120,67,111,111,114,100,41,46,114,59,13,10,9,35,101,110,100,105,102,13,10,13,10,9,35,105,102,32,65,76,80,72,65,95,84,69,83,84,13,10,9,105,102,32,40,100,105,102,102,117,115,101,67,111,108,111,114,46,97,32,60,32,77,97,116,101,114,105,97,108,65,108,112,104,97,84,104,114,101,115,104,111,108,100,41,13,10,9,9,100,105,115,99,97,114,100,59,13,10,9,35,101,110,100,105,102,13,10,13,10,9,35,105,102,32,76,73,71,72,84,73,78,71,13,10,9,118,101,99,51,32,108,105,103,104,116,65,109,98,105,101,110,116,32,61,32,118,101,99,51,40,48,46,48,41,59,13,10,9,118,101,99,51,32,108,105,103,104,116,68,105,102,102,117,115,101,32,61,32,118,101,99,51,40,48,46,48,41,59,13,10,9,118,101,99,51,32,108,105,103,104,116,83,112,101,99,117,108,97,114,32,61,32,118,101,99,51,40,48,46,48,41,59,13,10,13,10,9,9,35,105,102,32,78,79,82,77,65,76,95,77,65,80,80,73,78,71,13,10,9,118,101,99,51,32,110,111,114,109,97,108,32,61,32,110,111,114,109,97,108,105,122,101,40,118,76,105,103,104,116,84,111,87,111,114,108,100,32,42,32,40,50,46,48,32,42,32,118,101,99,51,40,116,101,120,116,117,114,101,40,77,97,116,101,114,105,97,108,78,111,114,109,97,108,77,97,112,44,32,116,101,120,67,111,111,114,100,41,41,32,45,32,49,46,48,41,41,59,13,10,9,9,35,101,108,115,101,13,10,9,118,101,99,51,32,110,111,114,109,97,108,32,61,32,110,111,114,109,97,108,105,122,101,40,118,78,111,114,109,97,108,41,59,13,10,9,9,35,101,110,100,105,102,13,10,13,10,9,105,102,32,40,77,97,116,101,114,105,97,108,83,104,105,110,105,110,101,115,115,32,62,32,48,46,48,41,13,10,9,123,13,10,9,9,118,101,99,51,32,101,121,101,86,101,99,32,61,32,110,111,114,109,97,108,105,122,101,40,69,121,101,80,111,115,105,116,105,111,110,32,45,32,118,87,111,114,108,100,80,111,115,41,59,13,10,13,10,9,9,102,111,114,32,40,105,110,116,32,105,32,61,32,48,59,32,105,32,60,32,51,59,32,43,43,105,41,13,10,9,9,123,13,10,9,9,9,118,101,99,52,32,108,105,103,104,116,67,111,108,111,114,32,61,32,76,105,103,104,116,115,91,105,93,46,99,111,108,111,114,59,13,10,9,9,9,102,108,111,97,116,32,108,105,103,104,116,65,109,98,105,101,110,116,70,97,99,116,111,114,32,61,32,76,105,103,104,116,115,91,105,93,46,102,97,99,116,111,114,115,46,120,59,13,10,9,9,9,102,108,111,97,116,32,108,105,103,104,116,68,105,102,102,117,115,101,70,97,99,116,111,114,32,61,32,76,105,103,104,116,115,91,105,93,46,102,97,99,116,111,114,115,46,121,59,13,10,13,10,9,9,9,115,119,105,116,99,104,32,40,76,105,103,104,116,115,91,105,93,46,116,121,112,101,41,13,10,9,9,9,123,13,10,9,9,9,9,99,97,115,101,32,76,73,71,72,84,95,68,73,82,69,67,84,73,79,78,65,76,58,13,10,9,9,9,9,123,13,10,9,9,9,9,9,118,101,99,51,32,108,105,103,104,116,68,105,114,32,61,32,45,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,49,46,120,121,122,59,13,10,13,10,9,9,9,9,9,47,47,32,65,109,98,105,101,110,116,13,10,9,9,9,9,9,108,105,103,104,116,65,109,98,105,101,110,116,32,43,61,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,32,42,32,108,105,103,104,116,65,109,98,105,101,110,116,70,97,99,116,111,114,32,42,32,40,77,97,116,101,114,105,97,108,65,109,98,105,101,110,116,46,114,103,98,32,43,32,83,99,101,110,101,65,109,98,105,101,110,116,46,114,103,98,41,59,13,10,13,10,9,9,9,9,9,47,47,32,68,105,102,102,117,115,101,13,10,9,9,9,9,9,102,108,111,97,116,32,108,97,109,98,101,114,116,32,61,32,109,97,120,40,100,111,116,40,110,111,114,109,97,108,44,32,108,105,103,104,116,68,105,114,41,44,32,48,46,48,41,59,13,10,13,10,9,9,9,9,9,108,105,103,104,116,68,105,102,102,117,115,101,32,43,61,32,108,97,109,98,101,114,116,32,42,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,32,42,32,108,105,103,104,116,68,105,102,102,117,115,101,70,97,99,116,111,114,59,13,10,13,10,9,9,9,9,9,47,47,32,83,112,101,99,117,108,97,114,13,10,9,9,9,9,9,118,101,99,51,32,114,101,102,108,101,99,116,105,111,110,32,61,32,114,101,102,108,101,99,116,40,45,108,105,103,104,116,68,105,114,44,32,110,111,114,109,97,108,41,59,13,10,9,9,9,9,9,102,108,111,97,116,32,115,112,101,99,117,108,97,114,70,97,99,116,111,114,32,61,32,109,97,120,40,100,111,116,40,114,101,102,108,101,99,116,105,111,110,44,32,101,121,101,86,101,99,41,44,32,48,46,48,41,59,13,10,9,9,9,9,9,115,112,101,99,117,108,97,114,70,97,99,116,111,114,32,61,32,112,111,119,40,115,112,101,99,117,108,97,114,70,97,99,116,111,114,44,32,77,97,116,101,114,105,97,108,83,104,105,110,105,110,101,115,115,41,59,13,10,13,10,9,9,9,9,9,108,105,103,104,116,83,112,101,99,117,108,97,114,32,43,61,32,115,112,101,99,117,108,97,114,70,97,99,116,111,114,32,42,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,59,13,10,9,9,9,9,9,98,114,101,97,107,59,13,10,9,9,9,9,125,13,10,13,10,9,9,9,9,99,97,115,101,32,76,73,71,72,84,95,80,79,73,78,84,58,13,10,9,9,9,9,123,13,10,9,9,9,9,9,118,101,99,51,32,108,105,103,104,116,80,111,115,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,49,46,120,121,122,59,13,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,65,116,116,101,110,117,97,116,105,111,110,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,49,46,119,59,13,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,73,110,118,82,97,100,105,117,115,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,50,46,119,59,13,10,9,9,9,9,9,13,10,9,9,9,9,9,118,101,99,51,32,119,111,114,108,100,84,111,76,105,103,104,116,32,61,32,108,105,103,104,116,80,111,115,32,45,32,118,87,111,114,108,100,80,111,115,59,13,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,68,105,114,76,101,110,103,116,104,32,61,32,108,101,110,103,116,104,40,119,111,114,108,100,84,111,76,105,103,104,116,41,59,13,10,9,9,9,9,9,118,101,99,51,32,108,105,103,104,116,68,105,114,32,61,32,119,111,114,108,100,84,111,76,105,103,104,116,32,47,32,108,105,103,104,116,68,105,114,76,101,110,103,116,104,59,32,47,47,32,78,111,114,109,97,108,105,115,97,116,105,111,110,13,10,9,9,9,9,9,13,10,9,9,9,9,9,102,108,111,97,116,32,97,116,116,32,61,32,109,97,120,40,108,105,103,104,116,65,116,116,101,110,117,97,116,105,111,110,32,45,32,108,105,103,104,116,73,110,118,82,97,100,105,117,115,32,42,32,108,105,103,104,116,68,105,114,76,101,110,103,116,104,44,32,48,46,48,41,59,13,10,13,10,9,9,9,9,9,47,47,32,65,109,98,105,101,110,116,13,10,9,9,9,9,9,108,105,103,104,116,65,109,98,105,101,110,116,32,43,61,32,97,116,116,32,42,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,32,42,32,108,105,103,104,116,65,109,98,105,101,110,116,70,97,99,116,111,114,32,42,32,40,77,97,116,101,114,105,97,108,65,109,98,105,101,110,116,46,114,103,98,32,43,32,83,99,101,110,101,65,109,98,105,101,110,116,46,114,103,98,41,59,13,10,13,10,9,9,9,9,9,35,105,102,32,83,72,65,68,79,87,95,77,65,80,80,73,78,71,13,10,9,9,9,9,9,105,102,32,40,76,105,103,104,116,115,91,105,93,46,115,104,97,100,111,119,77,97,112,112,105,110,103,32,38,38,32,33,84,101,115,116,83,104,97,100,111,119,80,111,105,110,116,40,105,44,32,118,87,111,114,108,100,80,111,115,32,45,32,108,105,103,104,116,80,111,115,44,32,48,46,49,44,32,53,48,46,48,41,41,13,10,9,9,9,9,9,9,98,114,101,97,107,59,13,10,9,9,9,9,9,35,101,110,100,105,102,13,10,13,10,9,9,9,9,9,47,47,32,68,105,102,102,117,115,101,13,10,9,9,9,9,9,102,108,111,97,116,32,108,97,109,98,101,114,116,32,61,32,109,97,120,40,100,111,116,40,110,111,114,109,97,108,44,32,108,105,103,104,116,68,105,114,41,44,32,48,46,48,41,59,13,10,9,9,9,9,9,13,10,9,9,9,9,9,108,105,103,104,116,68,105,102,102,117,115,101,32,43,61,32,97,116,116,32,42,32,108,97,109,98,101,114,116,32,42,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,32,42,32,108,105,103,104,116,68,105,102,102,117,115,101,70,97,99,116,111,114,59,13,10,13,10,9,9,9,9,9,47,47,32,83,112,101,99,117,108,97,114,13,10,9,9,9,9,9,118,101,99,51,32,114,101,102,108,101,99,116,105,111,110,32,61,32,114,101,102,108,101,99,116,40,45,108,105,103,104,116,68,105,114,44,32,110,111,114,109,97,108,41,59,13,10,9,9,9,9,9,102,108,111,97,116,32,115,112,101,99,117,108,97,114,70,97,99,116,111,114,32,61,32,109,97,120,40,100,111,116,40,114,101,102,108,101,99,116,105,111,110,44,32,101,121,101,86,101,99,41,44,32,48,46,48,41,59,13,10,9,9,9,9,9,115,112,101,99,117,108,97,114,70,97,99,116,111,114,32,61,32,112,111,119,40,115,112,101,99,117,108,97,114,70,97,99,116,111,114,44,32,77,97,116,101,114,105,97,108,83,104,105,110,105,110,101,115,115,41,59,13,10,13,10,9,9,9,9,9,108,105,103,104,116,83,112,101,99,117,108,97,114,32,43,61,32,97,116,116,32,42,32,115,112,101,99,117,108,97,114,70,97,99,116,111,114,32,42,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,59,13,10,9,9,9,9,9,98,114,101,97,107,59,13,10,9,9,9,9,125,13,10,13,10,9,9,9,9,99,97,115,101,32,76,73,71,72,84,95,83,80,79,84,58,13,10,9,9,9,9,123,13,10,9,9,9,9,9,118,101,99,51,32,108,105,103,104,116,80,111,115,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,49,46,120,121,122,59,13,10,9,9,9,9,9,118,101,99,51,32,108,105,103,104,116,68,105,114,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,50,46,120,121,122,59,13,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,65,116,116,101,110,117,97,116,105,111,110,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,49,46,119,59,13,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,73,110,118,82,97,100,105,117,115,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,50,46,119,59,13,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,73,110,110,101,114,65,110,103,108,101,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,51,46,120,59,13,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,79,117,116,101,114,65,110,103,108,101,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,51,46,121,59,13,10,13,10,9,9,9,9,9,118,101,99,51,32,119,111,114,108,100,84,111,76,105,103,104,116,32,61,32,108,105,103,104,116,80,111,115,32,45,32,118,87,111,114,108,100,80,111,115,59,13,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,68,105,115,116,97,110,99,101,32,61,32,108,101,110,103,116,104,40,119,111,114,108,100,84,111,76,105,103,104,116,41,59,13,10,9,9,9,9,9,119,111,114,108,100,84,111,76,105,103,104,116,32,47,61,32,108,105,103,104,116,68,105,115,116,97,110,99,101,59,32,47,47,32,78,111,114,109,97,108,105,115,97,116,105,111,110,13,10,9,9,9,9,9,13,10,9,9,9,9,9,102,108,111,97,116,32,97,116,116,32,61,32,109,97,120,40,108,105,103,104,116,65,116,116,101,110,117,97,116,105,111,110,32,45,32,108,105,103,104,116,73,110,118,82,97,100,105,117,115,32,42,32,108,105,103,104,116,68,105,115,116,97,110,99,101,44,32,48,46,48,41,59,13,10,13,10,9,9,9,9,9,47,47,32,65,109,98,105,101,110,116,13,10,9,9,9,9,9,108,105,103,104,116,65,109,98,105,101,110,116,32,43,61,32,97,116,116,32,42,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,32,42,32,108,105,103,104,116,65,109,98,105,101,110,116,70,97,99,116,111,114,32,42,32,40,77,97,116,101,114,105,97,108,65,109,98,105,101,110,116,46,114,103,98,32,43,32,83,99,101,110,101,65,109,98,105,101,110,116,46,114,103,98,41,59,13,10,13,10,9,9,9,9,9,35,105,102,32,83,72,65,68,79,87,95,77,65,80,80,73,78,71,13,10,9,9,9,9,9,105,102,32,40,76,105,103,104,116,115,91,105,93,46,115,104,97,100,111,119,77,97,112,112,105,110,103,32,38,38,32,33,84,101,115,116,83,104,97,100,111,119,83,112,111,116,40,105,41,41,13,10,9,9,9,9,9,9,98,114,101,97,107,59,13,10,9,9,9,9,9,35,101,110,100,105,102,13,10,13,10,9,9,9,9,9,47,47,32,77,111,100,105,102,105,99,97,116,105,111,110,32,100,101,32,108,39,97,116,116,195,169,110,117,97,116,105,111,110,32,112,111,117,114,32,103,195,169,114,101,114,32,108,101,32,115,112,111,116,13,10,9,9,9,9,9,102,108,111,97,116,32,99,117,114,65,110,103,108,101,32,61,32,100,111,116,40,108,105,103,104,116,68,105,114,44,32,45,119,111,114,108,100,84,111,76,105,103,104,116,41,59,13,10,9,9,9,9,9,102,108,111,97,116,32,105,110,110,101,114,77,105,110,117,115,79,117,116,101,114,65,110,103,108,101,32,61,32,108,105,103,104,116,73,110,110,101,114,65,110,103,108,101,32,45,32,108,105,103,104,116,79,117,116,101,114,65,110,103,108,101,59,13,10,9,9,9,9,9,97,116,116,32,42,61,32,109,97,120,40,40,99,117,114,65,110,103,108,101,32,45,32,108,105,103,104,116,79,117,116,101,114,65,110,103,108,101,41,32,47,32,105,110,110,101,114,77,105,110,117,115,79,117,116,101,114,65,110,103,108,101,44,32,48,46,48,41,59,13,10,13,10,9,9,9,9,9,47,47,32,68,105,102,102,117,115,101,13,10,9,9,9,9,9,102,108,111,97,116,32,108,97,109,98,101,114,116,32,61,32,109,97,120,40,100,111,116,40,110,111,114,109,97,108,44,32,119,111,114,108,100,84,111,76,105,103,104,116,41,44,32,48,46,48,41,59,13,10,13,10,9,9,9,9,9,108,105,103,104,116,68,105,102,102,117,115,101,32,43,61,32,97,116,116,32,42,32,108,97,109,98,101,114,116,32,42,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,32,42,32,108,105,103,104,116,68,105,102,102,117,115,101,70,97,99,116,111,114,59,13,10,13,10,9,9,9,9,9,47,47,32,83,112,101,99,117,108,97,114,13,10,9,9,9,9,9,118,101,99,51,32,114,101,102,108,101,99,116,105,111,110,32,61,32,114,101,102,108,101,99,116,40,45,119,111,114,108,100,84,111,76,105,103,104,116,44,32,110,111,114,109,97,108,41,59,13,10,9,9,9,9,9,102,108,111,97,116,32,115,112,101,99,117,108,97,114,70,97,99,116,111,114,32,61,32,109,97,120,40,100,111,116,40,114,101,102,108,101,99,116,105,111,110,44,32,101,121,101,86,101,99,41,44,32,48,46,48,41,59,13,10,9,9,9,9,9,115,112,101,99,117,108,97,114,70,97,99,116,111,114,32,61,32,112,111,119,40,115,112,101,99,117,108,97,114,70,97,99,116,111,114,44,32,77,97,116,101,114,105,97,108,83,104,105,110,105,110,101,115,115,41,59,13,10,13,10,9,9,9,9,9,108,105,103,104,116,83,112,101,99,117,108,97,114,32,43,61,32,97,116,116,32,42,32,115,112,101,99,117,108,97,114,70,97,99,116,111,114,32,42,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,59,13,10,9,9,9,9,9,98,114,101,97,107,59,13,10,9,9,9,9,125,13,10,9,9,9,9,13,10,9,9,9,9,100,101,102,97,117,108,116,58,13,10,9,9,9,9,9,98,114,101,97,107,59,13,10,9,9,9,125,13,10,9,9,125,13,10,9,125,13,10,9,101,108,115,101,13,10,9,123,13,10,9,9,102,111,114,32,40,105,110,116,32,105,32,61,32,48,59,32,105,32,60,32,51,59,32,43,43,105,41,13,10,9,9,123,13,10,9,9,9,118,101,99,52,32,108,105,103,104,116,67,111,108,111,114,32,61,32,76,105,103,104,116,115,91,105,93,46,99,111,108,111,114,59,13,10,9,9,9,102,108,111,97,116,32,108,105,103,104,116,65,109,98,105,101,110,116,70,97,99,116,111,114,32,61,32,76,105,103,104,116,115,91,105,93,46,102,97,99,116,111,114,115,46,120,59,13,10,9,9,9,102,108,111,97,116,32,108,105,103,104,116,68,105,102,102,117,115,101,70,97,99,116,111,114,32,61,32,76,105,103,104,116,115,91,105,93,46,102,97,99,116,111,114,115,46,121,59,13,10,13,10,9,9,9,115,119,105,116,99,104,32,40,76,105,103,104,116,115,91,105,93,46,116,121,112,101,41,13,10,9,9,9,123,13,10,9,9,9,9,99,97,115,101,32,76,73,71,72,84,95,68,73,82,69,67,84,73,79,78,65,76,58,13,10,9,9,9,9,123,13,10,9,9,9,9,9,118,101,99,51,32,108,105,103,104,116,68,105,114,32,61,32,45,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,49,46,120,121,122,59,13,10,13,10,9,9,9,9,9,47,47,32,65,109,98,105,101,110,116,13,10,9,9,9,9,9,108,105,103,104,116,65,109,98,105,101,110,116,32,43,61,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,32,42,32,108,105,103,104,116,65,109,98,105,101,110,116,70,97,99,116,111,114,32,42,32,40,77,97,116,101,114,105,97,108,65,109,98,105,101,110,116,46,114,103,98,32,43,32,83,99,101,110,101,65,109,98,105,101,110,116,46,114,103,98,41,59,13,10,13,10,9,9,9,9,9,47,47,32,68,105,102,102,117,115,101,13,10,9,9,9,9,9,102,108,111,97,116,32,108,97,109,98,101,114,116,32,61,32,109,97,120,40,100,111,116,40,110,111,114,109,97,108,44,32,108,105,103,104,116,68,105,114,41,44,32,48,46,48,41,59,13,10,13,10,9,9,9,9,9,108,105,103,104,116,68,105,102,102,117,115,101,32,43,61,32,108,97,109,98,101,114,116,32,42,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,32,42,32,108,105,103,104,116,68,105,102,102,117,115,101,70,97,99,116,111,114,59,13,10,9,9,9,9,9,98,114,101,97,107,59,13,10,9,9,9,9,125,13,10,13,10,9,9,9,9,99,97,115,101,32,76,73,71,72,84,95,80,79,73,78,84,58,13,10,9,9,9,9,123,13,10,9,9,9,9,9,118,101,99,51,32,108,105,103,104,116,80,111,115,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,49,46,120,121,122,59,13,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,65,116,116,101,110,117,97,116,105,111,110,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,49,46,119,59,13,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,73,110,118,82,97,100,105,117,115,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,50,46,119,59,13,10,9,9,9,9,9,13,10,9,9,9,9,9,118,101,99,51,32,119,111,114,108,100,84,111,76,105,103,104,116,32,61,32,108,105,103,104,116,80,111,115,32,45,32,118,87,111,114,108,100,80,111,115,59,13,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,68,105,114,76,101,110,103,116,104,32,61,32,108,101,110,103,116,104,40,119,111,114,108,100,84,111,76,105,103,104,116,41,59,13,10,9,9,9,9,9,118,101,99,51,32,108,105,103,104,116,68,105,114,32,61,32,119,111,114,108,100,84,111,76,105,103,104,116,32,47,32,108,105,103,104,116,68,105,114,76,101,110,103,116,104,59,32,47,47,32,78,111,114,109,97,108,105,115,97,116,105,111,110,13,10,9,9,9,9,9,13,10,9,9,9,9,9,102,108,111,97,116,32,97,116,116,32,61,32,109,97,120,40,108,105,103,104,116,65,116,116,101,110,117,97,116,105,111,110,32,45,32,108,105,103,104,116,73,110,118,82,97,100,105,117,115,32,42,32,108,105,103,104,116,68,105,114,76,101,110,103,116,104,44,32,48,46,48,41,59,13,10,13,10,9,9,9,9,9,47,47,32,65,109,98,105,101,110,116,13,10,9,9,9,9,9,108,105,103,104,116,65,109,98,105,101,110,116,32,43,61,32,97,116,116,32,42,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,32,42,32,108,105,103,104,116,65,109,98,105,101,110,116,70,97,99,116,111,114,32,42,32,40,77,97,116,101,114,105,97,108,65,109,98,105,101,110,116,46,114,103,98,32,43,32,83,99,101,110,101,65,109,98,105,101,110,116,46,114,103,98,41,59,13,10,13,10,9,9,9,9,9,35,105,102,32,83,72,65,68,79,87,95,77,65,80,80,73,78,71,13,10,9,9,9,9,9,105,102,32,40,76,105,103,104,116,115,91,105,93,46,115,104,97,100,111,119,77,97,112,112,105,110,103,32,38,38,32,33,84,101,115,116,83,104,97,100,111,119,80,111,105,110,116,40,105,44,32,118,87,111,114,108,100,80,111,115,32,45,32,108,105,103,104,116,80,111,115,44,32,48,46,49,44,32,49,46,48,32,47,32,108,105,103,104,116,73,110,118,82,97,100,105,117,115,41,41,13,10,9,9,9,9,9,9,98,114,101,97,107,59,13,10,9,9,9,9,9,35,101,110,100,105,102,13,10,13,10,9,9,9,9,9,47,47,32,68,105,102,102,117,115,101,13,10,9,9,9,9,9,102,108,111,97,116,32,108,97,109,98,101,114,116,32,61,32,109,97,120,40,100,111,116,40,110,111,114,109,97,108,44,32,108,105,103,104,116,68,105,114,41,44,32,48,46,48,41,59,13,10,9,9,9,9,9,13,10,9,9,9,9,9,108,105,103,104,116,68,105,102,102,117,115,101,32,43,61,32,97,116,116,32,42,32,108,97,109,98,101,114,116,32,42,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,32,42,32,108,105,103,104,116,68,105,102,102,117,115,101,70,97,99,116,111,114,59,13,10,9,9,9,9,9,98,114,101,97,107,59,13,10,9,9,9,9,125,13,10,13,10,9,9,9,9,99,97,115,101,32,76,73,71,72,84,95,83,80,79,84,58,13,10,9,9,9,9,123,13,10,9,9,9,9,9,118,101,99,51,32,108,105,103,104,116,80,111,115,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,49,46,120,121,122,59,13,10,9,9,9,9,9,118,101,99,51,32,108,105,103,104,116,68,105,114,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,50,46,120,121,122,59,13,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,65,116,116,101,110,117,97,116,105,111,110,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,49,46,119,59,13,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,73,110,118,82,97,100,105,117,115,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,50,46,119,59,13,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,73,110,110,101,114,65,110,103,108,101,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,51,46,120,59,13,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,79,117,116,101,114,65,110,103,108,101,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,51,46,121,59,13,10,13,10,9,9,9,9,9,118,101,99,51,32,119,111,114,108,100,84,111,76,105,103,104,116,32,61,32,108,105,103,104,116,80,111,115,32,45,32,118,87,111,114,108,100,80,111,115,59,13,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,68,105,115,116,97,110,99,101,32,61,32,108,101,110,103,116,104,40,119,111,114,108,100,84,111,76,105,103,104,116,41,59,13,10,9,9,9,9,9,119,111,114,108,100,84,111,76,105,103,104,116,32,47,61,32,108,105,103,104,116,68,105,115,116,97,110,99,101,59,32,47,47,32,78,111,114,109,97,108,105,115,97,116,105,111,110,13,10,9,9,9,9,9,13,10,9,9,9,9,9,102,108,111,97,116,32,97,116,116,32,61,32,109,97,120,40,108,105,103,104,116,65,116,116,101,110,117,97,116,105,111,110,32,45,32,108,105,103,104,116,73,110,118,82,97,100,105,117,115,32,42,32,108,105,103,104,116,68,105,115,116,97,110,99,101,44,32,48,46,48,41,59,13,10,13,10,9,9,9,9,9,47,47,32,65,109,98,105,101,110,116,13,10,9,9,9,9,9,108,105,103,104,116,65,109,98,105,101,110,116,32,43,61,32,97,116,116,32,42,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,32,42,32,108,105,103,104,116,65,109,98,105,101,110,116,70,97,99,116,111,114,32,42,32,40,77,97,116,101,114,105,97,108,65,109,98,105,101,110,116,46,114,103,98,32,43,32,83,99,101,110,101,65,109,98,105,101,110,116,46,114,103,98,41,59,13,10,13,10,9,9,9,9,9,35,105,102,32,83,72,65,68,79,87,95,77,65,80,80,73,78,71,13,10,9,9,9,9,9,105,102,32,40,76,105,103,104,116,115,91,105,93,46,115,104,97,100,111,119,77,97,112,112,105,110,103,32,38,38,32,33,84,101,115,116,83,104,97,100,111,119,83,112,111,116,40,105,41,41,13,10,9,9,9,9,9,9,98,114,101,97,107,59,13,10,9,9,9,9,9,35,101,110,100,105,102,13,10,13,10,9,9,9,9,9,47,47,32,77,111,100,105,102,105,99,97,116,105,111,110,32,100,101,32,108,39,97,116,116,195,169,110,117,97,116,105,111,110,32,112,111,117,114,32,103,195,169,114,101,114,32,108,101,32,115,112,111,116,13,10,9,9,9,9,9,102,108,111,97,116,32,99,117,114,65,110,103,108,101,32,61,32,100,111,116,40,108,105,103,104,116,68,105,114,44,32,45,119,111,114,108,100,84,111,76,105,103,104,116,41,59,13,10,9,9,9,9,9,102,108,111,97,116,32,105,110,110,101,114,77,105,110,117,115,79,117,116,101,114,65,110,103,108,101,32,61,32,108,105,103,104,116,73,110,110,101,114,65,110,103,108,101,32,45,32,108,105,103,104,116,79,117,116,101,114,65,110,103,108,101,59,13,10,9,9,9,9,9,97,116,116,32,42,61,32,109,97,120,40,40,99,117,114,65,110,103,108,101,32,45,32,108,105,103,104,116,79,117,116,101,114,65,110,103,108,101,41,32,47,32,105,110,110,101,114,77,105,110,117,115,79,117,116,101,114,65,110,103,108,101,44,32,48,46,48,41,59,13,10,13,10,9,9,9,9,9,47,47,32,68,105,102,102,117,115,101,13,10,9,9,9,9,9,102,108,111,97,116,32,108,97,109,98,101,114,116,32,61,32,109,97,120,40,100,111,116,40,110,111,114,109,97,108,44,32,119,111,114,108,100,84,111,76,105,103,104,116,41,44,32,48,46,48,41,59,13,10,13,10,9,9,9,9,9,108,105,103,104,116,68,105,102,102,117,115,101,32,43,61,32,97,116,116,32,42,32,108,97,109,98,101,114,116,32,42,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,32,42,32,108,105,103,104,116,68,105,102,102,117,115,101,70,97,99,116,111,114,59,13,10,9,9,9,9,125,13,10,9,9,9,9,13,10,9,9,9,9,100,101,102,97,117,108,116,58,13,10,9,9,9,9,9,98,114,101,97,107,59,13,10,9,9,9,125,13,10,9,9,125,13,10,9,125,13,10,9,13,10,9,108,105,103,104,116,83,112,101,99,117,108,97,114,32,42,61,32,77,97,116,101,114,105,97,108,83,112,101,99,117,108,97,114,46,114,103,98,59,13,10,9,9,35,105,102,32,83,80,69,67,85,76,65,82,95,77,65,80,80,73,78,71,13,10,9,108,105,103,104,116,83,112,101,99,117,108,97,114,32,42,61,32,116,101,120,116,117,114,101,40,77,97,116,101,114,105,97,108,83,112,101,99,117,108,97,114,77,97,112,44,32,116,101,120,67,111,111,114,100,41,46,114,103,98,59,32,47,47,32,85,116,105,108,105,115,101,114,32,108,39,97,108,112,104,97,32,100,101,32,77,97,116,101,114,105,97,108,83,112,101,99,117,108,97,114,32,110,39,97,117,114,97,105,116,32,97,117,99,117,110,32,115,101,110,115,13,10,9,9,35,101,110,100,105,102,13,10,9,9,13,10,9,118,101,99,51,32,108,105,103,104,116,67,111,108,111,114,32,61,32,40,108,105,103,104,116,65,109,98,105,101,110,116,32,43,32,108,105,103,104,116,68,105,102,102,117,115,101,32,43,32,108,105,103,104,116,83,112,101,99,117,108,97,114,41,59,13,10,9,118,101,99,52,32,102,114,97,103,109,101,110,116,67,111,108,111,114,32,61,32,118,101,99,52,40,108,105,103,104,116,67,111,108,111,114,44,32,49,46,48,41,32,42,32,100,105,102,102,117,115,101,67,111,108,111,114,59,13,10,13,10,9,9,35,105,102,32,69,77,73,83,83,73,86,69,95,77,65,80,80,73,78,71,13,10,9,102,108,111,97,116,32,108,105,103,104,116,73,110,116,101,110,115,105,116,121,32,61,32,100,111,116,40,108,105,103,104,116,67,111,108,111,114,44,32,118,101,99,51,40,48,46,51,44,32,48,46,53,57,44,32,48,46,49,49,41,41,59,13,10,13,10,9,118,101,99,51,32,101,109,105,115,115,105,111,110,67,111,108,111,114,32,61,32,77,97,116,101,114,105,97,108,68,105,102,102,117,115,101,46,114,103,98,32,42,32,116,101,120,116,117,114,101,40,77,97,116,101,114,105,97,108,69,109,105,115,115,105,118,101,77,97,112,44,32,116,101,120,67,111,111,114,100,41,46,114,103,98,59,13,10,9,82,101,110,100,101,114,84,97,114,103,101,116,48,32,61,32,118,101,99,52,40,109,105,120,40,102,114,97,103,109,101,110,116,67,111,108,111,114,46,114,103,98,44,32,101,109,105,115,115,105,111,110,67,111,108,111,114,44,32,99,108,97,109,112,40,49,46,48,32,45,32,51,46,48,42,108,105,103,104,116,73,110,116,101,110,115,105,116,121,44,32,48,46,48,44,32,49,46,48,41,41,44,32,102,114,97,103,109,101,110,116,67,111,108,111,114,46,97,41,59,13,10,9,9,35,101,108,115,101,13,10,9,82,101,110,100,101,114,84,97,114,103,101,116,48,32,61,32,102,114,97,103,109,101,110,116,67,111,108,111,114,59,13,10,9,9,35,101,110,100,105,102,32,47,47,32,69,77,73,83,83,73,86,69,95,77,65,80,80,73,78,71,13,10,9,35,101,108,115,101,13,10,9,82,101,110,100,101,114,84,97,114,103,101,116,48,32,61,32,100,105,102,102,117,115,101,67,111,108,111,114,59,13,10,9,35,101,110,100,105,102,32,47,47,32,76,73,71,72,84,73,78,71,13,10,35,101,110,100,105,102,32,47,47,32,70,76,65,71,95,68,69,70,69,82,82,69,68,13,10,125,13,10,10, \ No newline at end of file diff --git a/src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.vert b/src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.vert index 5c1d95fef..06f7b7bd2 100644 --- a/src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.vert +++ b/src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.vert @@ -15,6 +15,7 @@ in vec2 VertexTexCoord; /********************Sortant********************/ out vec4 vColor; +out vec4 vLightSpacePos[3]; out mat3 vLightToWorld; out vec3 vNormal; out vec2 vTexCoord; @@ -23,6 +24,8 @@ out vec3 vWorldPos; /********************Uniformes********************/ uniform vec3 EyePosition; +uniform mat4 InvViewMatrix; +uniform mat4 LightViewProjMatrix[3]; uniform float VertexDepth; uniform mat4 ViewProjMatrix; uniform mat4 WorldMatrix; @@ -120,6 +123,11 @@ void main() #endif #endif +#if SHADOW_MAPPING + for (int i = 0; i < 3; ++i) + vLightSpacePos[i] = LightViewProjMatrix[i] * WorldMatrix * vec4(VertexPosition, 1.0); +#endif + #if TEXTURE_MAPPING vTexCoord = VertexTexCoord; #endif diff --git a/src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.vert.h b/src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.vert.h index 3c23c60a3..45e30d30e 100644 --- a/src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.vert.h +++ b/src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.vert.h @@ -1 +1 @@ -47,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,69,110,116,114,97,110,116,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,47,13,10,35,105,102,32,70,76,65,71,95,66,73,76,76,66,79,65,82,68,13,10,105,110,32,118,101,99,51,32,73,110,115,116,97,110,99,101,68,97,116,97,48,59,32,47,47,32,99,101,110,116,101,114,13,10,105,110,32,118,101,99,52,32,73,110,115,116,97,110,99,101,68,97,116,97,49,59,32,47,47,32,115,105,122,101,32,124,32,115,105,110,32,99,111,115,13,10,105,110,32,118,101,99,52,32,73,110,115,116,97,110,99,101,68,97,116,97,50,59,32,47,47,32,99,111,108,111,114,13,10,35,101,108,115,101,13,10,105,110,32,109,97,116,52,32,73,110,115,116,97,110,99,101,68,97,116,97,48,59,13,10,35,101,110,100,105,102,13,10,13,10,105,110,32,118,101,99,52,32,86,101,114,116,101,120,67,111,108,111,114,59,13,10,105,110,32,118,101,99,51,32,86,101,114,116,101,120,80,111,115,105,116,105,111,110,59,13,10,105,110,32,118,101,99,51,32,86,101,114,116,101,120,78,111,114,109,97,108,59,13,10,105,110,32,118,101,99,51,32,86,101,114,116,101,120,84,97,110,103,101,110,116,59,13,10,105,110,32,118,101,99,50,32,86,101,114,116,101,120,84,101,120,67,111,111,114,100,59,13,10,13,10,47,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,83,111,114,116,97,110,116,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,47,13,10,111,117,116,32,118,101,99,52,32,118,67,111,108,111,114,59,13,10,111,117,116,32,109,97,116,51,32,118,76,105,103,104,116,84,111,87,111,114,108,100,59,13,10,111,117,116,32,118,101,99,51,32,118,78,111,114,109,97,108,59,13,10,111,117,116,32,118,101,99,50,32,118,84,101,120,67,111,111,114,100,59,13,10,111,117,116,32,118,101,99,51,32,118,86,105,101,119,68,105,114,59,13,10,111,117,116,32,118,101,99,51,32,118,87,111,114,108,100,80,111,115,59,13,10,13,10,47,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,85,110,105,102,111,114,109,101,115,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,47,13,10,117,110,105,102,111,114,109,32,118,101,99,51,32,69,121,101,80,111,115,105,116,105,111,110,59,13,10,117,110,105,102,111,114,109,32,102,108,111,97,116,32,86,101,114,116,101,120,68,101,112,116,104,59,13,10,117,110,105,102,111,114,109,32,109,97,116,52,32,86,105,101,119,80,114,111,106,77,97,116,114,105,120,59,13,10,117,110,105,102,111,114,109,32,109,97,116,52,32,87,111,114,108,100,77,97,116,114,105,120,59,13,10,117,110,105,102,111,114,109,32,109,97,116,52,32,87,111,114,108,100,86,105,101,119,80,114,111,106,77,97,116,114,105,120,59,13,10,13,10,47,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,70,111,110,99,116,105,111,110,115,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,47,13,10,118,111,105,100,32,109,97,105,110,40,41,13,10,123,13,10,35,105,102,32,70,76,65,71,95,86,69,82,84,69,88,67,79,76,79,82,13,10,9,118,101,99,52,32,99,111,108,111,114,32,61,32,86,101,114,116,101,120,67,111,108,111,114,59,13,10,35,101,108,115,101,13,10,9,118,101,99,52,32,99,111,108,111,114,32,61,32,118,101,99,52,40,49,46,48,41,59,13,10,35,101,110,100,105,102,13,10,13,10,9,118,101,99,50,32,116,101,120,67,111,111,114,100,115,59,13,10,13,10,35,105,102,32,70,76,65,71,95,66,73,76,76,66,79,65,82,68,13,10,9,35,105,102,32,70,76,65,71,95,73,78,83,84,65,78,67,73,78,71,13,10,9,118,101,99,51,32,98,105,108,108,98,111,97,114,100,67,101,110,116,101,114,32,61,32,73,110,115,116,97,110,99,101,68,97,116,97,48,59,13,10,9,118,101,99,50,32,98,105,108,108,98,111,97,114,100,83,105,122,101,32,61,32,73,110,115,116,97,110,99,101,68,97,116,97,49,46,120,121,59,13,10,9,118,101,99,50,32,98,105,108,108,98,111,97,114,100,83,105,110,67,111,115,32,61,32,73,110,115,116,97,110,99,101,68,97,116,97,49,46,122,119,59,13,10,9,118,101,99,52,32,98,105,108,108,98,111,97,114,100,67,111,108,111,114,32,61,32,73,110,115,116,97,110,99,101,68,97,116,97,50,59,13,10,13,10,9,118,101,99,50,32,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,59,13,10,9,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,46,120,32,61,32,86,101,114,116,101,120,80,111,115,105,116,105,111,110,46,120,42,98,105,108,108,98,111,97,114,100,83,105,110,67,111,115,46,121,32,45,32,86,101,114,116,101,120,80,111,115,105,116,105,111,110,46,121,42,98,105,108,108,98,111,97,114,100,83,105,110,67,111,115,46,120,59,13,10,9,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,46,121,32,61,32,86,101,114,116,101,120,80,111,115,105,116,105,111,110,46,121,42,98,105,108,108,98,111,97,114,100,83,105,110,67,111,115,46,121,32,43,32,86,101,114,116,101,120,80,111,115,105,116,105,111,110,46,120,42,98,105,108,108,98,111,97,114,100,83,105,110,67,111,115,46,120,59,13,10,9,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,32,42,61,32,98,105,108,108,98,111,97,114,100,83,105,122,101,59,13,10,13,10,9,118,101,99,51,32,99,97,109,101,114,97,82,105,103,104,116,32,61,32,118,101,99,51,40,86,105,101,119,77,97,116,114,105,120,91,48,93,91,48,93,44,32,86,105,101,119,77,97,116,114,105,120,91,49,93,91,48,93,44,32,86,105,101,119,77,97,116,114,105,120,91,50,93,91,48,93,41,59,13,10,9,118,101,99,51,32,99,97,109,101,114,97,85,112,32,61,32,118,101,99,51,40,86,105,101,119,77,97,116,114,105,120,91,48,93,91,49,93,44,32,86,105,101,119,77,97,116,114,105,120,91,49,93,91,49,93,44,32,86,105,101,119,77,97,116,114,105,120,91,50,93,91,49,93,41,59,13,10,9,118,101,99,51,32,118,101,114,116,101,120,80,111,115,32,61,32,98,105,108,108,98,111,97,114,100,67,101,110,116,101,114,32,43,32,99,97,109,101,114,97,82,105,103,104,116,42,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,46,120,32,43,32,99,97,109,101,114,97,85,112,42,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,46,121,59,13,10,13,10,9,103,108,95,80,111,115,105,116,105,111,110,32,61,32,86,105,101,119,80,114,111,106,77,97,116,114,105,120,32,42,32,118,101,99,52,40,118,101,114,116,101,120,80,111,115,44,32,49,46,48,41,59,13,10,9,99,111,108,111,114,32,61,32,98,105,108,108,98,111,97,114,100,67,111,108,111,114,59,13,10,9,116,101,120,67,111,111,114,100,115,32,61,32,86,101,114,116,101,120,80,111,115,105,116,105,111,110,46,120,121,32,43,32,48,46,53,59,13,10,9,35,101,108,115,101,13,10,9,118,101,99,50,32,98,105,108,108,98,111,97,114,100,67,111,114,110,101,114,32,61,32,86,101,114,116,101,120,84,101,120,67,111,111,114,100,32,45,32,48,46,53,59,13,10,9,118,101,99,50,32,98,105,108,108,98,111,97,114,100,83,105,122,101,32,61,32,86,101,114,116,101,120,85,115,101,114,100,97,116,97,48,46,120,121,59,13,10,9,118,101,99,50,32,98,105,108,108,98,111,97,114,100,83,105,110,67,111,115,32,61,32,86,101,114,116,101,120,85,115,101,114,100,97,116,97,48,46,122,119,59,13,10,9,13,10,9,118,101,99,50,32,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,59,13,10,9,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,46,120,32,61,32,98,105,108,108,98,111,97,114,100,67,111,114,110,101,114,46,120,42,98,105,108,108,98,111,97,114,100,83,105,110,67,111,115,46,121,32,45,32,98,105,108,108,98,111,97,114,100,67,111,114,110,101,114,46,121,42,98,105,108,108,98,111,97,114,100,83,105,110,67,111,115,46,120,59,13,10,9,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,46,121,32,61,32,98,105,108,108,98,111,97,114,100,67,111,114,110,101,114,46,121,42,98,105,108,108,98,111,97,114,100,83,105,110,67,111,115,46,121,32,43,32,98,105,108,108,98,111,97,114,100,67,111,114,110,101,114,46,120,42,98,105,108,108,98,111,97,114,100,83,105,110,67,111,115,46,120,59,13,10,9,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,32,42,61,32,98,105,108,108,98,111,97,114,100,83,105,122,101,59,13,10,13,10,9,118,101,99,51,32,99,97,109,101,114,97,82,105,103,104,116,32,61,32,118,101,99,51,40,86,105,101,119,77,97,116,114,105,120,91,48,93,91,48,93,44,32,86,105,101,119,77,97,116,114,105,120,91,49,93,91,48,93,44,32,86,105,101,119,77,97,116,114,105,120,91,50,93,91,48,93,41,59,13,10,9,118,101,99,51,32,99,97,109,101,114,97,85,112,32,61,32,118,101,99,51,40,86,105,101,119,77,97,116,114,105,120,91,48,93,91,49,93,44,32,86,105,101,119,77,97,116,114,105,120,91,49,93,91,49,93,44,32,86,105,101,119,77,97,116,114,105,120,91,50,93,91,49,93,41,59,13,10,9,118,101,99,51,32,118,101,114,116,101,120,80,111,115,32,61,32,86,101,114,116,101,120,80,111,115,105,116,105,111,110,32,43,32,99,97,109,101,114,97,82,105,103,104,116,42,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,46,120,32,43,32,99,97,109,101,114,97,85,112,42,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,46,121,59,13,10,13,10,9,103,108,95,80,111,115,105,116,105,111,110,32,61,32,86,105,101,119,80,114,111,106,77,97,116,114,105,120,32,42,32,118,101,99,52,40,118,101,114,116,101,120,80,111,115,44,32,49,46,48,41,59,13,10,9,116,101,120,67,111,111,114,100,115,32,61,32,86,101,114,116,101,120,84,101,120,67,111,111,114,100,59,13,10,9,35,101,110,100,105,102,13,10,35,101,108,115,101,13,10,9,35,105,102,32,70,76,65,71,95,73,78,83,84,65,78,67,73,78,71,13,10,9,9,35,105,102,32,84,82,65,78,83,70,79,82,77,13,10,9,103,108,95,80,111,115,105,116,105,111,110,32,61,32,86,105,101,119,80,114,111,106,77,97,116,114,105,120,32,42,32,73,110,115,116,97,110,99,101,68,97,116,97,48,32,42,32,118,101,99,52,40,86,101,114,116,101,120,80,111,115,105,116,105,111,110,44,32,49,46,48,41,59,13,10,9,9,35,101,108,115,101,13,10,9,9,9,35,105,102,32,85,78,73,70,79,82,77,95,86,69,82,84,69,88,95,68,69,80,84,72,13,10,9,103,108,95,80,111,115,105,116,105,111,110,32,61,32,73,110,115,116,97,110,99,101,68,97,116,97,48,32,42,32,118,101,99,52,40,86,101,114,116,101,120,80,111,115,105,116,105,111,110,46,120,121,44,32,86,101,114,116,101,120,68,101,112,116,104,44,32,49,46,48,41,59,13,10,9,9,9,35,101,108,115,101,13,10,9,103,108,95,80,111,115,105,116,105,111,110,32,61,32,73,110,115,116,97,110,99,101,68,97,116,97,48,32,42,32,118,101,99,52,40,86,101,114,116,101,120,80,111,115,105,116,105,111,110,44,32,49,46,48,41,59,13,10,9,9,9,35,101,110,100,105,102,13,10,9,9,35,101,110,100,105,102,13,10,9,35,101,108,115,101,13,10,9,9,35,105,102,32,84,82,65,78,83,70,79,82,77,13,10,9,103,108,95,80,111,115,105,116,105,111,110,32,61,32,87,111,114,108,100,86,105,101,119,80,114,111,106,77,97,116,114,105,120,32,42,32,118,101,99,52,40,86,101,114,116,101,120,80,111,115,105,116,105,111,110,44,32,49,46,48,41,59,13,10,9,9,35,101,108,115,101,13,10,9,9,9,35,105,102,32,85,78,73,70,79,82,77,95,86,69,82,84,69,88,95,68,69,80,84,72,13,10,9,103,108,95,80,111,115,105,116,105,111,110,32,61,32,118,101,99,52,40,86,101,114,116,101,120,80,111,115,105,116,105,111,110,46,120,121,44,32,86,101,114,116,101,120,68,101,112,116,104,44,32,49,46,48,41,59,13,10,9,9,9,35,101,108,115,101,13,10,9,103,108,95,80,111,115,105,116,105,111,110,32,61,32,118,101,99,52,40,86,101,114,116,101,120,80,111,115,105,116,105,111,110,44,32,49,46,48,41,59,13,10,9,9,9,35,101,110,100,105,102,13,10,9,9,35,101,110,100,105,102,13,10,9,35,101,110,100,105,102,13,10,13,10,9,116,101,120,67,111,111,114,100,115,32,61,32,86,101,114,116,101,120,84,101,120,67,111,111,114,100,59,13,10,35,101,110,100,105,102,13,10,13,10,9,118,67,111,108,111,114,32,61,32,99,111,108,111,114,59,13,10,13,10,35,105,102,32,76,73,71,72,84,73,78,71,13,10,9,35,105,102,32,70,76,65,71,95,73,78,83,84,65,78,67,73,78,71,13,10,9,109,97,116,51,32,114,111,116,97,116,105,111,110,77,97,116,114,105,120,32,61,32,109,97,116,51,40,73,110,115,116,97,110,99,101,68,97,116,97,48,41,59,13,10,9,35,101,108,115,101,13,10,9,109,97,116,51,32,114,111,116,97,116,105,111,110,77,97,116,114,105,120,32,61,32,109,97,116,51,40,87,111,114,108,100,77,97,116,114,105,120,41,59,13,10,9,35,101,110,100,105,102,13,10,9,13,10,9,35,105,102,32,67,79,77,80,85,84,69,95,84,66,78,77,65,84,82,73,88,13,10,9,118,101,99,51,32,98,105,110,111,114,109,97,108,32,61,32,99,114,111,115,115,40,86,101,114,116,101,120,78,111,114,109,97,108,44,32,86,101,114,116,101,120,84,97,110,103,101,110,116,41,59,13,10,9,118,76,105,103,104,116,84,111,87,111,114,108,100,91,48,93,32,61,32,110,111,114,109,97,108,105,122,101,40,114,111,116,97,116,105,111,110,77,97,116,114,105,120,32,42,32,86,101,114,116,101,120,84,97,110,103,101,110,116,41,59,13,10,9,118,76,105,103,104,116,84,111,87,111,114,108,100,91,49,93,32,61,32,110,111,114,109,97,108,105,122,101,40,114,111,116,97,116,105,111,110,77,97,116,114,105,120,32,42,32,98,105,110,111,114,109,97,108,41,59,13,10,9,118,76,105,103,104,116,84,111,87,111,114,108,100,91,50,93,32,61,32,110,111,114,109,97,108,105,122,101,40,114,111,116,97,116,105,111,110,77,97,116,114,105,120,32,42,32,86,101,114,116,101,120,78,111,114,109,97,108,41,59,13,10,9,35,101,108,115,101,13,10,9,118,78,111,114,109,97,108,32,61,32,110,111,114,109,97,108,105,122,101,40,114,111,116,97,116,105,111,110,77,97,116,114,105,120,32,42,32,86,101,114,116,101,120,78,111,114,109,97,108,41,59,13,10,9,35,101,110,100,105,102,13,10,35,101,110,100,105,102,13,10,13,10,35,105,102,32,84,69,88,84,85,82,69,95,77,65,80,80,73,78,71,13,10,9,118,84,101,120,67,111,111,114,100,32,61,32,86,101,114,116,101,120,84,101,120,67,111,111,114,100,59,13,10,35,101,110,100,105,102,13,10,13,10,35,105,102,32,76,73,71,72,84,73,78,71,32,38,38,32,80,65,82,65,76,76,65,88,95,77,65,80,80,73,78,71,13,10,9,118,86,105,101,119,68,105,114,32,61,32,69,121,101,80,111,115,105,116,105,111,110,32,45,32,86,101,114,116,101,120,80,111,115,105,116,105,111,110,59,32,13,10,9,118,86,105,101,119,68,105,114,32,42,61,32,118,76,105,103,104,116,84,111,87,111,114,108,100,59,13,10,35,101,110,100,105,102,13,10,13,10,35,105,102,32,76,73,71,72,84,73,78,71,32,38,38,32,33,70,76,65,71,95,68,69,70,69,82,82,69,68,13,10,9,35,105,102,32,70,76,65,71,95,73,78,83,84,65,78,67,73,78,71,13,10,9,118,87,111,114,108,100,80,111,115,32,61,32,118,101,99,51,40,73,110,115,116,97,110,99,101,68,97,116,97,48,32,42,32,118,101,99,52,40,86,101,114,116,101,120,80,111,115,105,116,105,111,110,44,32,49,46,48,41,41,59,13,10,9,35,101,108,115,101,13,10,9,118,87,111,114,108,100,80,111,115,32,61,32,118,101,99,51,40,87,111,114,108,100,77,97,116,114,105,120,32,42,32,118,101,99,52,40,86,101,114,116,101,120,80,111,115,105,116,105,111,110,44,32,49,46,48,41,41,59,13,10,9,35,101,110,100,105,102,13,10,35,101,110,100,105,102,13,10,125,13,10, \ No newline at end of file +47,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,69,110,116,114,97,110,116,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,47,13,10,35,105,102,32,70,76,65,71,95,66,73,76,76,66,79,65,82,68,13,10,105,110,32,118,101,99,51,32,73,110,115,116,97,110,99,101,68,97,116,97,48,59,32,47,47,32,99,101,110,116,101,114,13,10,105,110,32,118,101,99,52,32,73,110,115,116,97,110,99,101,68,97,116,97,49,59,32,47,47,32,115,105,122,101,32,124,32,115,105,110,32,99,111,115,13,10,105,110,32,118,101,99,52,32,73,110,115,116,97,110,99,101,68,97,116,97,50,59,32,47,47,32,99,111,108,111,114,13,10,35,101,108,115,101,13,10,105,110,32,109,97,116,52,32,73,110,115,116,97,110,99,101,68,97,116,97,48,59,13,10,35,101,110,100,105,102,13,10,13,10,105,110,32,118,101,99,52,32,86,101,114,116,101,120,67,111,108,111,114,59,13,10,105,110,32,118,101,99,51,32,86,101,114,116,101,120,80,111,115,105,116,105,111,110,59,13,10,105,110,32,118,101,99,51,32,86,101,114,116,101,120,78,111,114,109,97,108,59,13,10,105,110,32,118,101,99,51,32,86,101,114,116,101,120,84,97,110,103,101,110,116,59,13,10,105,110,32,118,101,99,50,32,86,101,114,116,101,120,84,101,120,67,111,111,114,100,59,13,10,13,10,47,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,83,111,114,116,97,110,116,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,47,13,10,111,117,116,32,118,101,99,52,32,118,67,111,108,111,114,59,13,10,111,117,116,32,118,101,99,52,32,118,76,105,103,104,116,83,112,97,99,101,80,111,115,91,51,93,59,13,10,111,117,116,32,109,97,116,51,32,118,76,105,103,104,116,84,111,87,111,114,108,100,59,13,10,111,117,116,32,118,101,99,51,32,118,78,111,114,109,97,108,59,13,10,111,117,116,32,118,101,99,50,32,118,84,101,120,67,111,111,114,100,59,13,10,111,117,116,32,118,101,99,51,32,118,86,105,101,119,68,105,114,59,13,10,111,117,116,32,118,101,99,51,32,118,87,111,114,108,100,80,111,115,59,13,10,13,10,47,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,85,110,105,102,111,114,109,101,115,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,47,13,10,117,110,105,102,111,114,109,32,118,101,99,51,32,69,121,101,80,111,115,105,116,105,111,110,59,13,10,117,110,105,102,111,114,109,32,109,97,116,52,32,73,110,118,86,105,101,119,77,97,116,114,105,120,59,13,10,117,110,105,102,111,114,109,32,109,97,116,52,32,76,105,103,104,116,86,105,101,119,80,114,111,106,77,97,116,114,105,120,91,51,93,59,13,10,117,110,105,102,111,114,109,32,102,108,111,97,116,32,86,101,114,116,101,120,68,101,112,116,104,59,13,10,117,110,105,102,111,114,109,32,109,97,116,52,32,86,105,101,119,80,114,111,106,77,97,116,114,105,120,59,13,10,117,110,105,102,111,114,109,32,109,97,116,52,32,87,111,114,108,100,77,97,116,114,105,120,59,13,10,117,110,105,102,111,114,109,32,109,97,116,52,32,87,111,114,108,100,86,105,101,119,80,114,111,106,77,97,116,114,105,120,59,13,10,13,10,47,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,70,111,110,99,116,105,111,110,115,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,47,13,10,118,111,105,100,32,109,97,105,110,40,41,13,10,123,13,10,35,105,102,32,70,76,65,71,95,86,69,82,84,69,88,67,79,76,79,82,13,10,9,118,101,99,52,32,99,111,108,111,114,32,61,32,86,101,114,116,101,120,67,111,108,111,114,59,13,10,35,101,108,115,101,13,10,9,118,101,99,52,32,99,111,108,111,114,32,61,32,118,101,99,52,40,49,46,48,41,59,13,10,35,101,110,100,105,102,13,10,13,10,9,118,101,99,50,32,116,101,120,67,111,111,114,100,115,59,13,10,13,10,35,105,102,32,70,76,65,71,95,66,73,76,76,66,79,65,82,68,13,10,9,35,105,102,32,70,76,65,71,95,73,78,83,84,65,78,67,73,78,71,13,10,9,118,101,99,51,32,98,105,108,108,98,111,97,114,100,67,101,110,116,101,114,32,61,32,73,110,115,116,97,110,99,101,68,97,116,97,48,59,13,10,9,118,101,99,50,32,98,105,108,108,98,111,97,114,100,83,105,122,101,32,61,32,73,110,115,116,97,110,99,101,68,97,116,97,49,46,120,121,59,13,10,9,118,101,99,50,32,98,105,108,108,98,111,97,114,100,83,105,110,67,111,115,32,61,32,73,110,115,116,97,110,99,101,68,97,116,97,49,46,122,119,59,13,10,9,118,101,99,52,32,98,105,108,108,98,111,97,114,100,67,111,108,111,114,32,61,32,73,110,115,116,97,110,99,101,68,97,116,97,50,59,13,10,13,10,9,118,101,99,50,32,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,59,13,10,9,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,46,120,32,61,32,86,101,114,116,101,120,80,111,115,105,116,105,111,110,46,120,42,98,105,108,108,98,111,97,114,100,83,105,110,67,111,115,46,121,32,45,32,86,101,114,116,101,120,80,111,115,105,116,105,111,110,46,121,42,98,105,108,108,98,111,97,114,100,83,105,110,67,111,115,46,120,59,13,10,9,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,46,121,32,61,32,86,101,114,116,101,120,80,111,115,105,116,105,111,110,46,121,42,98,105,108,108,98,111,97,114,100,83,105,110,67,111,115,46,121,32,43,32,86,101,114,116,101,120,80,111,115,105,116,105,111,110,46,120,42,98,105,108,108,98,111,97,114,100,83,105,110,67,111,115,46,120,59,13,10,9,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,32,42,61,32,98,105,108,108,98,111,97,114,100,83,105,122,101,59,13,10,13,10,9,118,101,99,51,32,99,97,109,101,114,97,82,105,103,104,116,32,61,32,118,101,99,51,40,86,105,101,119,77,97,116,114,105,120,91,48,93,91,48,93,44,32,86,105,101,119,77,97,116,114,105,120,91,49,93,91,48,93,44,32,86,105,101,119,77,97,116,114,105,120,91,50,93,91,48,93,41,59,13,10,9,118,101,99,51,32,99,97,109,101,114,97,85,112,32,61,32,118,101,99,51,40,86,105,101,119,77,97,116,114,105,120,91,48,93,91,49,93,44,32,86,105,101,119,77,97,116,114,105,120,91,49,93,91,49,93,44,32,86,105,101,119,77,97,116,114,105,120,91,50,93,91,49,93,41,59,13,10,9,118,101,99,51,32,118,101,114,116,101,120,80,111,115,32,61,32,98,105,108,108,98,111,97,114,100,67,101,110,116,101,114,32,43,32,99,97,109,101,114,97,82,105,103,104,116,42,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,46,120,32,43,32,99,97,109,101,114,97,85,112,42,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,46,121,59,13,10,13,10,9,103,108,95,80,111,115,105,116,105,111,110,32,61,32,86,105,101,119,80,114,111,106,77,97,116,114,105,120,32,42,32,118,101,99,52,40,118,101,114,116,101,120,80,111,115,44,32,49,46,48,41,59,13,10,9,99,111,108,111,114,32,61,32,98,105,108,108,98,111,97,114,100,67,111,108,111,114,59,13,10,9,116,101,120,67,111,111,114,100,115,32,61,32,86,101,114,116,101,120,80,111,115,105,116,105,111,110,46,120,121,32,43,32,48,46,53,59,13,10,9,35,101,108,115,101,13,10,9,118,101,99,50,32,98,105,108,108,98,111,97,114,100,67,111,114,110,101,114,32,61,32,86,101,114,116,101,120,84,101,120,67,111,111,114,100,32,45,32,48,46,53,59,13,10,9,118,101,99,50,32,98,105,108,108,98,111,97,114,100,83,105,122,101,32,61,32,86,101,114,116,101,120,85,115,101,114,100,97,116,97,48,46,120,121,59,13,10,9,118,101,99,50,32,98,105,108,108,98,111,97,114,100,83,105,110,67,111,115,32,61,32,86,101,114,116,101,120,85,115,101,114,100,97,116,97,48,46,122,119,59,13,10,9,13,10,9,118,101,99,50,32,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,59,13,10,9,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,46,120,32,61,32,98,105,108,108,98,111,97,114,100,67,111,114,110,101,114,46,120,42,98,105,108,108,98,111,97,114,100,83,105,110,67,111,115,46,121,32,45,32,98,105,108,108,98,111,97,114,100,67,111,114,110,101,114,46,121,42,98,105,108,108,98,111,97,114,100,83,105,110,67,111,115,46,120,59,13,10,9,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,46,121,32,61,32,98,105,108,108,98,111,97,114,100,67,111,114,110,101,114,46,121,42,98,105,108,108,98,111,97,114,100,83,105,110,67,111,115,46,121,32,43,32,98,105,108,108,98,111,97,114,100,67,111,114,110,101,114,46,120,42,98,105,108,108,98,111,97,114,100,83,105,110,67,111,115,46,120,59,13,10,9,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,32,42,61,32,98,105,108,108,98,111,97,114,100,83,105,122,101,59,13,10,13,10,9,118,101,99,51,32,99,97,109,101,114,97,82,105,103,104,116,32,61,32,118,101,99,51,40,86,105,101,119,77,97,116,114,105,120,91,48,93,91,48,93,44,32,86,105,101,119,77,97,116,114,105,120,91,49,93,91,48,93,44,32,86,105,101,119,77,97,116,114,105,120,91,50,93,91,48,93,41,59,13,10,9,118,101,99,51,32,99,97,109,101,114,97,85,112,32,61,32,118,101,99,51,40,86,105,101,119,77,97,116,114,105,120,91,48,93,91,49,93,44,32,86,105,101,119,77,97,116,114,105,120,91,49,93,91,49,93,44,32,86,105,101,119,77,97,116,114,105,120,91,50,93,91,49,93,41,59,13,10,9,118,101,99,51,32,118,101,114,116,101,120,80,111,115,32,61,32,86,101,114,116,101,120,80,111,115,105,116,105,111,110,32,43,32,99,97,109,101,114,97,82,105,103,104,116,42,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,46,120,32,43,32,99,97,109,101,114,97,85,112,42,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,46,121,59,13,10,13,10,9,103,108,95,80,111,115,105,116,105,111,110,32,61,32,86,105,101,119,80,114,111,106,77,97,116,114,105,120,32,42,32,118,101,99,52,40,118,101,114,116,101,120,80,111,115,44,32,49,46,48,41,59,13,10,9,116,101,120,67,111,111,114,100,115,32,61,32,86,101,114,116,101,120,84,101,120,67,111,111,114,100,59,13,10,9,35,101,110,100,105,102,13,10,35,101,108,115,101,13,10,9,35,105,102,32,70,76,65,71,95,73,78,83,84,65,78,67,73,78,71,13,10,9,9,35,105,102,32,84,82,65,78,83,70,79,82,77,13,10,9,103,108,95,80,111,115,105,116,105,111,110,32,61,32,86,105,101,119,80,114,111,106,77,97,116,114,105,120,32,42,32,73,110,115,116,97,110,99,101,68,97,116,97,48,32,42,32,118,101,99,52,40,86,101,114,116,101,120,80,111,115,105,116,105,111,110,44,32,49,46,48,41,59,13,10,9,9,35,101,108,115,101,13,10,9,9,9,35,105,102,32,85,78,73,70,79,82,77,95,86,69,82,84,69,88,95,68,69,80,84,72,13,10,9,103,108,95,80,111,115,105,116,105,111,110,32,61,32,73,110,115,116,97,110,99,101,68,97,116,97,48,32,42,32,118,101,99,52,40,86,101,114,116,101,120,80,111,115,105,116,105,111,110,46,120,121,44,32,86,101,114,116,101,120,68,101,112,116,104,44,32,49,46,48,41,59,13,10,9,9,9,35,101,108,115,101,13,10,9,103,108,95,80,111,115,105,116,105,111,110,32,61,32,73,110,115,116,97,110,99,101,68,97,116,97,48,32,42,32,118,101,99,52,40,86,101,114,116,101,120,80,111,115,105,116,105,111,110,44,32,49,46,48,41,59,13,10,9,9,9,35,101,110,100,105,102,13,10,9,9,35,101,110,100,105,102,13,10,9,35,101,108,115,101,13,10,9,9,35,105,102,32,84,82,65,78,83,70,79,82,77,13,10,9,103,108,95,80,111,115,105,116,105,111,110,32,61,32,87,111,114,108,100,86,105,101,119,80,114,111,106,77,97,116,114,105,120,32,42,32,118,101,99,52,40,86,101,114,116,101,120,80,111,115,105,116,105,111,110,44,32,49,46,48,41,59,13,10,9,9,35,101,108,115,101,13,10,9,9,9,35,105,102,32,85,78,73,70,79,82,77,95,86,69,82,84,69,88,95,68,69,80,84,72,13,10,9,103,108,95,80,111,115,105,116,105,111,110,32,61,32,118,101,99,52,40,86,101,114,116,101,120,80,111,115,105,116,105,111,110,46,120,121,44,32,86,101,114,116,101,120,68,101,112,116,104,44,32,49,46,48,41,59,13,10,9,9,9,35,101,108,115,101,13,10,9,103,108,95,80,111,115,105,116,105,111,110,32,61,32,118,101,99,52,40,86,101,114,116,101,120,80,111,115,105,116,105,111,110,44,32,49,46,48,41,59,13,10,9,9,9,35,101,110,100,105,102,13,10,9,9,35,101,110,100,105,102,13,10,9,35,101,110,100,105,102,13,10,13,10,9,116,101,120,67,111,111,114,100,115,32,61,32,86,101,114,116,101,120,84,101,120,67,111,111,114,100,59,13,10,35,101,110,100,105,102,13,10,13,10,9,118,67,111,108,111,114,32,61,32,99,111,108,111,114,59,13,10,13,10,35,105,102,32,76,73,71,72,84,73,78,71,13,10,9,35,105,102,32,70,76,65,71,95,73,78,83,84,65,78,67,73,78,71,13,10,9,109,97,116,51,32,114,111,116,97,116,105,111,110,77,97,116,114,105,120,32,61,32,109,97,116,51,40,73,110,115,116,97,110,99,101,68,97,116,97,48,41,59,13,10,9,35,101,108,115,101,13,10,9,109,97,116,51,32,114,111,116,97,116,105,111,110,77,97,116,114,105,120,32,61,32,109,97,116,51,40,87,111,114,108,100,77,97,116,114,105,120,41,59,13,10,9,35,101,110,100,105,102,13,10,9,13,10,9,35,105,102,32,67,79,77,80,85,84,69,95,84,66,78,77,65,84,82,73,88,13,10,9,118,101,99,51,32,98,105,110,111,114,109,97,108,32,61,32,99,114,111,115,115,40,86,101,114,116,101,120,78,111,114,109,97,108,44,32,86,101,114,116,101,120,84,97,110,103,101,110,116,41,59,13,10,9,118,76,105,103,104,116,84,111,87,111,114,108,100,91,48,93,32,61,32,110,111,114,109,97,108,105,122,101,40,114,111,116,97,116,105,111,110,77,97,116,114,105,120,32,42,32,86,101,114,116,101,120,84,97,110,103,101,110,116,41,59,13,10,9,118,76,105,103,104,116,84,111,87,111,114,108,100,91,49,93,32,61,32,110,111,114,109,97,108,105,122,101,40,114,111,116,97,116,105,111,110,77,97,116,114,105,120,32,42,32,98,105,110,111,114,109,97,108,41,59,13,10,9,118,76,105,103,104,116,84,111,87,111,114,108,100,91,50,93,32,61,32,110,111,114,109,97,108,105,122,101,40,114,111,116,97,116,105,111,110,77,97,116,114,105,120,32,42,32,86,101,114,116,101,120,78,111,114,109,97,108,41,59,13,10,9,35,101,108,115,101,13,10,9,118,78,111,114,109,97,108,32,61,32,110,111,114,109,97,108,105,122,101,40,114,111,116,97,116,105,111,110,77,97,116,114,105,120,32,42,32,86,101,114,116,101,120,78,111,114,109,97,108,41,59,13,10,9,35,101,110,100,105,102,13,10,35,101,110,100,105,102,13,10,13,10,35,105,102,32,83,72,65,68,79,87,95,77,65,80,80,73,78,71,13,10,9,102,111,114,32,40,105,110,116,32,105,32,61,32,48,59,32,105,32,60,32,51,59,32,43,43,105,41,13,10,9,9,118,76,105,103,104,116,83,112,97,99,101,80,111,115,91,105,93,32,61,32,76,105,103,104,116,86,105,101,119,80,114,111,106,77,97,116,114,105,120,91,105,93,32,42,32,87,111,114,108,100,77,97,116,114,105,120,32,42,32,118,101,99,52,40,86,101,114,116,101,120,80,111,115,105,116,105,111,110,44,32,49,46,48,41,59,13,10,35,101,110,100,105,102,13,10,13,10,35,105,102,32,84,69,88,84,85,82,69,95,77,65,80,80,73,78,71,13,10,9,118,84,101,120,67,111,111,114,100,32,61,32,86,101,114,116,101,120,84,101,120,67,111,111,114,100,59,13,10,35,101,110,100,105,102,13,10,13,10,35,105,102,32,76,73,71,72,84,73,78,71,32,38,38,32,80,65,82,65,76,76,65,88,95,77,65,80,80,73,78,71,13,10,9,118,86,105,101,119,68,105,114,32,61,32,69,121,101,80,111,115,105,116,105,111,110,32,45,32,86,101,114,116,101,120,80,111,115,105,116,105,111,110,59,32,13,10,9,118,86,105,101,119,68,105,114,32,42,61,32,118,76,105,103,104,116,84,111,87,111,114,108,100,59,13,10,35,101,110,100,105,102,13,10,13,10,35,105,102,32,76,73,71,72,84,73,78,71,32,38,38,32,33,70,76,65,71,95,68,69,70,69,82,82,69,68,13,10,9,35,105,102,32,70,76,65,71,95,73,78,83,84,65,78,67,73,78,71,13,10,9,118,87,111,114,108,100,80,111,115,32,61,32,118,101,99,51,40,73,110,115,116,97,110,99,101,68,97,116,97,48,32,42,32,118,101,99,52,40,86,101,114,116,101,120,80,111,115,105,116,105,111,110,44,32,49,46,48,41,41,59,13,10,9,35,101,108,115,101,13,10,9,118,87,111,114,108,100,80,111,115,32,61,32,118,101,99,51,40,87,111,114,108,100,77,97,116,114,105,120,32,42,32,118,101,99,52,40,86,101,114,116,101,120,80,111,115,105,116,105,111,110,44,32,49,46,48,41,41,59,13,10,9,35,101,110,100,105,102,13,10,35,101,110,100,105,102,13,10,125,13,10, \ No newline at end of file From 835da411c780971d48309bb189aac0161d532342 Mon Sep 17 00:00:00 2001 From: Lynix Date: Thu, 13 Aug 2015 13:54:34 +0200 Subject: [PATCH 28/37] Graphics/Shadows: Add directional shadow mapping (WIP) It still needs some debug Former-commit-id: 029872debc1a784712a33802ddd70a2b61e55623 --- SDK/include/NDK/Systems/RenderSystem.hpp | 5 +- SDK/src/NDK/Systems/RenderSystem.cpp | 79 +++++++++++++++++-- .../Nazara/Graphics/AbstractRenderQueue.hpp | 2 + .../Graphics/ForwardRenderTechnique.inl | 22 +++++- include/Nazara/Graphics/Light.hpp | 2 +- .../Graphics/ForwardRenderTechnique.cpp | 2 +- src/Nazara/Graphics/Light.cpp | 13 +-- .../Resources/Shaders/PhongLighting/core.frag | 15 ++-- .../Shaders/PhongLighting/core.frag.h | 2 +- 9 files changed, 118 insertions(+), 24 deletions(-) diff --git a/SDK/include/NDK/Systems/RenderSystem.hpp b/SDK/include/NDK/Systems/RenderSystem.hpp index 91f63f8ed..9df56bc49 100644 --- a/SDK/include/NDK/Systems/RenderSystem.hpp +++ b/SDK/include/NDK/Systems/RenderSystem.hpp @@ -37,11 +37,14 @@ namespace Ndk void OnEntityRemoved(Entity* entity) override; void OnEntityValidation(Entity* entity, bool justAdded) override; void OnUpdate(float elapsedTime) override; - void UpdateShadowMaps(); + void UpdateDirectionalShadowMaps(const NzAbstractViewer& viewer); + void UpdatePointSpotShadowMaps(); EntityList m_cameras; EntityList m_drawables; + EntityList m_directionalLights; EntityList m_lights; + EntityList m_pointSpotLights; NzBackgroundRef m_background; NzDepthRenderTechnique m_shadowTechnique; NzForwardRenderTechnique m_renderTechnique; diff --git a/SDK/src/NDK/Systems/RenderSystem.cpp b/SDK/src/NDK/Systems/RenderSystem.cpp index f4c8fe82c..742dcd363 100644 --- a/SDK/src/NDK/Systems/RenderSystem.cpp +++ b/SDK/src/NDK/Systems/RenderSystem.cpp @@ -46,21 +46,40 @@ namespace Ndk m_drawables.Remove(entity); if (entity->HasComponent() && entity->HasComponent()) + { + LightComponent& lightComponent = entity->GetComponent(); + if (lightComponent.GetLightType() == nzLightType_Directional) + { + m_directionalLights.Insert(entity); + m_pointSpotLights.Remove(entity); + } + else + { + m_directionalLights.Remove(entity); + m_pointSpotLights.Insert(entity); + } + m_lights.Insert(entity); + } else + { + m_directionalLights.Remove(entity); m_lights.Remove(entity); + m_pointSpotLights.Remove(entity); + } } void RenderSystem::OnUpdate(float elapsedTime) { NazaraUnused(elapsedTime); - UpdateShadowMaps(); + UpdatePointSpotShadowMaps(); for (const Ndk::EntityHandle& camera : m_cameras) { CameraComponent& camComponent = camera->GetComponent(); - camComponent.ApplyView(); + + //UpdateDirectionalShadowMaps(camComponent); NzAbstractRenderQueue* renderQueue = m_renderTechnique.GetRenderQueue(); renderQueue->Clear(); @@ -81,6 +100,8 @@ namespace Ndk lightComponent.AddToRenderQueue(renderQueue, lightNode.GetTransformMatrix()); } + camComponent.ApplyView(); + NzSceneData sceneData; sceneData.ambientColor = NzColor(25, 25, 25); sceneData.background = m_background; @@ -90,7 +111,7 @@ namespace Ndk } } - void RenderSystem::UpdateShadowMaps() + void RenderSystem::UpdateDirectionalShadowMaps(const NzAbstractViewer& viewer) { if (!m_shadowRT.IsValid()) m_shadowRT.Create(); @@ -100,18 +121,66 @@ namespace Ndk dummySceneData.background = nullptr; dummySceneData.viewer = nullptr; //< Depth technique doesn't require any viewer - for (const Ndk::EntityHandle& light : m_lights) + for (const Ndk::EntityHandle& light : m_directionalLights) { LightComponent& lightComponent = light->GetComponent(); NodeComponent& lightNode = light->GetComponent(); - if (!lightComponent.IsShadowCastingEnabled() || lightComponent.GetLightType() == nzLightType_Directional) + if (!lightComponent.IsShadowCastingEnabled()) + continue; + + NzVector2ui shadowMapSize(lightComponent.GetShadowMap()->GetSize()); + + m_shadowRT.AttachTexture(nzAttachmentPoint_Depth, 0, lightComponent.GetShadowMap()); + NzRenderer::SetTarget(&m_shadowRT); + NzRenderer::SetViewport(NzRecti(0, 0, shadowMapSize.x, shadowMapSize.y)); + + NzAbstractRenderQueue* renderQueue = m_shadowTechnique.GetRenderQueue(); + renderQueue->Clear(); + + ///TODO: Culling + for (const Ndk::EntityHandle& drawable : m_drawables) + { + GraphicsComponent& graphicsComponent = drawable->GetComponent(); + NodeComponent& drawableNode = drawable->GetComponent(); + + graphicsComponent.AddToRenderQueue(renderQueue); + } + + ///TODO: Cache the matrices in the light? + NzRenderer::SetMatrix(nzMatrixType_Projection, NzMatrix4f::Ortho(0.f, 100.f, 100.f, 0.f, 1.f, 100.f)); + NzRenderer::SetMatrix(nzMatrixType_View, NzMatrix4f::ViewMatrix(lightNode.GetRotation() * NzVector3f::Forward() * 100.f, lightNode.GetRotation())); + + m_shadowTechnique.Draw(dummySceneData); + } + } + + void RenderSystem::UpdatePointSpotShadowMaps() + { + if (!m_shadowRT.IsValid()) + m_shadowRT.Create(); + + NzSceneData dummySceneData; + dummySceneData.ambientColor = NzColor(0, 0, 0); + dummySceneData.background = nullptr; + dummySceneData.viewer = nullptr; //< Depth technique doesn't require any viewer + + for (const Ndk::EntityHandle& light : m_pointSpotLights) + { + LightComponent& lightComponent = light->GetComponent(); + NodeComponent& lightNode = light->GetComponent(); + + if (!lightComponent.IsShadowCastingEnabled()) continue; NzVector2ui shadowMapSize(lightComponent.GetShadowMap()->GetSize()); switch (lightComponent.GetLightType()) { + case nzLightType_Directional: + NazaraInternalError("Directional lights included in point/spot light list"); + break; + case nzLightType_Point: { static NzQuaternionf rotations[6] = diff --git a/include/Nazara/Graphics/AbstractRenderQueue.hpp b/include/Nazara/Graphics/AbstractRenderQueue.hpp index f7e0ad79d..fceabf47f 100644 --- a/include/Nazara/Graphics/AbstractRenderQueue.hpp +++ b/include/Nazara/Graphics/AbstractRenderQueue.hpp @@ -59,7 +59,9 @@ class NAZARA_GRAPHICS_API NzAbstractRenderQueue struct DirectionalLight { NzColor color; + NzMatrix4f transformMatrix; NzVector3f direction; + NzTexture* shadowMap; float ambientFactor; float diffuseFactor; }; diff --git a/include/Nazara/Graphics/ForwardRenderTechnique.inl b/include/Nazara/Graphics/ForwardRenderTechnique.inl index 2e9f46dd4..a04fab511 100644 --- a/include/Nazara/Graphics/ForwardRenderTechnique.inl +++ b/include/Nazara/Graphics/ForwardRenderTechnique.inl @@ -25,6 +25,20 @@ inline void NzForwardRenderTechnique::SendLightUniforms(const NzShader* shader, shader->SendColor(uniforms.locations.color + uniformOffset, light.color); shader->SendVector(uniforms.locations.factors + uniformOffset, NzVector2f(light.ambientFactor, light.diffuseFactor)); shader->SendVector(uniforms.locations.parameters1 + uniformOffset, NzVector4f(light.direction)); + + shader->SendBoolean(uniforms.locations.shadowMapping + uniformOffset, light.shadowMap != nullptr); + if (light.shadowMap) + { + NzRenderer::SetTexture(availableTextureUnit, light.shadowMap); + NzRenderer::SetTextureSampler(availableTextureUnit, s_shadowSampler); + + shader->SendMatrix(uniforms.locations.lightViewProjMatrix + index, light.transformMatrix); + shader->SendInteger(uniforms.locations.directionalSpotLightShadowMap + index, availableTextureUnit); + } + else + shader->SendInteger(uniforms.locations.directionalSpotLightShadowMap + index, dummyTexture); + + shader->SendInteger(uniforms.locations.pointLightShadowMap + index, dummyCubemap); break; } @@ -48,7 +62,7 @@ inline void NzForwardRenderTechnique::SendLightUniforms(const NzShader* shader, else shader->SendInteger(uniforms.locations.pointLightShadowMap + index, dummyCubemap); - shader->SendInteger(uniforms.locations.spotLightShadowMap + index, dummyTexture); + shader->SendInteger(uniforms.locations.directionalSpotLightShadowMap + index, dummyTexture); break; } @@ -69,10 +83,10 @@ inline void NzForwardRenderTechnique::SendLightUniforms(const NzShader* shader, NzRenderer::SetTextureSampler(availableTextureUnit, s_shadowSampler); shader->SendMatrix(uniforms.locations.lightViewProjMatrix + index, light.transformMatrix); - shader->SendInteger(uniforms.locations.spotLightShadowMap + index, availableTextureUnit); + shader->SendInteger(uniforms.locations.directionalSpotLightShadowMap + index, availableTextureUnit); } else - shader->SendInteger(uniforms.locations.spotLightShadowMap + index, dummyTexture); + shader->SendInteger(uniforms.locations.directionalSpotLightShadowMap + index, dummyTexture); shader->SendInteger(uniforms.locations.pointLightShadowMap + index, dummyCubemap); break; @@ -82,8 +96,8 @@ inline void NzForwardRenderTechnique::SendLightUniforms(const NzShader* shader, else { shader->SendInteger(uniforms.locations.type + uniformOffset, -1); //< Disable the light in the shader + shader->SendInteger(uniforms.locations.directionalSpotLightShadowMap + index, dummyTexture); shader->SendInteger(uniforms.locations.pointLightShadowMap + index, dummyCubemap); - shader->SendInteger(uniforms.locations.spotLightShadowMap + index, dummyTexture); } } diff --git a/include/Nazara/Graphics/Light.hpp b/include/Nazara/Graphics/Light.hpp index a8cdaf191..a9a4a781f 100644 --- a/include/Nazara/Graphics/Light.hpp +++ b/include/Nazara/Graphics/Light.hpp @@ -97,6 +97,7 @@ struct NzLightUniforms { int type; int color; + int directionalSpotLightShadowMap; int factors; int lightViewProjMatrix; int parameters1; @@ -104,7 +105,6 @@ struct NzLightUniforms int parameters3; int pointLightShadowMap; int shadowMapping; - int spotLightShadowMap; }; bool ubo; diff --git a/src/Nazara/Graphics/ForwardRenderTechnique.cpp b/src/Nazara/Graphics/ForwardRenderTechnique.cpp index b8611feaa..5c3b29bca 100644 --- a/src/Nazara/Graphics/ForwardRenderTechnique.cpp +++ b/src/Nazara/Graphics/ForwardRenderTechnique.cpp @@ -769,7 +769,7 @@ const NzForwardRenderTechnique::ShaderUniforms* NzForwardRenderTechnique::GetSha uniforms.lightUniforms.locations.parameters3 = shader->GetUniformLocation("Lights[0].parameters3"); uniforms.lightUniforms.locations.pointLightShadowMap = shader->GetUniformLocation("PointLightShadowMap[0]"); uniforms.lightUniforms.locations.shadowMapping = shader->GetUniformLocation("Lights[0].shadowMapping"); - uniforms.lightUniforms.locations.spotLightShadowMap = shader->GetUniformLocation("SpotLightShadowMap[0]"); + uniforms.lightUniforms.locations.directionalSpotLightShadowMap = shader->GetUniformLocation("DirectionalSpotLightShadowMap[0]"); } else uniforms.hasLightUniforms = false; diff --git a/src/Nazara/Graphics/Light.cpp b/src/Nazara/Graphics/Light.cpp index 4fc4506e7..43bbf9b0e 100644 --- a/src/Nazara/Graphics/Light.cpp +++ b/src/Nazara/Graphics/Light.cpp @@ -33,6 +33,11 @@ m_shadowMapUpdated(false) void NzLight::AddToRenderQueue(NzAbstractRenderQueue* renderQueue, const NzMatrix4f& transformMatrix) const { + static NzMatrix4f biasMatrix(0.5f, 0.f, 0.f, 0.f, + 0.f, 0.5f, 0.f, 0.f, + 0.f, 0.f, 0.5f, 0.f, + 0.5f, 0.5f, 0.5f, 1.f); + switch (m_type) { case nzLightType_Directional: @@ -42,6 +47,8 @@ void NzLight::AddToRenderQueue(NzAbstractRenderQueue* renderQueue, const NzMatri light.color = m_color; light.diffuseFactor = m_diffuseFactor; light.direction = transformMatrix.Transform(NzVector3f::Forward(), 0.f); + light.shadowMap = m_shadowMap.Get(); + light.transformMatrix = NzMatrix4f::ViewMatrix(transformMatrix.GetRotation() * NzVector3f::Forward() * 100.f, transformMatrix.GetRotation()) * NzMatrix4f::Ortho(0.f, 100.f, 100.f, 0.f, 1.f, 100.f) * biasMatrix; renderQueue->AddDirectionalLight(light); break; @@ -78,12 +85,6 @@ void NzLight::AddToRenderQueue(NzAbstractRenderQueue* renderQueue, const NzMatri light.position = transformMatrix.GetTranslation(); light.radius = m_radius; light.shadowMap = m_shadowMap.Get(); - - static NzMatrix4f biasMatrix(0.5f, 0.f, 0.f, 0.f, - 0.f, 0.5f, 0.f, 0.f, - 0.f, 0.f, 0.5f, 0.f, - 0.5f, 0.5f, 0.5f, 1.f); - light.transformMatrix = NzMatrix4f::ViewMatrix(transformMatrix.GetTranslation(), transformMatrix.GetRotation()) * NzMatrix4f::Perspective(m_outerAngle*2.f, 1.f, 0.1f, m_radius) * biasMatrix; renderQueue->AddSpotLight(light); diff --git a/src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.frag b/src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.frag index e80279b7d..6f4b1e3aa 100644 --- a/src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.frag +++ b/src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.frag @@ -36,7 +36,7 @@ struct Light // Lumières uniform Light Lights[3]; uniform samplerCube PointLightShadowMap[3]; -uniform sampler2D SpotLightShadowMap[3]; +uniform sampler2D DirectionalSpotLightShadowMap[3]; // Matériau uniform sampler2D MaterialAlphaMap; @@ -94,10 +94,10 @@ float VectorToDepthValue(vec3 vec, float zNear, float zFar) return (normZ + 1.0) * 0.5; } -bool TestShadowDirectional() +bool TestShadowDirectional(int lightIndex) { - ///TODO - return true; + vec4 lightSpacePos = vLightSpacePos[lightIndex]; + return texture(DirectionalSpotLightShadowMap[lightIndex], lightSpacePos.xy).x >= (lightSpacePos.z - 0.0005); } bool TestShadowPoint(int lightIndex, vec3 lightToWorld, float zNear, float zFar) @@ -108,7 +108,7 @@ bool TestShadowPoint(int lightIndex, vec3 lightToWorld, float zNear, float zFar) bool TestShadowSpot(int lightIndex) { vec4 lightSpacePos = vLightSpacePos[lightIndex]; - return textureProj(SpotLightShadowMap[lightIndex], lightSpacePos.xyw).x >= (lightSpacePos.z - 0.0005)/lightSpacePos.w; + return textureProj(DirectionalSpotLightShadowMap[lightIndex], lightSpacePos.xyw).x >= (lightSpacePos.z - 0.0005)/lightSpacePos.w; } void main() @@ -211,6 +211,11 @@ void main() // Ambient lightAmbient += lightColor.rgb * lightAmbientFactor * (MaterialAmbient.rgb + SceneAmbient.rgb); + #if SHADOW_MAPPING + if (Lights[i].shadowMapping && !TestShadowDirectional(i)) + break; + #endif + // Diffuse float lambert = max(dot(normal, lightDir), 0.0); diff --git a/src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.frag.h b/src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.frag.h index ca82b7284..d617f915b 100644 --- a/src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.frag.h +++ b/src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.frag.h @@ -1 +1 @@ -35,105,102,32,69,65,82,76,89,95,70,82,65,71,77,69,78,84,95,84,69,83,84,83,32,38,38,32,33,65,76,80,72,65,95,84,69,83,84,13,10,108,97,121,111,117,116,40,101,97,114,108,121,95,102,114,97,103,109,101,110,116,95,116,101,115,116,115,41,32,105,110,59,13,10,35,101,110,100,105,102,13,10,13,10,35,100,101,102,105,110,101,32,76,73,71,72,84,95,68,73,82,69,67,84,73,79,78,65,76,32,48,13,10,35,100,101,102,105,110,101,32,76,73,71,72,84,95,80,79,73,78,84,32,49,13,10,35,100,101,102,105,110,101,32,76,73,71,72,84,95,83,80,79,84,32,50,13,10,13,10,47,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,69,110,116,114,97,110,116,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,47,13,10,105,110,32,118,101,99,52,32,118,67,111,108,111,114,59,13,10,105,110,32,118,101,99,52,32,118,76,105,103,104,116,83,112,97,99,101,80,111,115,91,51,93,59,13,10,105,110,32,109,97,116,51,32,118,76,105,103,104,116,84,111,87,111,114,108,100,59,13,10,105,110,32,118,101,99,51,32,118,78,111,114,109,97,108,59,13,10,105,110,32,118,101,99,50,32,118,84,101,120,67,111,111,114,100,59,13,10,105,110,32,118,101,99,51,32,118,86,105,101,119,68,105,114,59,13,10,105,110,32,118,101,99,51,32,118,87,111,114,108,100,80,111,115,59,13,10,13,10,47,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,83,111,114,116,97,110,116,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,47,13,10,111,117,116,32,118,101,99,52,32,82,101,110,100,101,114,84,97,114,103,101,116,48,59,13,10,111,117,116,32,118,101,99,52,32,82,101,110,100,101,114,84,97,114,103,101,116,49,59,13,10,111,117,116,32,118,101,99,52,32,82,101,110,100,101,114,84,97,114,103,101,116,50,59,13,10,13,10,47,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,85,110,105,102,111,114,109,101,115,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,47,13,10,115,116,114,117,99,116,32,76,105,103,104,116,13,10,123,13,10,9,105,110,116,32,116,121,112,101,59,13,10,9,118,101,99,52,32,99,111,108,111,114,59,13,10,9,118,101,99,50,32,102,97,99,116,111,114,115,59,13,10,13,10,9,118,101,99,52,32,112,97,114,97,109,101,116,101,114,115,49,59,13,10,9,118,101,99,52,32,112,97,114,97,109,101,116,101,114,115,50,59,13,10,9,118,101,99,50,32,112,97,114,97,109,101,116,101,114,115,51,59,13,10,9,98,111,111,108,32,115,104,97,100,111,119,77,97,112,112,105,110,103,59,13,10,125,59,13,10,13,10,47,47,32,76,117,109,105,195,168,114,101,115,13,10,117,110,105,102,111,114,109,32,76,105,103,104,116,32,76,105,103,104,116,115,91,51,93,59,13,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,67,117,98,101,32,80,111,105,110,116,76,105,103,104,116,83,104,97,100,111,119,77,97,112,91,51,93,59,13,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,83,112,111,116,76,105,103,104,116,83,104,97,100,111,119,77,97,112,91,51,93,59,13,10,13,10,47,47,32,77,97,116,195,169,114,105,97,117,13,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,77,97,116,101,114,105,97,108,65,108,112,104,97,77,97,112,59,13,10,117,110,105,102,111,114,109,32,102,108,111,97,116,32,77,97,116,101,114,105,97,108,65,108,112,104,97,84,104,114,101,115,104,111,108,100,59,13,10,117,110,105,102,111,114,109,32,118,101,99,52,32,77,97,116,101,114,105,97,108,65,109,98,105,101,110,116,59,13,10,117,110,105,102,111,114,109,32,118,101,99,52,32,77,97,116,101,114,105,97,108,68,105,102,102,117,115,101,59,13,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,77,97,116,101,114,105,97,108,68,105,102,102,117,115,101,77,97,112,59,13,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,77,97,116,101,114,105,97,108,69,109,105,115,115,105,118,101,77,97,112,59,13,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,77,97,116,101,114,105,97,108,72,101,105,103,104,116,77,97,112,59,13,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,77,97,116,101,114,105,97,108,78,111,114,109,97,108,77,97,112,59,13,10,117,110,105,102,111,114,109,32,102,108,111,97,116,32,77,97,116,101,114,105,97,108,83,104,105,110,105,110,101,115,115,59,13,10,117,110,105,102,111,114,109,32,118,101,99,52,32,77,97,116,101,114,105,97,108,83,112,101,99,117,108,97,114,59,13,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,77,97,116,101,114,105,97,108,83,112,101,99,117,108,97,114,77,97,112,59,13,10,13,10,47,47,32,65,117,116,114,101,115,13,10,117,110,105,102,111,114,109,32,102,108,111,97,116,32,80,97,114,97,108,108,97,120,66,105,97,115,32,61,32,45,48,46,48,51,59,13,10,117,110,105,102,111,114,109,32,102,108,111,97,116,32,80,97,114,97,108,108,97,120,83,99,97,108,101,32,61,32,48,46,48,50,59,13,10,117,110,105,102,111,114,109,32,118,101,99,50,32,73,110,118,84,97,114,103,101,116,83,105,122,101,59,13,10,117,110,105,102,111,114,109,32,118,101,99,51,32,69,121,101,80,111,115,105,116,105,111,110,59,13,10,117,110,105,102,111,114,109,32,118,101,99,52,32,83,99,101,110,101,65,109,98,105,101,110,116,59,13,10,13,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,84,101,120,116,117,114,101,79,118,101,114,108,97,121,59,13,10,13,10,47,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,70,111,110,99,116,105,111,110,115,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,47,13,10,118,101,99,51,32,70,108,111,97,116,84,111,67,111,108,111,114,40,102,108,111,97,116,32,102,41,13,10,123,13,10,9,118,101,99,51,32,99,111,108,111,114,59,13,10,13,10,9,102,32,42,61,32,50,53,54,46,48,59,13,10,9,99,111,108,111,114,46,120,32,61,32,102,108,111,111,114,40,102,41,59,13,10,13,10,9,102,32,61,32,40,102,32,45,32,99,111,108,111,114,46,120,41,32,42,32,50,53,54,46,48,59,13,10,9,99,111,108,111,114,46,121,32,61,32,102,108,111,111,114,40,102,41,59,13,10,13,10,9,99,111,108,111,114,46,122,32,61,32,102,32,45,32,99,111,108,111,114,46,121,59,13,10,9,99,111,108,111,114,46,120,121,32,42,61,32,48,46,48,48,51,57,48,54,50,53,59,32,47,47,32,42,61,32,49,46,48,47,50,53,54,13,10,13,10,9,114,101,116,117,114,110,32,99,111,108,111,114,59,13,10,125,13,10,13,10,35,100,101,102,105,110,101,32,107,80,73,32,51,46,49,52,49,53,57,50,54,53,51,54,13,10,13,10,118,101,99,52,32,69,110,99,111,100,101,78,111,114,109,97,108,40,105,110,32,118,101,99,51,32,110,111,114,109,97,108,41,13,10,123,13,10,9,47,47,114,101,116,117,114,110,32,118,101,99,52,40,110,111,114,109,97,108,42,48,46,53,32,43,32,48,46,53,44,32,48,46,48,41,59,13,10,9,114,101,116,117,114,110,32,118,101,99,52,40,118,101,99,50,40,97,116,97,110,40,110,111,114,109,97,108,46,121,44,32,110,111,114,109,97,108,46,120,41,47,107,80,73,44,32,110,111,114,109,97,108,46,122,41,44,32,48,46,48,44,32,48,46,48,41,59,13,10,125,13,10,13,10,102,108,111,97,116,32,86,101,99,116,111,114,84,111,68,101,112,116,104,86,97,108,117,101,40,118,101,99,51,32,118,101,99,44,32,102,108,111,97,116,32,122,78,101,97,114,44,32,102,108,111,97,116,32,122,70,97,114,41,13,10,123,13,10,32,32,32,32,118,101,99,51,32,97,98,115,86,101,99,32,61,32,97,98,115,40,118,101,99,41,59,13,10,32,32,32,32,102,108,111,97,116,32,108,111,99,97,108,90,32,61,32,109,97,120,40,97,98,115,86,101,99,46,120,44,32,109,97,120,40,97,98,115,86,101,99,46,121,44,32,97,98,115,86,101,99,46,122,41,41,59,13,10,13,10,9,102,108,111,97,116,32,110,111,114,109,90,32,61,32,40,40,122,70,97,114,32,43,32,122,78,101,97,114,41,32,42,32,108,111,99,97,108,90,32,45,32,40,50,46,48,42,122,70,97,114,42,122,78,101,97,114,41,41,32,47,32,40,40,122,70,97,114,32,45,32,122,78,101,97,114,41,42,108,111,99,97,108,90,41,59,13,10,9,114,101,116,117,114,110,32,40,110,111,114,109,90,32,43,32,49,46,48,41,32,42,32,48,46,53,59,13,10,125,13,10,13,10,98,111,111,108,32,84,101,115,116,83,104,97,100,111,119,68,105,114,101,99,116,105,111,110,97,108,40,41,13,10,123,13,10,9,47,47,47,84,79,68,79,13,10,9,114,101,116,117,114,110,32,116,114,117,101,59,13,10,125,13,10,13,10,98,111,111,108,32,84,101,115,116,83,104,97,100,111,119,80,111,105,110,116,40,105,110,116,32,108,105,103,104,116,73,110,100,101,120,44,32,118,101,99,51,32,108,105,103,104,116,84,111,87,111,114,108,100,44,32,102,108,111,97,116,32,122,78,101,97,114,44,32,102,108,111,97,116,32,122,70,97,114,41,13,10,123,13,10,9,114,101,116,117,114,110,32,116,101,120,116,117,114,101,40,80,111,105,110,116,76,105,103,104,116,83,104,97,100,111,119,77,97,112,91,108,105,103,104,116,73,110,100,101,120,93,44,32,118,101,99,51,40,108,105,103,104,116,84,111,87,111,114,108,100,46,120,44,32,45,108,105,103,104,116,84,111,87,111,114,108,100,46,121,44,32,45,108,105,103,104,116,84,111,87,111,114,108,100,46,122,41,41,46,120,32,62,61,32,86,101,99,116,111,114,84,111,68,101,112,116,104,86,97,108,117,101,40,108,105,103,104,116,84,111,87,111,114,108,100,44,32,122,78,101,97,114,44,32,122,70,97,114,41,59,13,10,125,13,10,13,10,98,111,111,108,32,84,101,115,116,83,104,97,100,111,119,83,112,111,116,40,105,110,116,32,108,105,103,104,116,73,110,100,101,120,41,13,10,123,13,10,9,118,101,99,52,32,108,105,103,104,116,83,112,97,99,101,80,111,115,32,61,32,118,76,105,103,104,116,83,112,97,99,101,80,111,115,91,108,105,103,104,116,73,110,100,101,120,93,59,13,10,9,114,101,116,117,114,110,32,116,101,120,116,117,114,101,80,114,111,106,40,83,112,111,116,76,105,103,104,116,83,104,97,100,111,119,77,97,112,91,108,105,103,104,116,73,110,100,101,120,93,44,32,108,105,103,104,116,83,112,97,99,101,80,111,115,46,120,121,119,41,46,120,32,62,61,32,40,108,105,103,104,116,83,112,97,99,101,80,111,115,46,122,32,45,32,48,46,48,48,48,53,41,47,108,105,103,104,116,83,112,97,99,101,80,111,115,46,119,59,13,10,125,13,10,13,10,118,111,105,100,32,109,97,105,110,40,41,13,10,123,13,10,9,118,101,99,52,32,100,105,102,102,117,115,101,67,111,108,111,114,32,61,32,77,97,116,101,114,105,97,108,68,105,102,102,117,115,101,32,42,32,118,67,111,108,111,114,59,13,10,13,10,35,105,102,32,65,85,84,79,95,84,69,88,67,79,79,82,68,83,13,10,9,118,101,99,50,32,116,101,120,67,111,111,114,100,32,61,32,103,108,95,70,114,97,103,67,111,111,114,100,46,120,121,32,42,32,73,110,118,84,97,114,103,101,116,83,105,122,101,59,13,10,35,101,108,115,101,13,10,9,118,101,99,50,32,116,101,120,67,111,111,114,100,32,61,32,118,84,101,120,67,111,111,114,100,59,13,10,35,101,110,100,105,102,13,10,13,10,35,105,102,32,76,73,71,72,84,73,78,71,32,38,38,32,80,65,82,65,76,76,65,88,95,77,65,80,80,73,78,71,13,10,9,102,108,111,97,116,32,104,101,105,103,104,116,32,61,32,116,101,120,116,117,114,101,40,77,97,116,101,114,105,97,108,72,101,105,103,104,116,77,97,112,44,32,116,101,120,67,111,111,114,100,41,46,114,59,13,10,9,102,108,111,97,116,32,118,32,61,32,104,101,105,103,104,116,42,80,97,114,97,108,108,97,120,83,99,97,108,101,32,43,32,80,97,114,97,108,108,97,120,66,105,97,115,59,13,10,13,10,9,118,101,99,51,32,118,105,101,119,68,105,114,32,61,32,110,111,114,109,97,108,105,122,101,40,118,86,105,101,119,68,105,114,41,59,13,10,9,116,101,120,67,111,111,114,100,32,43,61,32,118,32,42,32,118,105,101,119,68,105,114,46,120,121,59,13,10,35,101,110,100,105,102,13,10,13,10,35,105,102,32,68,73,70,70,85,83,69,95,77,65,80,80,73,78,71,13,10,9,100,105,102,102,117,115,101,67,111,108,111,114,32,42,61,32,116,101,120,116,117,114,101,40,77,97,116,101,114,105,97,108,68,105,102,102,117,115,101,77,97,112,44,32,116,101,120,67,111,111,114,100,41,59,13,10,35,101,110,100,105,102,13,10,13,10,35,105,102,32,70,76,65,71,95,84,69,88,84,85,82,69,79,86,69,82,76,65,89,13,10,9,100,105,102,102,117,115,101,67,111,108,111,114,32,42,61,32,116,101,120,116,117,114,101,40,84,101,120,116,117,114,101,79,118,101,114,108,97,121,44,32,116,101,120,67,111,111,114,100,41,59,13,10,35,101,110,100,105,102,13,10,13,10,35,105,102,32,70,76,65,71,95,68,69,70,69,82,82,69,68,13,10,9,35,105,102,32,65,76,80,72,65,95,84,69,83,84,13,10,9,9,47,47,32,73,110,117,116,105,108,101,32,100,101,32,102,97,105,114,101,32,100,101,32,108,39,97,108,112,104,97,45,109,97,112,112,105,110,103,32,115,97,110,115,32,97,108,112,104,97,45,116,101,115,116,32,101,110,32,68,101,102,101,114,114,101,100,32,40,108,39,97,108,112,104,97,32,110,39,101,115,116,32,112,97,115,32,115,97,117,118,101,103,97,114,100,195,169,32,100,97,110,115,32,108,101,32,71,45,66,117,102,102,101,114,41,13,10,9,9,35,105,102,32,65,76,80,72,65,95,77,65,80,80,73,78,71,13,10,9,100,105,102,102,117,115,101,67,111,108,111,114,46,97,32,42,61,32,116,101,120,116,117,114,101,40,77,97,116,101,114,105,97,108,65,108,112,104,97,77,97,112,44,32,116,101,120,67,111,111,114,100,41,46,114,59,13,10,9,9,35,101,110,100,105,102,13,10,9,9,13,10,9,105,102,32,40,100,105,102,102,117,115,101,67,111,108,111,114,46,97,32,60,32,77,97,116,101,114,105,97,108,65,108,112,104,97,84,104,114,101,115,104,111,108,100,41,13,10,9,9,100,105,115,99,97,114,100,59,13,10,9,35,101,110,100,105,102,32,47,47,32,65,76,80,72,65,95,84,69,83,84,13,10,13,10,9,35,105,102,32,76,73,71,72,84,73,78,71,13,10,9,9,35,105,102,32,78,79,82,77,65,76,95,77,65,80,80,73,78,71,13,10,9,118,101,99,51,32,110,111,114,109,97,108,32,61,32,110,111,114,109,97,108,105,122,101,40,118,76,105,103,104,116,84,111,87,111,114,108,100,32,42,32,40,50,46,48,32,42,32,118,101,99,51,40,116,101,120,116,117,114,101,40,77,97,116,101,114,105,97,108,78,111,114,109,97,108,77,97,112,44,32,116,101,120,67,111,111,114,100,41,41,32,45,32,49,46,48,41,41,59,13,10,9,9,35,101,108,115,101,13,10,9,118,101,99,51,32,110,111,114,109,97,108,32,61,32,110,111,114,109,97,108,105,122,101,40,118,78,111,114,109,97,108,41,59,13,10,9,9,35,101,110,100,105,102,32,47,47,32,78,79,82,77,65,76,95,77,65,80,80,73,78,71,13,10,13,10,9,118,101,99,51,32,115,112,101,99,117,108,97,114,67,111,108,111,114,32,61,32,77,97,116,101,114,105,97,108,83,112,101,99,117,108,97,114,46,114,103,98,59,13,10,9,9,35,105,102,32,83,80,69,67,85,76,65,82,95,77,65,80,80,73,78,71,13,10,9,115,112,101,99,117,108,97,114,67,111,108,111,114,32,42,61,32,116,101,120,116,117,114,101,40,77,97,116,101,114,105,97,108,83,112,101,99,117,108,97,114,77,97,112,44,32,116,101,120,67,111,111,114,100,41,46,114,103,98,59,13,10,9,9,35,101,110,100,105,102,13,10,13,10,9,47,42,13,10,9,84,101,120,116,117,114,101,48,58,32,68,105,102,102,117,115,101,32,67,111,108,111,114,32,43,32,83,112,101,99,117,108,97,114,13,10,9,84,101,120,116,117,114,101,49,58,32,78,111,114,109,97,108,32,43,32,83,112,101,99,117,108,97,114,13,10,9,84,101,120,116,117,114,101,50,58,32,69,110,99,111,100,101,100,32,100,101,112,116,104,32,43,32,83,104,105,110,105,110,101,115,115,13,10,9,42,47,13,10,9,82,101,110,100,101,114,84,97,114,103,101,116,48,32,61,32,118,101,99,52,40,100,105,102,102,117,115,101,67,111,108,111,114,46,114,103,98,44,32,100,111,116,40,115,112,101,99,117,108,97,114,67,111,108,111,114,44,32,118,101,99,51,40,48,46,51,44,32,48,46,53,57,44,32,48,46,49,49,41,41,41,59,13,10,9,82,101,110,100,101,114,84,97,114,103,101,116,49,32,61,32,118,101,99,52,40,69,110,99,111,100,101,78,111,114,109,97,108,40,110,111,114,109,97,108,41,41,59,13,10,9,82,101,110,100,101,114,84,97,114,103,101,116,50,32,61,32,118,101,99,52,40,70,108,111,97,116,84,111,67,111,108,111,114,40,103,108,95,70,114,97,103,67,111,111,114,100,46,122,41,44,32,40,77,97,116,101,114,105,97,108,83,104,105,110,105,110,101,115,115,32,61,61,32,48,46,48,41,32,63,32,48,46,48,32,58,32,109,97,120,40,108,111,103,50,40,77,97,116,101,114,105,97,108,83,104,105,110,105,110,101,115,115,41,44,32,48,46,49,41,47,49,48,46,53,41,59,32,47,47,32,104,116,116,112,58,47,47,119,119,119,46,103,117,101,114,114,105,108,108,97,45,103,97,109,101,115,46,99,111,109,47,112,117,98,108,105,99,97,116,105,111,110,115,47,100,114,95,107,122,50,95,114,115,120,95,100,101,118,48,55,46,112,100,102,13,10,9,35,101,108,115,101,32,47,47,32,76,73,71,72,84,73,78,71,13,10,9,82,101,110,100,101,114,84,97,114,103,101,116,48,32,61,32,118,101,99,52,40,100,105,102,102,117,115,101,67,111,108,111,114,46,114,103,98,44,32,48,46,48,41,59,13,10,9,35,101,110,100,105,102,13,10,35,101,108,115,101,32,47,47,32,70,76,65,71,95,68,69,70,69,82,82,69,68,13,10,9,35,105,102,32,65,76,80,72,65,95,77,65,80,80,73,78,71,13,10,9,100,105,102,102,117,115,101,67,111,108,111,114,46,97,32,42,61,32,116,101,120,116,117,114,101,40,77,97,116,101,114,105,97,108,65,108,112,104,97,77,97,112,44,32,116,101,120,67,111,111,114,100,41,46,114,59,13,10,9,35,101,110,100,105,102,13,10,13,10,9,35,105,102,32,65,76,80,72,65,95,84,69,83,84,13,10,9,105,102,32,40,100,105,102,102,117,115,101,67,111,108,111,114,46,97,32,60,32,77,97,116,101,114,105,97,108,65,108,112,104,97,84,104,114,101,115,104,111,108,100,41,13,10,9,9,100,105,115,99,97,114,100,59,13,10,9,35,101,110,100,105,102,13,10,13,10,9,35,105,102,32,76,73,71,72,84,73,78,71,13,10,9,118,101,99,51,32,108,105,103,104,116,65,109,98,105,101,110,116,32,61,32,118,101,99,51,40,48,46,48,41,59,13,10,9,118,101,99,51,32,108,105,103,104,116,68,105,102,102,117,115,101,32,61,32,118,101,99,51,40,48,46,48,41,59,13,10,9,118,101,99,51,32,108,105,103,104,116,83,112,101,99,117,108,97,114,32,61,32,118,101,99,51,40,48,46,48,41,59,13,10,13,10,9,9,35,105,102,32,78,79,82,77,65,76,95,77,65,80,80,73,78,71,13,10,9,118,101,99,51,32,110,111,114,109,97,108,32,61,32,110,111,114,109,97,108,105,122,101,40,118,76,105,103,104,116,84,111,87,111,114,108,100,32,42,32,40,50,46,48,32,42,32,118,101,99,51,40,116,101,120,116,117,114,101,40,77,97,116,101,114,105,97,108,78,111,114,109,97,108,77,97,112,44,32,116,101,120,67,111,111,114,100,41,41,32,45,32,49,46,48,41,41,59,13,10,9,9,35,101,108,115,101,13,10,9,118,101,99,51,32,110,111,114,109,97,108,32,61,32,110,111,114,109,97,108,105,122,101,40,118,78,111,114,109,97,108,41,59,13,10,9,9,35,101,110,100,105,102,13,10,13,10,9,105,102,32,40,77,97,116,101,114,105,97,108,83,104,105,110,105,110,101,115,115,32,62,32,48,46,48,41,13,10,9,123,13,10,9,9,118,101,99,51,32,101,121,101,86,101,99,32,61,32,110,111,114,109,97,108,105,122,101,40,69,121,101,80,111,115,105,116,105,111,110,32,45,32,118,87,111,114,108,100,80,111,115,41,59,13,10,13,10,9,9,102,111,114,32,40,105,110,116,32,105,32,61,32,48,59,32,105,32,60,32,51,59,32,43,43,105,41,13,10,9,9,123,13,10,9,9,9,118,101,99,52,32,108,105,103,104,116,67,111,108,111,114,32,61,32,76,105,103,104,116,115,91,105,93,46,99,111,108,111,114,59,13,10,9,9,9,102,108,111,97,116,32,108,105,103,104,116,65,109,98,105,101,110,116,70,97,99,116,111,114,32,61,32,76,105,103,104,116,115,91,105,93,46,102,97,99,116,111,114,115,46,120,59,13,10,9,9,9,102,108,111,97,116,32,108,105,103,104,116,68,105,102,102,117,115,101,70,97,99,116,111,114,32,61,32,76,105,103,104,116,115,91,105,93,46,102,97,99,116,111,114,115,46,121,59,13,10,13,10,9,9,9,115,119,105,116,99,104,32,40,76,105,103,104,116,115,91,105,93,46,116,121,112,101,41,13,10,9,9,9,123,13,10,9,9,9,9,99,97,115,101,32,76,73,71,72,84,95,68,73,82,69,67,84,73,79,78,65,76,58,13,10,9,9,9,9,123,13,10,9,9,9,9,9,118,101,99,51,32,108,105,103,104,116,68,105,114,32,61,32,45,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,49,46,120,121,122,59,13,10,13,10,9,9,9,9,9,47,47,32,65,109,98,105,101,110,116,13,10,9,9,9,9,9,108,105,103,104,116,65,109,98,105,101,110,116,32,43,61,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,32,42,32,108,105,103,104,116,65,109,98,105,101,110,116,70,97,99,116,111,114,32,42,32,40,77,97,116,101,114,105,97,108,65,109,98,105,101,110,116,46,114,103,98,32,43,32,83,99,101,110,101,65,109,98,105,101,110,116,46,114,103,98,41,59,13,10,13,10,9,9,9,9,9,47,47,32,68,105,102,102,117,115,101,13,10,9,9,9,9,9,102,108,111,97,116,32,108,97,109,98,101,114,116,32,61,32,109,97,120,40,100,111,116,40,110,111,114,109,97,108,44,32,108,105,103,104,116,68,105,114,41,44,32,48,46,48,41,59,13,10,13,10,9,9,9,9,9,108,105,103,104,116,68,105,102,102,117,115,101,32,43,61,32,108,97,109,98,101,114,116,32,42,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,32,42,32,108,105,103,104,116,68,105,102,102,117,115,101,70,97,99,116,111,114,59,13,10,13,10,9,9,9,9,9,47,47,32,83,112,101,99,117,108,97,114,13,10,9,9,9,9,9,118,101,99,51,32,114,101,102,108,101,99,116,105,111,110,32,61,32,114,101,102,108,101,99,116,40,45,108,105,103,104,116,68,105,114,44,32,110,111,114,109,97,108,41,59,13,10,9,9,9,9,9,102,108,111,97,116,32,115,112,101,99,117,108,97,114,70,97,99,116,111,114,32,61,32,109,97,120,40,100,111,116,40,114,101,102,108,101,99,116,105,111,110,44,32,101,121,101,86,101,99,41,44,32,48,46,48,41,59,13,10,9,9,9,9,9,115,112,101,99,117,108,97,114,70,97,99,116,111,114,32,61,32,112,111,119,40,115,112,101,99,117,108,97,114,70,97,99,116,111,114,44,32,77,97,116,101,114,105,97,108,83,104,105,110,105,110,101,115,115,41,59,13,10,13,10,9,9,9,9,9,108,105,103,104,116,83,112,101,99,117,108,97,114,32,43,61,32,115,112,101,99,117,108,97,114,70,97,99,116,111,114,32,42,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,59,13,10,9,9,9,9,9,98,114,101,97,107,59,13,10,9,9,9,9,125,13,10,13,10,9,9,9,9,99,97,115,101,32,76,73,71,72,84,95,80,79,73,78,84,58,13,10,9,9,9,9,123,13,10,9,9,9,9,9,118,101,99,51,32,108,105,103,104,116,80,111,115,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,49,46,120,121,122,59,13,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,65,116,116,101,110,117,97,116,105,111,110,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,49,46,119,59,13,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,73,110,118,82,97,100,105,117,115,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,50,46,119,59,13,10,9,9,9,9,9,13,10,9,9,9,9,9,118,101,99,51,32,119,111,114,108,100,84,111,76,105,103,104,116,32,61,32,108,105,103,104,116,80,111,115,32,45,32,118,87,111,114,108,100,80,111,115,59,13,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,68,105,114,76,101,110,103,116,104,32,61,32,108,101,110,103,116,104,40,119,111,114,108,100,84,111,76,105,103,104,116,41,59,13,10,9,9,9,9,9,118,101,99,51,32,108,105,103,104,116,68,105,114,32,61,32,119,111,114,108,100,84,111,76,105,103,104,116,32,47,32,108,105,103,104,116,68,105,114,76,101,110,103,116,104,59,32,47,47,32,78,111,114,109,97,108,105,115,97,116,105,111,110,13,10,9,9,9,9,9,13,10,9,9,9,9,9,102,108,111,97,116,32,97,116,116,32,61,32,109,97,120,40,108,105,103,104,116,65,116,116,101,110,117,97,116,105,111,110,32,45,32,108,105,103,104,116,73,110,118,82,97,100,105,117,115,32,42,32,108,105,103,104,116,68,105,114,76,101,110,103,116,104,44,32,48,46,48,41,59,13,10,13,10,9,9,9,9,9,47,47,32,65,109,98,105,101,110,116,13,10,9,9,9,9,9,108,105,103,104,116,65,109,98,105,101,110,116,32,43,61,32,97,116,116,32,42,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,32,42,32,108,105,103,104,116,65,109,98,105,101,110,116,70,97,99,116,111,114,32,42,32,40,77,97,116,101,114,105,97,108,65,109,98,105,101,110,116,46,114,103,98,32,43,32,83,99,101,110,101,65,109,98,105,101,110,116,46,114,103,98,41,59,13,10,13,10,9,9,9,9,9,35,105,102,32,83,72,65,68,79,87,95,77,65,80,80,73,78,71,13,10,9,9,9,9,9,105,102,32,40,76,105,103,104,116,115,91,105,93,46,115,104,97,100,111,119,77,97,112,112,105,110,103,32,38,38,32,33,84,101,115,116,83,104,97,100,111,119,80,111,105,110,116,40,105,44,32,118,87,111,114,108,100,80,111,115,32,45,32,108,105,103,104,116,80,111,115,44,32,48,46,49,44,32,53,48,46,48,41,41,13,10,9,9,9,9,9,9,98,114,101,97,107,59,13,10,9,9,9,9,9,35,101,110,100,105,102,13,10,13,10,9,9,9,9,9,47,47,32,68,105,102,102,117,115,101,13,10,9,9,9,9,9,102,108,111,97,116,32,108,97,109,98,101,114,116,32,61,32,109,97,120,40,100,111,116,40,110,111,114,109,97,108,44,32,108,105,103,104,116,68,105,114,41,44,32,48,46,48,41,59,13,10,9,9,9,9,9,13,10,9,9,9,9,9,108,105,103,104,116,68,105,102,102,117,115,101,32,43,61,32,97,116,116,32,42,32,108,97,109,98,101,114,116,32,42,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,32,42,32,108,105,103,104,116,68,105,102,102,117,115,101,70,97,99,116,111,114,59,13,10,13,10,9,9,9,9,9,47,47,32,83,112,101,99,117,108,97,114,13,10,9,9,9,9,9,118,101,99,51,32,114,101,102,108,101,99,116,105,111,110,32,61,32,114,101,102,108,101,99,116,40,45,108,105,103,104,116,68,105,114,44,32,110,111,114,109,97,108,41,59,13,10,9,9,9,9,9,102,108,111,97,116,32,115,112,101,99,117,108,97,114,70,97,99,116,111,114,32,61,32,109,97,120,40,100,111,116,40,114,101,102,108,101,99,116,105,111,110,44,32,101,121,101,86,101,99,41,44,32,48,46,48,41,59,13,10,9,9,9,9,9,115,112,101,99,117,108,97,114,70,97,99,116,111,114,32,61,32,112,111,119,40,115,112,101,99,117,108,97,114,70,97,99,116,111,114,44,32,77,97,116,101,114,105,97,108,83,104,105,110,105,110,101,115,115,41,59,13,10,13,10,9,9,9,9,9,108,105,103,104,116,83,112,101,99,117,108,97,114,32,43,61,32,97,116,116,32,42,32,115,112,101,99,117,108,97,114,70,97,99,116,111,114,32,42,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,59,13,10,9,9,9,9,9,98,114,101,97,107,59,13,10,9,9,9,9,125,13,10,13,10,9,9,9,9,99,97,115,101,32,76,73,71,72,84,95,83,80,79,84,58,13,10,9,9,9,9,123,13,10,9,9,9,9,9,118,101,99,51,32,108,105,103,104,116,80,111,115,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,49,46,120,121,122,59,13,10,9,9,9,9,9,118,101,99,51,32,108,105,103,104,116,68,105,114,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,50,46,120,121,122,59,13,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,65,116,116,101,110,117,97,116,105,111,110,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,49,46,119,59,13,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,73,110,118,82,97,100,105,117,115,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,50,46,119,59,13,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,73,110,110,101,114,65,110,103,108,101,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,51,46,120,59,13,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,79,117,116,101,114,65,110,103,108,101,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,51,46,121,59,13,10,13,10,9,9,9,9,9,118,101,99,51,32,119,111,114,108,100,84,111,76,105,103,104,116,32,61,32,108,105,103,104,116,80,111,115,32,45,32,118,87,111,114,108,100,80,111,115,59,13,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,68,105,115,116,97,110,99,101,32,61,32,108,101,110,103,116,104,40,119,111,114,108,100,84,111,76,105,103,104,116,41,59,13,10,9,9,9,9,9,119,111,114,108,100,84,111,76,105,103,104,116,32,47,61,32,108,105,103,104,116,68,105,115,116,97,110,99,101,59,32,47,47,32,78,111,114,109,97,108,105,115,97,116,105,111,110,13,10,9,9,9,9,9,13,10,9,9,9,9,9,102,108,111,97,116,32,97,116,116,32,61,32,109,97,120,40,108,105,103,104,116,65,116,116,101,110,117,97,116,105,111,110,32,45,32,108,105,103,104,116,73,110,118,82,97,100,105,117,115,32,42,32,108,105,103,104,116,68,105,115,116,97,110,99,101,44,32,48,46,48,41,59,13,10,13,10,9,9,9,9,9,47,47,32,65,109,98,105,101,110,116,13,10,9,9,9,9,9,108,105,103,104,116,65,109,98,105,101,110,116,32,43,61,32,97,116,116,32,42,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,32,42,32,108,105,103,104,116,65,109,98,105,101,110,116,70,97,99,116,111,114,32,42,32,40,77,97,116,101,114,105,97,108,65,109,98,105,101,110,116,46,114,103,98,32,43,32,83,99,101,110,101,65,109,98,105,101,110,116,46,114,103,98,41,59,13,10,13,10,9,9,9,9,9,35,105,102,32,83,72,65,68,79,87,95,77,65,80,80,73,78,71,13,10,9,9,9,9,9,105,102,32,40,76,105,103,104,116,115,91,105,93,46,115,104,97,100,111,119,77,97,112,112,105,110,103,32,38,38,32,33,84,101,115,116,83,104,97,100,111,119,83,112,111,116,40,105,41,41,13,10,9,9,9,9,9,9,98,114,101,97,107,59,13,10,9,9,9,9,9,35,101,110,100,105,102,13,10,13,10,9,9,9,9,9,47,47,32,77,111,100,105,102,105,99,97,116,105,111,110,32,100,101,32,108,39,97,116,116,195,169,110,117,97,116,105,111,110,32,112,111,117,114,32,103,195,169,114,101,114,32,108,101,32,115,112,111,116,13,10,9,9,9,9,9,102,108,111,97,116,32,99,117,114,65,110,103,108,101,32,61,32,100,111,116,40,108,105,103,104,116,68,105,114,44,32,45,119,111,114,108,100,84,111,76,105,103,104,116,41,59,13,10,9,9,9,9,9,102,108,111,97,116,32,105,110,110,101,114,77,105,110,117,115,79,117,116,101,114,65,110,103,108,101,32,61,32,108,105,103,104,116,73,110,110,101,114,65,110,103,108,101,32,45,32,108,105,103,104,116,79,117,116,101,114,65,110,103,108,101,59,13,10,9,9,9,9,9,97,116,116,32,42,61,32,109,97,120,40,40,99,117,114,65,110,103,108,101,32,45,32,108,105,103,104,116,79,117,116,101,114,65,110,103,108,101,41,32,47,32,105,110,110,101,114,77,105,110,117,115,79,117,116,101,114,65,110,103,108,101,44,32,48,46,48,41,59,13,10,13,10,9,9,9,9,9,47,47,32,68,105,102,102,117,115,101,13,10,9,9,9,9,9,102,108,111,97,116,32,108,97,109,98,101,114,116,32,61,32,109,97,120,40,100,111,116,40,110,111,114,109,97,108,44,32,119,111,114,108,100,84,111,76,105,103,104,116,41,44,32,48,46,48,41,59,13,10,13,10,9,9,9,9,9,108,105,103,104,116,68,105,102,102,117,115,101,32,43,61,32,97,116,116,32,42,32,108,97,109,98,101,114,116,32,42,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,32,42,32,108,105,103,104,116,68,105,102,102,117,115,101,70,97,99,116,111,114,59,13,10,13,10,9,9,9,9,9,47,47,32,83,112,101,99,117,108,97,114,13,10,9,9,9,9,9,118,101,99,51,32,114,101,102,108,101,99,116,105,111,110,32,61,32,114,101,102,108,101,99,116,40,45,119,111,114,108,100,84,111,76,105,103,104,116,44,32,110,111,114,109,97,108,41,59,13,10,9,9,9,9,9,102,108,111,97,116,32,115,112,101,99,117,108,97,114,70,97,99,116,111,114,32,61,32,109,97,120,40,100,111,116,40,114,101,102,108,101,99,116,105,111,110,44,32,101,121,101,86,101,99,41,44,32,48,46,48,41,59,13,10,9,9,9,9,9,115,112,101,99,117,108,97,114,70,97,99,116,111,114,32,61,32,112,111,119,40,115,112,101,99,117,108,97,114,70,97,99,116,111,114,44,32,77,97,116,101,114,105,97,108,83,104,105,110,105,110,101,115,115,41,59,13,10,13,10,9,9,9,9,9,108,105,103,104,116,83,112,101,99,117,108,97,114,32,43,61,32,97,116,116,32,42,32,115,112,101,99,117,108,97,114,70,97,99,116,111,114,32,42,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,59,13,10,9,9,9,9,9,98,114,101,97,107,59,13,10,9,9,9,9,125,13,10,9,9,9,9,13,10,9,9,9,9,100,101,102,97,117,108,116,58,13,10,9,9,9,9,9,98,114,101,97,107,59,13,10,9,9,9,125,13,10,9,9,125,13,10,9,125,13,10,9,101,108,115,101,13,10,9,123,13,10,9,9,102,111,114,32,40,105,110,116,32,105,32,61,32,48,59,32,105,32,60,32,51,59,32,43,43,105,41,13,10,9,9,123,13,10,9,9,9,118,101,99,52,32,108,105,103,104,116,67,111,108,111,114,32,61,32,76,105,103,104,116,115,91,105,93,46,99,111,108,111,114,59,13,10,9,9,9,102,108,111,97,116,32,108,105,103,104,116,65,109,98,105,101,110,116,70,97,99,116,111,114,32,61,32,76,105,103,104,116,115,91,105,93,46,102,97,99,116,111,114,115,46,120,59,13,10,9,9,9,102,108,111,97,116,32,108,105,103,104,116,68,105,102,102,117,115,101,70,97,99,116,111,114,32,61,32,76,105,103,104,116,115,91,105,93,46,102,97,99,116,111,114,115,46,121,59,13,10,13,10,9,9,9,115,119,105,116,99,104,32,40,76,105,103,104,116,115,91,105,93,46,116,121,112,101,41,13,10,9,9,9,123,13,10,9,9,9,9,99,97,115,101,32,76,73,71,72,84,95,68,73,82,69,67,84,73,79,78,65,76,58,13,10,9,9,9,9,123,13,10,9,9,9,9,9,118,101,99,51,32,108,105,103,104,116,68,105,114,32,61,32,45,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,49,46,120,121,122,59,13,10,13,10,9,9,9,9,9,47,47,32,65,109,98,105,101,110,116,13,10,9,9,9,9,9,108,105,103,104,116,65,109,98,105,101,110,116,32,43,61,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,32,42,32,108,105,103,104,116,65,109,98,105,101,110,116,70,97,99,116,111,114,32,42,32,40,77,97,116,101,114,105,97,108,65,109,98,105,101,110,116,46,114,103,98,32,43,32,83,99,101,110,101,65,109,98,105,101,110,116,46,114,103,98,41,59,13,10,13,10,9,9,9,9,9,47,47,32,68,105,102,102,117,115,101,13,10,9,9,9,9,9,102,108,111,97,116,32,108,97,109,98,101,114,116,32,61,32,109,97,120,40,100,111,116,40,110,111,114,109,97,108,44,32,108,105,103,104,116,68,105,114,41,44,32,48,46,48,41,59,13,10,13,10,9,9,9,9,9,108,105,103,104,116,68,105,102,102,117,115,101,32,43,61,32,108,97,109,98,101,114,116,32,42,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,32,42,32,108,105,103,104,116,68,105,102,102,117,115,101,70,97,99,116,111,114,59,13,10,9,9,9,9,9,98,114,101,97,107,59,13,10,9,9,9,9,125,13,10,13,10,9,9,9,9,99,97,115,101,32,76,73,71,72,84,95,80,79,73,78,84,58,13,10,9,9,9,9,123,13,10,9,9,9,9,9,118,101,99,51,32,108,105,103,104,116,80,111,115,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,49,46,120,121,122,59,13,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,65,116,116,101,110,117,97,116,105,111,110,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,49,46,119,59,13,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,73,110,118,82,97,100,105,117,115,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,50,46,119,59,13,10,9,9,9,9,9,13,10,9,9,9,9,9,118,101,99,51,32,119,111,114,108,100,84,111,76,105,103,104,116,32,61,32,108,105,103,104,116,80,111,115,32,45,32,118,87,111,114,108,100,80,111,115,59,13,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,68,105,114,76,101,110,103,116,104,32,61,32,108,101,110,103,116,104,40,119,111,114,108,100,84,111,76,105,103,104,116,41,59,13,10,9,9,9,9,9,118,101,99,51,32,108,105,103,104,116,68,105,114,32,61,32,119,111,114,108,100,84,111,76,105,103,104,116,32,47,32,108,105,103,104,116,68,105,114,76,101,110,103,116,104,59,32,47,47,32,78,111,114,109,97,108,105,115,97,116,105,111,110,13,10,9,9,9,9,9,13,10,9,9,9,9,9,102,108,111,97,116,32,97,116,116,32,61,32,109,97,120,40,108,105,103,104,116,65,116,116,101,110,117,97,116,105,111,110,32,45,32,108,105,103,104,116,73,110,118,82,97,100,105,117,115,32,42,32,108,105,103,104,116,68,105,114,76,101,110,103,116,104,44,32,48,46,48,41,59,13,10,13,10,9,9,9,9,9,47,47,32,65,109,98,105,101,110,116,13,10,9,9,9,9,9,108,105,103,104,116,65,109,98,105,101,110,116,32,43,61,32,97,116,116,32,42,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,32,42,32,108,105,103,104,116,65,109,98,105,101,110,116,70,97,99,116,111,114,32,42,32,40,77,97,116,101,114,105,97,108,65,109,98,105,101,110,116,46,114,103,98,32,43,32,83,99,101,110,101,65,109,98,105,101,110,116,46,114,103,98,41,59,13,10,13,10,9,9,9,9,9,35,105,102,32,83,72,65,68,79,87,95,77,65,80,80,73,78,71,13,10,9,9,9,9,9,105,102,32,40,76,105,103,104,116,115,91,105,93,46,115,104,97,100,111,119,77,97,112,112,105,110,103,32,38,38,32,33,84,101,115,116,83,104,97,100,111,119,80,111,105,110,116,40,105,44,32,118,87,111,114,108,100,80,111,115,32,45,32,108,105,103,104,116,80,111,115,44,32,48,46,49,44,32,49,46,48,32,47,32,108,105,103,104,116,73,110,118,82,97,100,105,117,115,41,41,13,10,9,9,9,9,9,9,98,114,101,97,107,59,13,10,9,9,9,9,9,35,101,110,100,105,102,13,10,13,10,9,9,9,9,9,47,47,32,68,105,102,102,117,115,101,13,10,9,9,9,9,9,102,108,111,97,116,32,108,97,109,98,101,114,116,32,61,32,109,97,120,40,100,111,116,40,110,111,114,109,97,108,44,32,108,105,103,104,116,68,105,114,41,44,32,48,46,48,41,59,13,10,9,9,9,9,9,13,10,9,9,9,9,9,108,105,103,104,116,68,105,102,102,117,115,101,32,43,61,32,97,116,116,32,42,32,108,97,109,98,101,114,116,32,42,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,32,42,32,108,105,103,104,116,68,105,102,102,117,115,101,70,97,99,116,111,114,59,13,10,9,9,9,9,9,98,114,101,97,107,59,13,10,9,9,9,9,125,13,10,13,10,9,9,9,9,99,97,115,101,32,76,73,71,72,84,95,83,80,79,84,58,13,10,9,9,9,9,123,13,10,9,9,9,9,9,118,101,99,51,32,108,105,103,104,116,80,111,115,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,49,46,120,121,122,59,13,10,9,9,9,9,9,118,101,99,51,32,108,105,103,104,116,68,105,114,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,50,46,120,121,122,59,13,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,65,116,116,101,110,117,97,116,105,111,110,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,49,46,119,59,13,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,73,110,118,82,97,100,105,117,115,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,50,46,119,59,13,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,73,110,110,101,114,65,110,103,108,101,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,51,46,120,59,13,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,79,117,116,101,114,65,110,103,108,101,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,51,46,121,59,13,10,13,10,9,9,9,9,9,118,101,99,51,32,119,111,114,108,100,84,111,76,105,103,104,116,32,61,32,108,105,103,104,116,80,111,115,32,45,32,118,87,111,114,108,100,80,111,115,59,13,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,68,105,115,116,97,110,99,101,32,61,32,108,101,110,103,116,104,40,119,111,114,108,100,84,111,76,105,103,104,116,41,59,13,10,9,9,9,9,9,119,111,114,108,100,84,111,76,105,103,104,116,32,47,61,32,108,105,103,104,116,68,105,115,116,97,110,99,101,59,32,47,47,32,78,111,114,109,97,108,105,115,97,116,105,111,110,13,10,9,9,9,9,9,13,10,9,9,9,9,9,102,108,111,97,116,32,97,116,116,32,61,32,109,97,120,40,108,105,103,104,116,65,116,116,101,110,117,97,116,105,111,110,32,45,32,108,105,103,104,116,73,110,118,82,97,100,105,117,115,32,42,32,108,105,103,104,116,68,105,115,116,97,110,99,101,44,32,48,46,48,41,59,13,10,13,10,9,9,9,9,9,47,47,32,65,109,98,105,101,110,116,13,10,9,9,9,9,9,108,105,103,104,116,65,109,98,105,101,110,116,32,43,61,32,97,116,116,32,42,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,32,42,32,108,105,103,104,116,65,109,98,105,101,110,116,70,97,99,116,111,114,32,42,32,40,77,97,116,101,114,105,97,108,65,109,98,105,101,110,116,46,114,103,98,32,43,32,83,99,101,110,101,65,109,98,105,101,110,116,46,114,103,98,41,59,13,10,13,10,9,9,9,9,9,35,105,102,32,83,72,65,68,79,87,95,77,65,80,80,73,78,71,13,10,9,9,9,9,9,105,102,32,40,76,105,103,104,116,115,91,105,93,46,115,104,97,100,111,119,77,97,112,112,105,110,103,32,38,38,32,33,84,101,115,116,83,104,97,100,111,119,83,112,111,116,40,105,41,41,13,10,9,9,9,9,9,9,98,114,101,97,107,59,13,10,9,9,9,9,9,35,101,110,100,105,102,13,10,13,10,9,9,9,9,9,47,47,32,77,111,100,105,102,105,99,97,116,105,111,110,32,100,101,32,108,39,97,116,116,195,169,110,117,97,116,105,111,110,32,112,111,117,114,32,103,195,169,114,101,114,32,108,101,32,115,112,111,116,13,10,9,9,9,9,9,102,108,111,97,116,32,99,117,114,65,110,103,108,101,32,61,32,100,111,116,40,108,105,103,104,116,68,105,114,44,32,45,119,111,114,108,100,84,111,76,105,103,104,116,41,59,13,10,9,9,9,9,9,102,108,111,97,116,32,105,110,110,101,114,77,105,110,117,115,79,117,116,101,114,65,110,103,108,101,32,61,32,108,105,103,104,116,73,110,110,101,114,65,110,103,108,101,32,45,32,108,105,103,104,116,79,117,116,101,114,65,110,103,108,101,59,13,10,9,9,9,9,9,97,116,116,32,42,61,32,109,97,120,40,40,99,117,114,65,110,103,108,101,32,45,32,108,105,103,104,116,79,117,116,101,114,65,110,103,108,101,41,32,47,32,105,110,110,101,114,77,105,110,117,115,79,117,116,101,114,65,110,103,108,101,44,32,48,46,48,41,59,13,10,13,10,9,9,9,9,9,47,47,32,68,105,102,102,117,115,101,13,10,9,9,9,9,9,102,108,111,97,116,32,108,97,109,98,101,114,116,32,61,32,109,97,120,40,100,111,116,40,110,111,114,109,97,108,44,32,119,111,114,108,100,84,111,76,105,103,104,116,41,44,32,48,46,48,41,59,13,10,13,10,9,9,9,9,9,108,105,103,104,116,68,105,102,102,117,115,101,32,43,61,32,97,116,116,32,42,32,108,97,109,98,101,114,116,32,42,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,32,42,32,108,105,103,104,116,68,105,102,102,117,115,101,70,97,99,116,111,114,59,13,10,9,9,9,9,125,13,10,9,9,9,9,13,10,9,9,9,9,100,101,102,97,117,108,116,58,13,10,9,9,9,9,9,98,114,101,97,107,59,13,10,9,9,9,125,13,10,9,9,125,13,10,9,125,13,10,9,13,10,9,108,105,103,104,116,83,112,101,99,117,108,97,114,32,42,61,32,77,97,116,101,114,105,97,108,83,112,101,99,117,108,97,114,46,114,103,98,59,13,10,9,9,35,105,102,32,83,80,69,67,85,76,65,82,95,77,65,80,80,73,78,71,13,10,9,108,105,103,104,116,83,112,101,99,117,108,97,114,32,42,61,32,116,101,120,116,117,114,101,40,77,97,116,101,114,105,97,108,83,112,101,99,117,108,97,114,77,97,112,44,32,116,101,120,67,111,111,114,100,41,46,114,103,98,59,32,47,47,32,85,116,105,108,105,115,101,114,32,108,39,97,108,112,104,97,32,100,101,32,77,97,116,101,114,105,97,108,83,112,101,99,117,108,97,114,32,110,39,97,117,114,97,105,116,32,97,117,99,117,110,32,115,101,110,115,13,10,9,9,35,101,110,100,105,102,13,10,9,9,13,10,9,118,101,99,51,32,108,105,103,104,116,67,111,108,111,114,32,61,32,40,108,105,103,104,116,65,109,98,105,101,110,116,32,43,32,108,105,103,104,116,68,105,102,102,117,115,101,32,43,32,108,105,103,104,116,83,112,101,99,117,108,97,114,41,59,13,10,9,118,101,99,52,32,102,114,97,103,109,101,110,116,67,111,108,111,114,32,61,32,118,101,99,52,40,108,105,103,104,116,67,111,108,111,114,44,32,49,46,48,41,32,42,32,100,105,102,102,117,115,101,67,111,108,111,114,59,13,10,13,10,9,9,35,105,102,32,69,77,73,83,83,73,86,69,95,77,65,80,80,73,78,71,13,10,9,102,108,111,97,116,32,108,105,103,104,116,73,110,116,101,110,115,105,116,121,32,61,32,100,111,116,40,108,105,103,104,116,67,111,108,111,114,44,32,118,101,99,51,40,48,46,51,44,32,48,46,53,57,44,32,48,46,49,49,41,41,59,13,10,13,10,9,118,101,99,51,32,101,109,105,115,115,105,111,110,67,111,108,111,114,32,61,32,77,97,116,101,114,105,97,108,68,105,102,102,117,115,101,46,114,103,98,32,42,32,116,101,120,116,117,114,101,40,77,97,116,101,114,105,97,108,69,109,105,115,115,105,118,101,77,97,112,44,32,116,101,120,67,111,111,114,100,41,46,114,103,98,59,13,10,9,82,101,110,100,101,114,84,97,114,103,101,116,48,32,61,32,118,101,99,52,40,109,105,120,40,102,114,97,103,109,101,110,116,67,111,108,111,114,46,114,103,98,44,32,101,109,105,115,115,105,111,110,67,111,108,111,114,44,32,99,108,97,109,112,40,49,46,48,32,45,32,51,46,48,42,108,105,103,104,116,73,110,116,101,110,115,105,116,121,44,32,48,46,48,44,32,49,46,48,41,41,44,32,102,114,97,103,109,101,110,116,67,111,108,111,114,46,97,41,59,13,10,9,9,35,101,108,115,101,13,10,9,82,101,110,100,101,114,84,97,114,103,101,116,48,32,61,32,102,114,97,103,109,101,110,116,67,111,108,111,114,59,13,10,9,9,35,101,110,100,105,102,32,47,47,32,69,77,73,83,83,73,86,69,95,77,65,80,80,73,78,71,13,10,9,35,101,108,115,101,13,10,9,82,101,110,100,101,114,84,97,114,103,101,116,48,32,61,32,100,105,102,102,117,115,101,67,111,108,111,114,59,13,10,9,35,101,110,100,105,102,32,47,47,32,76,73,71,72,84,73,78,71,13,10,35,101,110,100,105,102,32,47,47,32,70,76,65,71,95,68,69,70,69,82,82,69,68,13,10,125,13,10,10, \ No newline at end of file +35,105,102,32,69,65,82,76,89,95,70,82,65,71,77,69,78,84,95,84,69,83,84,83,32,38,38,32,33,65,76,80,72,65,95,84,69,83,84,13,10,108,97,121,111,117,116,40,101,97,114,108,121,95,102,114,97,103,109,101,110,116,95,116,101,115,116,115,41,32,105,110,59,13,10,35,101,110,100,105,102,13,10,13,10,35,100,101,102,105,110,101,32,76,73,71,72,84,95,68,73,82,69,67,84,73,79,78,65,76,32,48,13,10,35,100,101,102,105,110,101,32,76,73,71,72,84,95,80,79,73,78,84,32,49,13,10,35,100,101,102,105,110,101,32,76,73,71,72,84,95,83,80,79,84,32,50,13,10,13,10,47,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,69,110,116,114,97,110,116,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,47,13,10,105,110,32,118,101,99,52,32,118,67,111,108,111,114,59,13,10,105,110,32,118,101,99,52,32,118,76,105,103,104,116,83,112,97,99,101,80,111,115,91,51,93,59,13,10,105,110,32,109,97,116,51,32,118,76,105,103,104,116,84,111,87,111,114,108,100,59,13,10,105,110,32,118,101,99,51,32,118,78,111,114,109,97,108,59,13,10,105,110,32,118,101,99,50,32,118,84,101,120,67,111,111,114,100,59,13,10,105,110,32,118,101,99,51,32,118,86,105,101,119,68,105,114,59,13,10,105,110,32,118,101,99,51,32,118,87,111,114,108,100,80,111,115,59,13,10,13,10,47,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,83,111,114,116,97,110,116,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,47,13,10,111,117,116,32,118,101,99,52,32,82,101,110,100,101,114,84,97,114,103,101,116,48,59,13,10,111,117,116,32,118,101,99,52,32,82,101,110,100,101,114,84,97,114,103,101,116,49,59,13,10,111,117,116,32,118,101,99,52,32,82,101,110,100,101,114,84,97,114,103,101,116,50,59,13,10,13,10,47,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,85,110,105,102,111,114,109,101,115,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,47,13,10,115,116,114,117,99,116,32,76,105,103,104,116,13,10,123,13,10,9,105,110,116,32,116,121,112,101,59,13,10,9,118,101,99,52,32,99,111,108,111,114,59,13,10,9,118,101,99,50,32,102,97,99,116,111,114,115,59,13,10,13,10,9,118,101,99,52,32,112,97,114,97,109,101,116,101,114,115,49,59,13,10,9,118,101,99,52,32,112,97,114,97,109,101,116,101,114,115,50,59,13,10,9,118,101,99,50,32,112,97,114,97,109,101,116,101,114,115,51,59,13,10,9,98,111,111,108,32,115,104,97,100,111,119,77,97,112,112,105,110,103,59,13,10,125,59,13,10,13,10,47,47,32,76,117,109,105,195,168,114,101,115,13,10,117,110,105,102,111,114,109,32,76,105,103,104,116,32,76,105,103,104,116,115,91,51,93,59,13,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,67,117,98,101,32,80,111,105,110,116,76,105,103,104,116,83,104,97,100,111,119,77,97,112,91,51,93,59,13,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,68,105,114,101,99,116,105,111,110,97,108,83,112,111,116,76,105,103,104,116,83,104,97,100,111,119,77,97,112,91,51,93,59,13,10,13,10,47,47,32,77,97,116,195,169,114,105,97,117,13,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,77,97,116,101,114,105,97,108,65,108,112,104,97,77,97,112,59,13,10,117,110,105,102,111,114,109,32,102,108,111,97,116,32,77,97,116,101,114,105,97,108,65,108,112,104,97,84,104,114,101,115,104,111,108,100,59,13,10,117,110,105,102,111,114,109,32,118,101,99,52,32,77,97,116,101,114,105,97,108,65,109,98,105,101,110,116,59,13,10,117,110,105,102,111,114,109,32,118,101,99,52,32,77,97,116,101,114,105,97,108,68,105,102,102,117,115,101,59,13,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,77,97,116,101,114,105,97,108,68,105,102,102,117,115,101,77,97,112,59,13,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,77,97,116,101,114,105,97,108,69,109,105,115,115,105,118,101,77,97,112,59,13,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,77,97,116,101,114,105,97,108,72,101,105,103,104,116,77,97,112,59,13,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,77,97,116,101,114,105,97,108,78,111,114,109,97,108,77,97,112,59,13,10,117,110,105,102,111,114,109,32,102,108,111,97,116,32,77,97,116,101,114,105,97,108,83,104,105,110,105,110,101,115,115,59,13,10,117,110,105,102,111,114,109,32,118,101,99,52,32,77,97,116,101,114,105,97,108,83,112,101,99,117,108,97,114,59,13,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,77,97,116,101,114,105,97,108,83,112,101,99,117,108,97,114,77,97,112,59,13,10,13,10,47,47,32,65,117,116,114,101,115,13,10,117,110,105,102,111,114,109,32,102,108,111,97,116,32,80,97,114,97,108,108,97,120,66,105,97,115,32,61,32,45,48,46,48,51,59,13,10,117,110,105,102,111,114,109,32,102,108,111,97,116,32,80,97,114,97,108,108,97,120,83,99,97,108,101,32,61,32,48,46,48,50,59,13,10,117,110,105,102,111,114,109,32,118,101,99,50,32,73,110,118,84,97,114,103,101,116,83,105,122,101,59,13,10,117,110,105,102,111,114,109,32,118,101,99,51,32,69,121,101,80,111,115,105,116,105,111,110,59,13,10,117,110,105,102,111,114,109,32,118,101,99,52,32,83,99,101,110,101,65,109,98,105,101,110,116,59,13,10,13,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,84,101,120,116,117,114,101,79,118,101,114,108,97,121,59,13,10,13,10,47,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,70,111,110,99,116,105,111,110,115,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,47,13,10,118,101,99,51,32,70,108,111,97,116,84,111,67,111,108,111,114,40,102,108,111,97,116,32,102,41,13,10,123,13,10,9,118,101,99,51,32,99,111,108,111,114,59,13,10,13,10,9,102,32,42,61,32,50,53,54,46,48,59,13,10,9,99,111,108,111,114,46,120,32,61,32,102,108,111,111,114,40,102,41,59,13,10,13,10,9,102,32,61,32,40,102,32,45,32,99,111,108,111,114,46,120,41,32,42,32,50,53,54,46,48,59,13,10,9,99,111,108,111,114,46,121,32,61,32,102,108,111,111,114,40,102,41,59,13,10,13,10,9,99,111,108,111,114,46,122,32,61,32,102,32,45,32,99,111,108,111,114,46,121,59,13,10,9,99,111,108,111,114,46,120,121,32,42,61,32,48,46,48,48,51,57,48,54,50,53,59,32,47,47,32,42,61,32,49,46,48,47,50,53,54,13,10,13,10,9,114,101,116,117,114,110,32,99,111,108,111,114,59,13,10,125,13,10,13,10,35,100,101,102,105,110,101,32,107,80,73,32,51,46,49,52,49,53,57,50,54,53,51,54,13,10,13,10,118,101,99,52,32,69,110,99,111,100,101,78,111,114,109,97,108,40,105,110,32,118,101,99,51,32,110,111,114,109,97,108,41,13,10,123,13,10,9,47,47,114,101,116,117,114,110,32,118,101,99,52,40,110,111,114,109,97,108,42,48,46,53,32,43,32,48,46,53,44,32,48,46,48,41,59,13,10,9,114,101,116,117,114,110,32,118,101,99,52,40,118,101,99,50,40,97,116,97,110,40,110,111,114,109,97,108,46,121,44,32,110,111,114,109,97,108,46,120,41,47,107,80,73,44,32,110,111,114,109,97,108,46,122,41,44,32,48,46,48,44,32,48,46,48,41,59,13,10,125,13,10,13,10,102,108,111,97,116,32,86,101,99,116,111,114,84,111,68,101,112,116,104,86,97,108,117,101,40,118,101,99,51,32,118,101,99,44,32,102,108,111,97,116,32,122,78,101,97,114,44,32,102,108,111,97,116,32,122,70,97,114,41,13,10,123,13,10,32,32,32,32,118,101,99,51,32,97,98,115,86,101,99,32,61,32,97,98,115,40,118,101,99,41,59,13,10,32,32,32,32,102,108,111,97,116,32,108,111,99,97,108,90,32,61,32,109,97,120,40,97,98,115,86,101,99,46,120,44,32,109,97,120,40,97,98,115,86,101,99,46,121,44,32,97,98,115,86,101,99,46,122,41,41,59,13,10,13,10,9,102,108,111,97,116,32,110,111,114,109,90,32,61,32,40,40,122,70,97,114,32,43,32,122,78,101,97,114,41,32,42,32,108,111,99,97,108,90,32,45,32,40,50,46,48,42,122,70,97,114,42,122,78,101,97,114,41,41,32,47,32,40,40,122,70,97,114,32,45,32,122,78,101,97,114,41,42,108,111,99,97,108,90,41,59,13,10,9,114,101,116,117,114,110,32,40,110,111,114,109,90,32,43,32,49,46,48,41,32,42,32,48,46,53,59,13,10,125,13,10,13,10,98,111,111,108,32,84,101,115,116,83,104,97,100,111,119,68,105,114,101,99,116,105,111,110,97,108,40,105,110,116,32,108,105,103,104,116,73,110,100,101,120,41,13,10,123,13,10,9,118,101,99,52,32,108,105,103,104,116,83,112,97,99,101,80,111,115,32,61,32,118,76,105,103,104,116,83,112,97,99,101,80,111,115,91,108,105,103,104,116,73,110,100,101,120,93,59,13,10,9,114,101,116,117,114,110,32,116,101,120,116,117,114,101,40,68,105,114,101,99,116,105,111,110,97,108,83,112,111,116,76,105,103,104,116,83,104,97,100,111,119,77,97,112,91,108,105,103,104,116,73,110,100,101,120,93,44,32,108,105,103,104,116,83,112,97,99,101,80,111,115,46,120,121,41,46,120,32,62,61,32,40,108,105,103,104,116,83,112,97,99,101,80,111,115,46,122,32,45,32,48,46,48,48,48,53,41,59,13,10,125,13,10,13,10,98,111,111,108,32,84,101,115,116,83,104,97,100,111,119,80,111,105,110,116,40,105,110,116,32,108,105,103,104,116,73,110,100,101,120,44,32,118,101,99,51,32,108,105,103,104,116,84,111,87,111,114,108,100,44,32,102,108,111,97,116,32,122,78,101,97,114,44,32,102,108,111,97,116,32,122,70,97,114,41,13,10,123,13,10,9,114,101,116,117,114,110,32,116,101,120,116,117,114,101,40,80,111,105,110,116,76,105,103,104,116,83,104,97,100,111,119,77,97,112,91,108,105,103,104,116,73,110,100,101,120,93,44,32,118,101,99,51,40,108,105,103,104,116,84,111,87,111,114,108,100,46,120,44,32,45,108,105,103,104,116,84,111,87,111,114,108,100,46,121,44,32,45,108,105,103,104,116,84,111,87,111,114,108,100,46,122,41,41,46,120,32,62,61,32,86,101,99,116,111,114,84,111,68,101,112,116,104,86,97,108,117,101,40,108,105,103,104,116,84,111,87,111,114,108,100,44,32,122,78,101,97,114,44,32,122,70,97,114,41,59,13,10,125,13,10,13,10,98,111,111,108,32,84,101,115,116,83,104,97,100,111,119,83,112,111,116,40,105,110,116,32,108,105,103,104,116,73,110,100,101,120,41,13,10,123,13,10,9,118,101,99,52,32,108,105,103,104,116,83,112,97,99,101,80,111,115,32,61,32,118,76,105,103,104,116,83,112,97,99,101,80,111,115,91,108,105,103,104,116,73,110,100,101,120,93,59,13,10,9,114,101,116,117,114,110,32,116,101,120,116,117,114,101,80,114,111,106,40,68,105,114,101,99,116,105,111,110,97,108,83,112,111,116,76,105,103,104,116,83,104,97,100,111,119,77,97,112,91,108,105,103,104,116,73,110,100,101,120,93,44,32,108,105,103,104,116,83,112,97,99,101,80,111,115,46,120,121,119,41,46,120,32,62,61,32,40,108,105,103,104,116,83,112,97,99,101,80,111,115,46,122,32,45,32,48,46,48,48,48,53,41,47,108,105,103,104,116,83,112,97,99,101,80,111,115,46,119,59,13,10,125,13,10,13,10,118,111,105,100,32,109,97,105,110,40,41,13,10,123,13,10,9,118,101,99,52,32,100,105,102,102,117,115,101,67,111,108,111,114,32,61,32,77,97,116,101,114,105,97,108,68,105,102,102,117,115,101,32,42,32,118,67,111,108,111,114,59,13,10,13,10,35,105,102,32,65,85,84,79,95,84,69,88,67,79,79,82,68,83,13,10,9,118,101,99,50,32,116,101,120,67,111,111,114,100,32,61,32,103,108,95,70,114,97,103,67,111,111,114,100,46,120,121,32,42,32,73,110,118,84,97,114,103,101,116,83,105,122,101,59,13,10,35,101,108,115,101,13,10,9,118,101,99,50,32,116,101,120,67,111,111,114,100,32,61,32,118,84,101,120,67,111,111,114,100,59,13,10,35,101,110,100,105,102,13,10,13,10,35,105,102,32,76,73,71,72,84,73,78,71,32,38,38,32,80,65,82,65,76,76,65,88,95,77,65,80,80,73,78,71,13,10,9,102,108,111,97,116,32,104,101,105,103,104,116,32,61,32,116,101,120,116,117,114,101,40,77,97,116,101,114,105,97,108,72,101,105,103,104,116,77,97,112,44,32,116,101,120,67,111,111,114,100,41,46,114,59,13,10,9,102,108,111,97,116,32,118,32,61,32,104,101,105,103,104,116,42,80,97,114,97,108,108,97,120,83,99,97,108,101,32,43,32,80,97,114,97,108,108,97,120,66,105,97,115,59,13,10,13,10,9,118,101,99,51,32,118,105,101,119,68,105,114,32,61,32,110,111,114,109,97,108,105,122,101,40,118,86,105,101,119,68,105,114,41,59,13,10,9,116,101,120,67,111,111,114,100,32,43,61,32,118,32,42,32,118,105,101,119,68,105,114,46,120,121,59,13,10,35,101,110,100,105,102,13,10,13,10,35,105,102,32,68,73,70,70,85,83,69,95,77,65,80,80,73,78,71,13,10,9,100,105,102,102,117,115,101,67,111,108,111,114,32,42,61,32,116,101,120,116,117,114,101,40,77,97,116,101,114,105,97,108,68,105,102,102,117,115,101,77,97,112,44,32,116,101,120,67,111,111,114,100,41,59,13,10,35,101,110,100,105,102,13,10,13,10,35,105,102,32,70,76,65,71,95,84,69,88,84,85,82,69,79,86,69,82,76,65,89,13,10,9,100,105,102,102,117,115,101,67,111,108,111,114,32,42,61,32,116,101,120,116,117,114,101,40,84,101,120,116,117,114,101,79,118,101,114,108,97,121,44,32,116,101,120,67,111,111,114,100,41,59,13,10,35,101,110,100,105,102,13,10,13,10,35,105,102,32,70,76,65,71,95,68,69,70,69,82,82,69,68,13,10,9,35,105,102,32,65,76,80,72,65,95,84,69,83,84,13,10,9,9,47,47,32,73,110,117,116,105,108,101,32,100,101,32,102,97,105,114,101,32,100,101,32,108,39,97,108,112,104,97,45,109,97,112,112,105,110,103,32,115,97,110,115,32,97,108,112,104,97,45,116,101,115,116,32,101,110,32,68,101,102,101,114,114,101,100,32,40,108,39,97,108,112,104,97,32,110,39,101,115,116,32,112,97,115,32,115,97,117,118,101,103,97,114,100,195,169,32,100,97,110,115,32,108,101,32,71,45,66,117,102,102,101,114,41,13,10,9,9,35,105,102,32,65,76,80,72,65,95,77,65,80,80,73,78,71,13,10,9,100,105,102,102,117,115,101,67,111,108,111,114,46,97,32,42,61,32,116,101,120,116,117,114,101,40,77,97,116,101,114,105,97,108,65,108,112,104,97,77,97,112,44,32,116,101,120,67,111,111,114,100,41,46,114,59,13,10,9,9,35,101,110,100,105,102,13,10,9,9,13,10,9,105,102,32,40,100,105,102,102,117,115,101,67,111,108,111,114,46,97,32,60,32,77,97,116,101,114,105,97,108,65,108,112,104,97,84,104,114,101,115,104,111,108,100,41,13,10,9,9,100,105,115,99,97,114,100,59,13,10,9,35,101,110,100,105,102,32,47,47,32,65,76,80,72,65,95,84,69,83,84,13,10,13,10,9,35,105,102,32,76,73,71,72,84,73,78,71,13,10,9,9,35,105,102,32,78,79,82,77,65,76,95,77,65,80,80,73,78,71,13,10,9,118,101,99,51,32,110,111,114,109,97,108,32,61,32,110,111,114,109,97,108,105,122,101,40,118,76,105,103,104,116,84,111,87,111,114,108,100,32,42,32,40,50,46,48,32,42,32,118,101,99,51,40,116,101,120,116,117,114,101,40,77,97,116,101,114,105,97,108,78,111,114,109,97,108,77,97,112,44,32,116,101,120,67,111,111,114,100,41,41,32,45,32,49,46,48,41,41,59,13,10,9,9,35,101,108,115,101,13,10,9,118,101,99,51,32,110,111,114,109,97,108,32,61,32,110,111,114,109,97,108,105,122,101,40,118,78,111,114,109,97,108,41,59,13,10,9,9,35,101,110,100,105,102,32,47,47,32,78,79,82,77,65,76,95,77,65,80,80,73,78,71,13,10,13,10,9,118,101,99,51,32,115,112,101,99,117,108,97,114,67,111,108,111,114,32,61,32,77,97,116,101,114,105,97,108,83,112,101,99,117,108,97,114,46,114,103,98,59,13,10,9,9,35,105,102,32,83,80,69,67,85,76,65,82,95,77,65,80,80,73,78,71,13,10,9,115,112,101,99,117,108,97,114,67,111,108,111,114,32,42,61,32,116,101,120,116,117,114,101,40,77,97,116,101,114,105,97,108,83,112,101,99,117,108,97,114,77,97,112,44,32,116,101,120,67,111,111,114,100,41,46,114,103,98,59,13,10,9,9,35,101,110,100,105,102,13,10,13,10,9,47,42,13,10,9,84,101,120,116,117,114,101,48,58,32,68,105,102,102,117,115,101,32,67,111,108,111,114,32,43,32,83,112,101,99,117,108,97,114,13,10,9,84,101,120,116,117,114,101,49,58,32,78,111,114,109,97,108,32,43,32,83,112,101,99,117,108,97,114,13,10,9,84,101,120,116,117,114,101,50,58,32,69,110,99,111,100,101,100,32,100,101,112,116,104,32,43,32,83,104,105,110,105,110,101,115,115,13,10,9,42,47,13,10,9,82,101,110,100,101,114,84,97,114,103,101,116,48,32,61,32,118,101,99,52,40,100,105,102,102,117,115,101,67,111,108,111,114,46,114,103,98,44,32,100,111,116,40,115,112,101,99,117,108,97,114,67,111,108,111,114,44,32,118,101,99,51,40,48,46,51,44,32,48,46,53,57,44,32,48,46,49,49,41,41,41,59,13,10,9,82,101,110,100,101,114,84,97,114,103,101,116,49,32,61,32,118,101,99,52,40,69,110,99,111,100,101,78,111,114,109,97,108,40,110,111,114,109,97,108,41,41,59,13,10,9,82,101,110,100,101,114,84,97,114,103,101,116,50,32,61,32,118,101,99,52,40,70,108,111,97,116,84,111,67,111,108,111,114,40,103,108,95,70,114,97,103,67,111,111,114,100,46,122,41,44,32,40,77,97,116,101,114,105,97,108,83,104,105,110,105,110,101,115,115,32,61,61,32,48,46,48,41,32,63,32,48,46,48,32,58,32,109,97,120,40,108,111,103,50,40,77,97,116,101,114,105,97,108,83,104,105,110,105,110,101,115,115,41,44,32,48,46,49,41,47,49,48,46,53,41,59,32,47,47,32,104,116,116,112,58,47,47,119,119,119,46,103,117,101,114,114,105,108,108,97,45,103,97,109,101,115,46,99,111,109,47,112,117,98,108,105,99,97,116,105,111,110,115,47,100,114,95,107,122,50,95,114,115,120,95,100,101,118,48,55,46,112,100,102,13,10,9,35,101,108,115,101,32,47,47,32,76,73,71,72,84,73,78,71,13,10,9,82,101,110,100,101,114,84,97,114,103,101,116,48,32,61,32,118,101,99,52,40,100,105,102,102,117,115,101,67,111,108,111,114,46,114,103,98,44,32,48,46,48,41,59,13,10,9,35,101,110,100,105,102,13,10,35,101,108,115,101,32,47,47,32,70,76,65,71,95,68,69,70,69,82,82,69,68,13,10,9,35,105,102,32,65,76,80,72,65,95,77,65,80,80,73,78,71,13,10,9,100,105,102,102,117,115,101,67,111,108,111,114,46,97,32,42,61,32,116,101,120,116,117,114,101,40,77,97,116,101,114,105,97,108,65,108,112,104,97,77,97,112,44,32,116,101,120,67,111,111,114,100,41,46,114,59,13,10,9,35,101,110,100,105,102,13,10,13,10,9,35,105,102,32,65,76,80,72,65,95,84,69,83,84,13,10,9,105,102,32,40,100,105,102,102,117,115,101,67,111,108,111,114,46,97,32,60,32,77,97,116,101,114,105,97,108,65,108,112,104,97,84,104,114,101,115,104,111,108,100,41,13,10,9,9,100,105,115,99,97,114,100,59,13,10,9,35,101,110,100,105,102,13,10,13,10,9,35,105,102,32,76,73,71,72,84,73,78,71,13,10,9,118,101,99,51,32,108,105,103,104,116,65,109,98,105,101,110,116,32,61,32,118,101,99,51,40,48,46,48,41,59,13,10,9,118,101,99,51,32,108,105,103,104,116,68,105,102,102,117,115,101,32,61,32,118,101,99,51,40,48,46,48,41,59,13,10,9,118,101,99,51,32,108,105,103,104,116,83,112,101,99,117,108,97,114,32,61,32,118,101,99,51,40,48,46,48,41,59,13,10,13,10,9,9,35,105,102,32,78,79,82,77,65,76,95,77,65,80,80,73,78,71,13,10,9,118,101,99,51,32,110,111,114,109,97,108,32,61,32,110,111,114,109,97,108,105,122,101,40,118,76,105,103,104,116,84,111,87,111,114,108,100,32,42,32,40,50,46,48,32,42,32,118,101,99,51,40,116,101,120,116,117,114,101,40,77,97,116,101,114,105,97,108,78,111,114,109,97,108,77,97,112,44,32,116,101,120,67,111,111,114,100,41,41,32,45,32,49,46,48,41,41,59,13,10,9,9,35,101,108,115,101,13,10,9,118,101,99,51,32,110,111,114,109,97,108,32,61,32,110,111,114,109,97,108,105,122,101,40,118,78,111,114,109,97,108,41,59,13,10,9,9,35,101,110,100,105,102,13,10,13,10,9,105,102,32,40,77,97,116,101,114,105,97,108,83,104,105,110,105,110,101,115,115,32,62,32,48,46,48,41,13,10,9,123,13,10,9,9,118,101,99,51,32,101,121,101,86,101,99,32,61,32,110,111,114,109,97,108,105,122,101,40,69,121,101,80,111,115,105,116,105,111,110,32,45,32,118,87,111,114,108,100,80,111,115,41,59,13,10,13,10,9,9,102,111,114,32,40,105,110,116,32,105,32,61,32,48,59,32,105,32,60,32,51,59,32,43,43,105,41,13,10,9,9,123,13,10,9,9,9,118,101,99,52,32,108,105,103,104,116,67,111,108,111,114,32,61,32,76,105,103,104,116,115,91,105,93,46,99,111,108,111,114,59,13,10,9,9,9,102,108,111,97,116,32,108,105,103,104,116,65,109,98,105,101,110,116,70,97,99,116,111,114,32,61,32,76,105,103,104,116,115,91,105,93,46,102,97,99,116,111,114,115,46,120,59,13,10,9,9,9,102,108,111,97,116,32,108,105,103,104,116,68,105,102,102,117,115,101,70,97,99,116,111,114,32,61,32,76,105,103,104,116,115,91,105,93,46,102,97,99,116,111,114,115,46,121,59,13,10,13,10,9,9,9,115,119,105,116,99,104,32,40,76,105,103,104,116,115,91,105,93,46,116,121,112,101,41,13,10,9,9,9,123,13,10,9,9,9,9,99,97,115,101,32,76,73,71,72,84,95,68,73,82,69,67,84,73,79,78,65,76,58,13,10,9,9,9,9,123,13,10,9,9,9,9,9,118,101,99,51,32,108,105,103,104,116,68,105,114,32,61,32,45,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,49,46,120,121,122,59,13,10,13,10,9,9,9,9,9,47,47,32,65,109,98,105,101,110,116,13,10,9,9,9,9,9,108,105,103,104,116,65,109,98,105,101,110,116,32,43,61,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,32,42,32,108,105,103,104,116,65,109,98,105,101,110,116,70,97,99,116,111,114,32,42,32,40,77,97,116,101,114,105,97,108,65,109,98,105,101,110,116,46,114,103,98,32,43,32,83,99,101,110,101,65,109,98,105,101,110,116,46,114,103,98,41,59,13,10,13,10,9,9,9,9,9,35,105,102,32,83,72,65,68,79,87,95,77,65,80,80,73,78,71,13,10,9,9,9,9,9,105,102,32,40,76,105,103,104,116,115,91,105,93,46,115,104,97,100,111,119,77,97,112,112,105,110,103,32,38,38,32,33,84,101,115,116,83,104,97,100,111,119,68,105,114,101,99,116,105,111,110,97,108,40,105,41,41,13,10,9,9,9,9,9,9,98,114,101,97,107,59,13,10,9,9,9,9,9,35,101,110,100,105,102,13,10,13,10,9,9,9,9,9,47,47,32,68,105,102,102,117,115,101,13,10,9,9,9,9,9,102,108,111,97,116,32,108,97,109,98,101,114,116,32,61,32,109,97,120,40,100,111,116,40,110,111,114,109,97,108,44,32,108,105,103,104,116,68,105,114,41,44,32,48,46,48,41,59,13,10,13,10,9,9,9,9,9,108,105,103,104,116,68,105,102,102,117,115,101,32,43,61,32,108,97,109,98,101,114,116,32,42,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,32,42,32,108,105,103,104,116,68,105,102,102,117,115,101,70,97,99,116,111,114,59,13,10,13,10,9,9,9,9,9,47,47,32,83,112,101,99,117,108,97,114,13,10,9,9,9,9,9,118,101,99,51,32,114,101,102,108,101,99,116,105,111,110,32,61,32,114,101,102,108,101,99,116,40,45,108,105,103,104,116,68,105,114,44,32,110,111,114,109,97,108,41,59,13,10,9,9,9,9,9,102,108,111,97,116,32,115,112,101,99,117,108,97,114,70,97,99,116,111,114,32,61,32,109,97,120,40,100,111,116,40,114,101,102,108,101,99,116,105,111,110,44,32,101,121,101,86,101,99,41,44,32,48,46,48,41,59,13,10,9,9,9,9,9,115,112,101,99,117,108,97,114,70,97,99,116,111,114,32,61,32,112,111,119,40,115,112,101,99,117,108,97,114,70,97,99,116,111,114,44,32,77,97,116,101,114,105,97,108,83,104,105,110,105,110,101,115,115,41,59,13,10,13,10,9,9,9,9,9,108,105,103,104,116,83,112,101,99,117,108,97,114,32,43,61,32,115,112,101,99,117,108,97,114,70,97,99,116,111,114,32,42,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,59,13,10,9,9,9,9,9,98,114,101,97,107,59,13,10,9,9,9,9,125,13,10,13,10,9,9,9,9,99,97,115,101,32,76,73,71,72,84,95,80,79,73,78,84,58,13,10,9,9,9,9,123,13,10,9,9,9,9,9,118,101,99,51,32,108,105,103,104,116,80,111,115,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,49,46,120,121,122,59,13,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,65,116,116,101,110,117,97,116,105,111,110,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,49,46,119,59,13,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,73,110,118,82,97,100,105,117,115,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,50,46,119,59,13,10,9,9,9,9,9,13,10,9,9,9,9,9,118,101,99,51,32,119,111,114,108,100,84,111,76,105,103,104,116,32,61,32,108,105,103,104,116,80,111,115,32,45,32,118,87,111,114,108,100,80,111,115,59,13,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,68,105,114,76,101,110,103,116,104,32,61,32,108,101,110,103,116,104,40,119,111,114,108,100,84,111,76,105,103,104,116,41,59,13,10,9,9,9,9,9,118,101,99,51,32,108,105,103,104,116,68,105,114,32,61,32,119,111,114,108,100,84,111,76,105,103,104,116,32,47,32,108,105,103,104,116,68,105,114,76,101,110,103,116,104,59,32,47,47,32,78,111,114,109,97,108,105,115,97,116,105,111,110,13,10,9,9,9,9,9,13,10,9,9,9,9,9,102,108,111,97,116,32,97,116,116,32,61,32,109,97,120,40,108,105,103,104,116,65,116,116,101,110,117,97,116,105,111,110,32,45,32,108,105,103,104,116,73,110,118,82,97,100,105,117,115,32,42,32,108,105,103,104,116,68,105,114,76,101,110,103,116,104,44,32,48,46,48,41,59,13,10,13,10,9,9,9,9,9,47,47,32,65,109,98,105,101,110,116,13,10,9,9,9,9,9,108,105,103,104,116,65,109,98,105,101,110,116,32,43,61,32,97,116,116,32,42,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,32,42,32,108,105,103,104,116,65,109,98,105,101,110,116,70,97,99,116,111,114,32,42,32,40,77,97,116,101,114,105,97,108,65,109,98,105,101,110,116,46,114,103,98,32,43,32,83,99,101,110,101,65,109,98,105,101,110,116,46,114,103,98,41,59,13,10,13,10,9,9,9,9,9,35,105,102,32,83,72,65,68,79,87,95,77,65,80,80,73,78,71,13,10,9,9,9,9,9,105,102,32,40,76,105,103,104,116,115,91,105,93,46,115,104,97,100,111,119,77,97,112,112,105,110,103,32,38,38,32,33,84,101,115,116,83,104,97,100,111,119,80,111,105,110,116,40,105,44,32,118,87,111,114,108,100,80,111,115,32,45,32,108,105,103,104,116,80,111,115,44,32,48,46,49,44,32,53,48,46,48,41,41,13,10,9,9,9,9,9,9,98,114,101,97,107,59,13,10,9,9,9,9,9,35,101,110,100,105,102,13,10,13,10,9,9,9,9,9,47,47,32,68,105,102,102,117,115,101,13,10,9,9,9,9,9,102,108,111,97,116,32,108,97,109,98,101,114,116,32,61,32,109,97,120,40,100,111,116,40,110,111,114,109,97,108,44,32,108,105,103,104,116,68,105,114,41,44,32,48,46,48,41,59,13,10,9,9,9,9,9,13,10,9,9,9,9,9,108,105,103,104,116,68,105,102,102,117,115,101,32,43,61,32,97,116,116,32,42,32,108,97,109,98,101,114,116,32,42,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,32,42,32,108,105,103,104,116,68,105,102,102,117,115,101,70,97,99,116,111,114,59,13,10,13,10,9,9,9,9,9,47,47,32,83,112,101,99,117,108,97,114,13,10,9,9,9,9,9,118,101,99,51,32,114,101,102,108,101,99,116,105,111,110,32,61,32,114,101,102,108,101,99,116,40,45,108,105,103,104,116,68,105,114,44,32,110,111,114,109,97,108,41,59,13,10,9,9,9,9,9,102,108,111,97,116,32,115,112,101,99,117,108,97,114,70,97,99,116,111,114,32,61,32,109,97,120,40,100,111,116,40,114,101,102,108,101,99,116,105,111,110,44,32,101,121,101,86,101,99,41,44,32,48,46,48,41,59,13,10,9,9,9,9,9,115,112,101,99,117,108,97,114,70,97,99,116,111,114,32,61,32,112,111,119,40,115,112,101,99,117,108,97,114,70,97,99,116,111,114,44,32,77,97,116,101,114,105,97,108,83,104,105,110,105,110,101,115,115,41,59,13,10,13,10,9,9,9,9,9,108,105,103,104,116,83,112,101,99,117,108,97,114,32,43,61,32,97,116,116,32,42,32,115,112,101,99,117,108,97,114,70,97,99,116,111,114,32,42,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,59,13,10,9,9,9,9,9,98,114,101,97,107,59,13,10,9,9,9,9,125,13,10,13,10,9,9,9,9,99,97,115,101,32,76,73,71,72,84,95,83,80,79,84,58,13,10,9,9,9,9,123,13,10,9,9,9,9,9,118,101,99,51,32,108,105,103,104,116,80,111,115,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,49,46,120,121,122,59,13,10,9,9,9,9,9,118,101,99,51,32,108,105,103,104,116,68,105,114,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,50,46,120,121,122,59,13,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,65,116,116,101,110,117,97,116,105,111,110,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,49,46,119,59,13,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,73,110,118,82,97,100,105,117,115,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,50,46,119,59,13,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,73,110,110,101,114,65,110,103,108,101,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,51,46,120,59,13,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,79,117,116,101,114,65,110,103,108,101,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,51,46,121,59,13,10,13,10,9,9,9,9,9,118,101,99,51,32,119,111,114,108,100,84,111,76,105,103,104,116,32,61,32,108,105,103,104,116,80,111,115,32,45,32,118,87,111,114,108,100,80,111,115,59,13,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,68,105,115,116,97,110,99,101,32,61,32,108,101,110,103,116,104,40,119,111,114,108,100,84,111,76,105,103,104,116,41,59,13,10,9,9,9,9,9,119,111,114,108,100,84,111,76,105,103,104,116,32,47,61,32,108,105,103,104,116,68,105,115,116,97,110,99,101,59,32,47,47,32,78,111,114,109,97,108,105,115,97,116,105,111,110,13,10,9,9,9,9,9,13,10,9,9,9,9,9,102,108,111,97,116,32,97,116,116,32,61,32,109,97,120,40,108,105,103,104,116,65,116,116,101,110,117,97,116,105,111,110,32,45,32,108,105,103,104,116,73,110,118,82,97,100,105,117,115,32,42,32,108,105,103,104,116,68,105,115,116,97,110,99,101,44,32,48,46,48,41,59,13,10,13,10,9,9,9,9,9,47,47,32,65,109,98,105,101,110,116,13,10,9,9,9,9,9,108,105,103,104,116,65,109,98,105,101,110,116,32,43,61,32,97,116,116,32,42,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,32,42,32,108,105,103,104,116,65,109,98,105,101,110,116,70,97,99,116,111,114,32,42,32,40,77,97,116,101,114,105,97,108,65,109,98,105,101,110,116,46,114,103,98,32,43,32,83,99,101,110,101,65,109,98,105,101,110,116,46,114,103,98,41,59,13,10,13,10,9,9,9,9,9,35,105,102,32,83,72,65,68,79,87,95,77,65,80,80,73,78,71,13,10,9,9,9,9,9,105,102,32,40,76,105,103,104,116,115,91,105,93,46,115,104,97,100,111,119,77,97,112,112,105,110,103,32,38,38,32,33,84,101,115,116,83,104,97,100,111,119,83,112,111,116,40,105,41,41,13,10,9,9,9,9,9,9,98,114,101,97,107,59,13,10,9,9,9,9,9,35,101,110,100,105,102,13,10,13,10,9,9,9,9,9,47,47,32,77,111,100,105,102,105,99,97,116,105,111,110,32,100,101,32,108,39,97,116,116,195,169,110,117,97,116,105,111,110,32,112,111,117,114,32,103,195,169,114,101,114,32,108,101,32,115,112,111,116,13,10,9,9,9,9,9,102,108,111,97,116,32,99,117,114,65,110,103,108,101,32,61,32,100,111,116,40,108,105,103,104,116,68,105,114,44,32,45,119,111,114,108,100,84,111,76,105,103,104,116,41,59,13,10,9,9,9,9,9,102,108,111,97,116,32,105,110,110,101,114,77,105,110,117,115,79,117,116,101,114,65,110,103,108,101,32,61,32,108,105,103,104,116,73,110,110,101,114,65,110,103,108,101,32,45,32,108,105,103,104,116,79,117,116,101,114,65,110,103,108,101,59,13,10,9,9,9,9,9,97,116,116,32,42,61,32,109,97,120,40,40,99,117,114,65,110,103,108,101,32,45,32,108,105,103,104,116,79,117,116,101,114,65,110,103,108,101,41,32,47,32,105,110,110,101,114,77,105,110,117,115,79,117,116,101,114,65,110,103,108,101,44,32,48,46,48,41,59,13,10,13,10,9,9,9,9,9,47,47,32,68,105,102,102,117,115,101,13,10,9,9,9,9,9,102,108,111,97,116,32,108,97,109,98,101,114,116,32,61,32,109,97,120,40,100,111,116,40,110,111,114,109,97,108,44,32,119,111,114,108,100,84,111,76,105,103,104,116,41,44,32,48,46,48,41,59,13,10,13,10,9,9,9,9,9,108,105,103,104,116,68,105,102,102,117,115,101,32,43,61,32,97,116,116,32,42,32,108,97,109,98,101,114,116,32,42,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,32,42,32,108,105,103,104,116,68,105,102,102,117,115,101,70,97,99,116,111,114,59,13,10,13,10,9,9,9,9,9,47,47,32,83,112,101,99,117,108,97,114,13,10,9,9,9,9,9,118,101,99,51,32,114,101,102,108,101,99,116,105,111,110,32,61,32,114,101,102,108,101,99,116,40,45,119,111,114,108,100,84,111,76,105,103,104,116,44,32,110,111,114,109,97,108,41,59,13,10,9,9,9,9,9,102,108,111,97,116,32,115,112,101,99,117,108,97,114,70,97,99,116,111,114,32,61,32,109,97,120,40,100,111,116,40,114,101,102,108,101,99,116,105,111,110,44,32,101,121,101,86,101,99,41,44,32,48,46,48,41,59,13,10,9,9,9,9,9,115,112,101,99,117,108,97,114,70,97,99,116,111,114,32,61,32,112,111,119,40,115,112,101,99,117,108,97,114,70,97,99,116,111,114,44,32,77,97,116,101,114,105,97,108,83,104,105,110,105,110,101,115,115,41,59,13,10,13,10,9,9,9,9,9,108,105,103,104,116,83,112,101,99,117,108,97,114,32,43,61,32,97,116,116,32,42,32,115,112,101,99,117,108,97,114,70,97,99,116,111,114,32,42,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,59,13,10,9,9,9,9,9,98,114,101,97,107,59,13,10,9,9,9,9,125,13,10,9,9,9,9,13,10,9,9,9,9,100,101,102,97,117,108,116,58,13,10,9,9,9,9,9,98,114,101,97,107,59,13,10,9,9,9,125,13,10,9,9,125,13,10,9,125,13,10,9,101,108,115,101,13,10,9,123,13,10,9,9,102,111,114,32,40,105,110,116,32,105,32,61,32,48,59,32,105,32,60,32,51,59,32,43,43,105,41,13,10,9,9,123,13,10,9,9,9,118,101,99,52,32,108,105,103,104,116,67,111,108,111,114,32,61,32,76,105,103,104,116,115,91,105,93,46,99,111,108,111,114,59,13,10,9,9,9,102,108,111,97,116,32,108,105,103,104,116,65,109,98,105,101,110,116,70,97,99,116,111,114,32,61,32,76,105,103,104,116,115,91,105,93,46,102,97,99,116,111,114,115,46,120,59,13,10,9,9,9,102,108,111,97,116,32,108,105,103,104,116,68,105,102,102,117,115,101,70,97,99,116,111,114,32,61,32,76,105,103,104,116,115,91,105,93,46,102,97,99,116,111,114,115,46,121,59,13,10,13,10,9,9,9,115,119,105,116,99,104,32,40,76,105,103,104,116,115,91,105,93,46,116,121,112,101,41,13,10,9,9,9,123,13,10,9,9,9,9,99,97,115,101,32,76,73,71,72,84,95,68,73,82,69,67,84,73,79,78,65,76,58,13,10,9,9,9,9,123,13,10,9,9,9,9,9,118,101,99,51,32,108,105,103,104,116,68,105,114,32,61,32,45,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,49,46,120,121,122,59,13,10,13,10,9,9,9,9,9,47,47,32,65,109,98,105,101,110,116,13,10,9,9,9,9,9,108,105,103,104,116,65,109,98,105,101,110,116,32,43,61,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,32,42,32,108,105,103,104,116,65,109,98,105,101,110,116,70,97,99,116,111,114,32,42,32,40,77,97,116,101,114,105,97,108,65,109,98,105,101,110,116,46,114,103,98,32,43,32,83,99,101,110,101,65,109,98,105,101,110,116,46,114,103,98,41,59,13,10,13,10,9,9,9,9,9,47,47,32,68,105,102,102,117,115,101,13,10,9,9,9,9,9,102,108,111,97,116,32,108,97,109,98,101,114,116,32,61,32,109,97,120,40,100,111,116,40,110,111,114,109,97,108,44,32,108,105,103,104,116,68,105,114,41,44,32,48,46,48,41,59,13,10,13,10,9,9,9,9,9,108,105,103,104,116,68,105,102,102,117,115,101,32,43,61,32,108,97,109,98,101,114,116,32,42,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,32,42,32,108,105,103,104,116,68,105,102,102,117,115,101,70,97,99,116,111,114,59,13,10,9,9,9,9,9,98,114,101,97,107,59,13,10,9,9,9,9,125,13,10,13,10,9,9,9,9,99,97,115,101,32,76,73,71,72,84,95,80,79,73,78,84,58,13,10,9,9,9,9,123,13,10,9,9,9,9,9,118,101,99,51,32,108,105,103,104,116,80,111,115,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,49,46,120,121,122,59,13,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,65,116,116,101,110,117,97,116,105,111,110,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,49,46,119,59,13,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,73,110,118,82,97,100,105,117,115,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,50,46,119,59,13,10,9,9,9,9,9,13,10,9,9,9,9,9,118,101,99,51,32,119,111,114,108,100,84,111,76,105,103,104,116,32,61,32,108,105,103,104,116,80,111,115,32,45,32,118,87,111,114,108,100,80,111,115,59,13,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,68,105,114,76,101,110,103,116,104,32,61,32,108,101,110,103,116,104,40,119,111,114,108,100,84,111,76,105,103,104,116,41,59,13,10,9,9,9,9,9,118,101,99,51,32,108,105,103,104,116,68,105,114,32,61,32,119,111,114,108,100,84,111,76,105,103,104,116,32,47,32,108,105,103,104,116,68,105,114,76,101,110,103,116,104,59,32,47,47,32,78,111,114,109,97,108,105,115,97,116,105,111,110,13,10,9,9,9,9,9,13,10,9,9,9,9,9,102,108,111,97,116,32,97,116,116,32,61,32,109,97,120,40,108,105,103,104,116,65,116,116,101,110,117,97,116,105,111,110,32,45,32,108,105,103,104,116,73,110,118,82,97,100,105,117,115,32,42,32,108,105,103,104,116,68,105,114,76,101,110,103,116,104,44,32,48,46,48,41,59,13,10,13,10,9,9,9,9,9,47,47,32,65,109,98,105,101,110,116,13,10,9,9,9,9,9,108,105,103,104,116,65,109,98,105,101,110,116,32,43,61,32,97,116,116,32,42,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,32,42,32,108,105,103,104,116,65,109,98,105,101,110,116,70,97,99,116,111,114,32,42,32,40,77,97,116,101,114,105,97,108,65,109,98,105,101,110,116,46,114,103,98,32,43,32,83,99,101,110,101,65,109,98,105,101,110,116,46,114,103,98,41,59,13,10,13,10,9,9,9,9,9,35,105,102,32,83,72,65,68,79,87,95,77,65,80,80,73,78,71,13,10,9,9,9,9,9,105,102,32,40,76,105,103,104,116,115,91,105,93,46,115,104,97,100,111,119,77,97,112,112,105,110,103,32,38,38,32,33,84,101,115,116,83,104,97,100,111,119,80,111,105,110,116,40,105,44,32,118,87,111,114,108,100,80,111,115,32,45,32,108,105,103,104,116,80,111,115,44,32,48,46,49,44,32,49,46,48,32,47,32,108,105,103,104,116,73,110,118,82,97,100,105,117,115,41,41,13,10,9,9,9,9,9,9,98,114,101,97,107,59,13,10,9,9,9,9,9,35,101,110,100,105,102,13,10,13,10,9,9,9,9,9,47,47,32,68,105,102,102,117,115,101,13,10,9,9,9,9,9,102,108,111,97,116,32,108,97,109,98,101,114,116,32,61,32,109,97,120,40,100,111,116,40,110,111,114,109,97,108,44,32,108,105,103,104,116,68,105,114,41,44,32,48,46,48,41,59,13,10,9,9,9,9,9,13,10,9,9,9,9,9,108,105,103,104,116,68,105,102,102,117,115,101,32,43,61,32,97,116,116,32,42,32,108,97,109,98,101,114,116,32,42,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,32,42,32,108,105,103,104,116,68,105,102,102,117,115,101,70,97,99,116,111,114,59,13,10,9,9,9,9,9,98,114,101,97,107,59,13,10,9,9,9,9,125,13,10,13,10,9,9,9,9,99,97,115,101,32,76,73,71,72,84,95,83,80,79,84,58,13,10,9,9,9,9,123,13,10,9,9,9,9,9,118,101,99,51,32,108,105,103,104,116,80,111,115,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,49,46,120,121,122,59,13,10,9,9,9,9,9,118,101,99,51,32,108,105,103,104,116,68,105,114,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,50,46,120,121,122,59,13,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,65,116,116,101,110,117,97,116,105,111,110,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,49,46,119,59,13,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,73,110,118,82,97,100,105,117,115,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,50,46,119,59,13,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,73,110,110,101,114,65,110,103,108,101,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,51,46,120,59,13,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,79,117,116,101,114,65,110,103,108,101,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,51,46,121,59,13,10,13,10,9,9,9,9,9,118,101,99,51,32,119,111,114,108,100,84,111,76,105,103,104,116,32,61,32,108,105,103,104,116,80,111,115,32,45,32,118,87,111,114,108,100,80,111,115,59,13,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,68,105,115,116,97,110,99,101,32,61,32,108,101,110,103,116,104,40,119,111,114,108,100,84,111,76,105,103,104,116,41,59,13,10,9,9,9,9,9,119,111,114,108,100,84,111,76,105,103,104,116,32,47,61,32,108,105,103,104,116,68,105,115,116,97,110,99,101,59,32,47,47,32,78,111,114,109,97,108,105,115,97,116,105,111,110,13,10,9,9,9,9,9,13,10,9,9,9,9,9,102,108,111,97,116,32,97,116,116,32,61,32,109,97,120,40,108,105,103,104,116,65,116,116,101,110,117,97,116,105,111,110,32,45,32,108,105,103,104,116,73,110,118,82,97,100,105,117,115,32,42,32,108,105,103,104,116,68,105,115,116,97,110,99,101,44,32,48,46,48,41,59,13,10,13,10,9,9,9,9,9,47,47,32,65,109,98,105,101,110,116,13,10,9,9,9,9,9,108,105,103,104,116,65,109,98,105,101,110,116,32,43,61,32,97,116,116,32,42,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,32,42,32,108,105,103,104,116,65,109,98,105,101,110,116,70,97,99,116,111,114,32,42,32,40,77,97,116,101,114,105,97,108,65,109,98,105,101,110,116,46,114,103,98,32,43,32,83,99,101,110,101,65,109,98,105,101,110,116,46,114,103,98,41,59,13,10,13,10,9,9,9,9,9,35,105,102,32,83,72,65,68,79,87,95,77,65,80,80,73,78,71,13,10,9,9,9,9,9,105,102,32,40,76,105,103,104,116,115,91,105,93,46,115,104,97,100,111,119,77,97,112,112,105,110,103,32,38,38,32,33,84,101,115,116,83,104,97,100,111,119,83,112,111,116,40,105,41,41,13,10,9,9,9,9,9,9,98,114,101,97,107,59,13,10,9,9,9,9,9,35,101,110,100,105,102,13,10,13,10,9,9,9,9,9,47,47,32,77,111,100,105,102,105,99,97,116,105,111,110,32,100,101,32,108,39,97,116,116,195,169,110,117,97,116,105,111,110,32,112,111,117,114,32,103,195,169,114,101,114,32,108,101,32,115,112,111,116,13,10,9,9,9,9,9,102,108,111,97,116,32,99,117,114,65,110,103,108,101,32,61,32,100,111,116,40,108,105,103,104,116,68,105,114,44,32,45,119,111,114,108,100,84,111,76,105,103,104,116,41,59,13,10,9,9,9,9,9,102,108,111,97,116,32,105,110,110,101,114,77,105,110,117,115,79,117,116,101,114,65,110,103,108,101,32,61,32,108,105,103,104,116,73,110,110,101,114,65,110,103,108,101,32,45,32,108,105,103,104,116,79,117,116,101,114,65,110,103,108,101,59,13,10,9,9,9,9,9,97,116,116,32,42,61,32,109,97,120,40,40,99,117,114,65,110,103,108,101,32,45,32,108,105,103,104,116,79,117,116,101,114,65,110,103,108,101,41,32,47,32,105,110,110,101,114,77,105,110,117,115,79,117,116,101,114,65,110,103,108,101,44,32,48,46,48,41,59,13,10,13,10,9,9,9,9,9,47,47,32,68,105,102,102,117,115,101,13,10,9,9,9,9,9,102,108,111,97,116,32,108,97,109,98,101,114,116,32,61,32,109,97,120,40,100,111,116,40,110,111,114,109,97,108,44,32,119,111,114,108,100,84,111,76,105,103,104,116,41,44,32,48,46,48,41,59,13,10,13,10,9,9,9,9,9,108,105,103,104,116,68,105,102,102,117,115,101,32,43,61,32,97,116,116,32,42,32,108,97,109,98,101,114,116,32,42,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,32,42,32,108,105,103,104,116,68,105,102,102,117,115,101,70,97,99,116,111,114,59,13,10,9,9,9,9,125,13,10,9,9,9,9,13,10,9,9,9,9,100,101,102,97,117,108,116,58,13,10,9,9,9,9,9,98,114,101,97,107,59,13,10,9,9,9,125,13,10,9,9,125,13,10,9,125,13,10,9,13,10,9,108,105,103,104,116,83,112,101,99,117,108,97,114,32,42,61,32,77,97,116,101,114,105,97,108,83,112,101,99,117,108,97,114,46,114,103,98,59,13,10,9,9,35,105,102,32,83,80,69,67,85,76,65,82,95,77,65,80,80,73,78,71,13,10,9,108,105,103,104,116,83,112,101,99,117,108,97,114,32,42,61,32,116,101,120,116,117,114,101,40,77,97,116,101,114,105,97,108,83,112,101,99,117,108,97,114,77,97,112,44,32,116,101,120,67,111,111,114,100,41,46,114,103,98,59,32,47,47,32,85,116,105,108,105,115,101,114,32,108,39,97,108,112,104,97,32,100,101,32,77,97,116,101,114,105,97,108,83,112,101,99,117,108,97,114,32,110,39,97,117,114,97,105,116,32,97,117,99,117,110,32,115,101,110,115,13,10,9,9,35,101,110,100,105,102,13,10,9,9,13,10,9,118,101,99,51,32,108,105,103,104,116,67,111,108,111,114,32,61,32,40,108,105,103,104,116,65,109,98,105,101,110,116,32,43,32,108,105,103,104,116,68,105,102,102,117,115,101,32,43,32,108,105,103,104,116,83,112,101,99,117,108,97,114,41,59,13,10,9,118,101,99,52,32,102,114,97,103,109,101,110,116,67,111,108,111,114,32,61,32,118,101,99,52,40,108,105,103,104,116,67,111,108,111,114,44,32,49,46,48,41,32,42,32,100,105,102,102,117,115,101,67,111,108,111,114,59,13,10,13,10,9,9,35,105,102,32,69,77,73,83,83,73,86,69,95,77,65,80,80,73,78,71,13,10,9,102,108,111,97,116,32,108,105,103,104,116,73,110,116,101,110,115,105,116,121,32,61,32,100,111,116,40,108,105,103,104,116,67,111,108,111,114,44,32,118,101,99,51,40,48,46,51,44,32,48,46,53,57,44,32,48,46,49,49,41,41,59,13,10,13,10,9,118,101,99,51,32,101,109,105,115,115,105,111,110,67,111,108,111,114,32,61,32,77,97,116,101,114,105,97,108,68,105,102,102,117,115,101,46,114,103,98,32,42,32,116,101,120,116,117,114,101,40,77,97,116,101,114,105,97,108,69,109,105,115,115,105,118,101,77,97,112,44,32,116,101,120,67,111,111,114,100,41,46,114,103,98,59,13,10,9,82,101,110,100,101,114,84,97,114,103,101,116,48,32,61,32,118,101,99,52,40,109,105,120,40,102,114,97,103,109,101,110,116,67,111,108,111,114,46,114,103,98,44,32,101,109,105,115,115,105,111,110,67,111,108,111,114,44,32,99,108,97,109,112,40,49,46,48,32,45,32,51,46,48,42,108,105,103,104,116,73,110,116,101,110,115,105,116,121,44,32,48,46,48,44,32,49,46,48,41,41,44,32,102,114,97,103,109,101,110,116,67,111,108,111,114,46,97,41,59,13,10,9,9,35,101,108,115,101,13,10,9,82,101,110,100,101,114,84,97,114,103,101,116,48,32,61,32,102,114,97,103,109,101,110,116,67,111,108,111,114,59,13,10,9,9,35,101,110,100,105,102,32,47,47,32,69,77,73,83,83,73,86,69,95,77,65,80,80,73,78,71,13,10,9,35,101,108,115,101,13,10,9,82,101,110,100,101,114,84,97,114,103,101,116,48,32,61,32,100,105,102,102,117,115,101,67,111,108,111,114,59,13,10,9,35,101,110,100,105,102,32,47,47,32,76,73,71,72,84,73,78,71,13,10,35,101,110,100,105,102,32,47,47,32,70,76,65,71,95,68,69,70,69,82,82,69,68,13,10,125,13,10,13,10, \ No newline at end of file From 6a2e0da88f1bd7b89f96a92ea45c926ca197036e Mon Sep 17 00:00:00 2001 From: Lynix Date: Thu, 13 Aug 2015 13:54:57 +0200 Subject: [PATCH 29/37] SDK/Entity: Fix destruction Former-commit-id: 045e771bc67f6141b4bd8d5a32d151fb09526857 --- SDK/src/NDK/Entity.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/SDK/src/NDK/Entity.cpp b/SDK/src/NDK/Entity.cpp index 9d05a504d..d26a8f953 100644 --- a/SDK/src/NDK/Entity.cpp +++ b/SDK/src/NDK/Entity.cpp @@ -119,8 +119,6 @@ namespace Ndk void Entity::Destroy() { - m_valid = false; - // On informe chaque système for (SystemIndex index = m_systemBits.FindFirst(); index != m_systemBits.npos; index = m_systemBits.FindNext(index)) { @@ -137,5 +135,7 @@ namespace Ndk handle->OnEntityDestroyed(); m_handles.clear(); + + m_valid = false; } } From fabe42dc3abd5e4980941b824cc2a71295b45c36 Mon Sep 17 00:00:00 2001 From: Lynix Date: Thu, 13 Aug 2015 13:55:14 +0200 Subject: [PATCH 30/37] Renderer/Texture: Set up compare mode Former-commit-id: 6f85b6956530ea27b5bb96eb9b51a3ddc702f71b --- src/Nazara/Renderer/Texture.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/Nazara/Renderer/Texture.cpp b/src/Nazara/Renderer/Texture.cpp index 303b983fa..2db286640 100644 --- a/src/Nazara/Renderer/Texture.cpp +++ b/src/Nazara/Renderer/Texture.cpp @@ -1269,6 +1269,12 @@ bool NzTexture::CreateTexture(bool proxy) glTexParameteri(target, GL_TEXTURE_SWIZZLE_A, openGLFormat.swizzle[3]); } + if (!proxy && NzPixelFormat::GetType(m_impl->format) == nzPixelFormatType_Depth) + { + glTexParameteri(target, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE); + glTexParameteri(target, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL); + } + return true; } From 5cad63c21bf0dc6914a6614281cba157dbdb343e Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 14 Aug 2015 14:13:53 +0200 Subject: [PATCH 31/37] Graphics/Shadow: Implement PCF for spot lights Former-commit-id: 0045af26b612a5c41268fcf3e3d03893e01c0448 --- .../Resources/Shaders/PhongLighting/core.frag | 96 +++++++++++++++---- .../Shaders/PhongLighting/core.frag.h | 2 +- 2 files changed, 76 insertions(+), 22 deletions(-) diff --git a/src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.frag b/src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.frag index 6f4b1e3aa..9e446aefd 100644 --- a/src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.frag +++ b/src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.frag @@ -87,28 +87,37 @@ vec4 EncodeNormal(in vec3 normal) float VectorToDepthValue(vec3 vec, float zNear, float zFar) { - vec3 absVec = abs(vec); - float localZ = max(absVec.x, max(absVec.y, absVec.z)); + vec3 absVec = abs(vec); + float localZ = max(absVec.x, max(absVec.y, absVec.z)); float normZ = ((zFar + zNear) * localZ - (2.0*zFar*zNear)) / ((zFar - zNear)*localZ); return (normZ + 1.0) * 0.5; } -bool TestShadowDirectional(int lightIndex) +float CalculateDirectionalShadowFactor(int lightIndex) { vec4 lightSpacePos = vLightSpacePos[lightIndex]; - return texture(DirectionalSpotLightShadowMap[lightIndex], lightSpacePos.xy).x >= (lightSpacePos.z - 0.0005); + return (texture(DirectionalSpotLightShadowMap[lightIndex], lightSpacePos.xy).x >= (lightSpacePos.z - 0.0005)) ? 1.0 : 0.0; } -bool TestShadowPoint(int lightIndex, vec3 lightToWorld, float zNear, float zFar) +float CalculatePointShadowFactor(int lightIndex, vec3 lightToWorld, float zNear, float zFar) { - return texture(PointLightShadowMap[lightIndex], vec3(lightToWorld.x, -lightToWorld.y, -lightToWorld.z)).x >= VectorToDepthValue(lightToWorld, zNear, zFar); + return (texture(PointLightShadowMap[lightIndex], vec3(lightToWorld.x, -lightToWorld.y, -lightToWorld.z)).x >= VectorToDepthValue(lightToWorld, zNear, zFar)) ? 1.0 : 0.0; } -bool TestShadowSpot(int lightIndex) +float CalculateSpotShadowFactor(int lightIndex) { vec4 lightSpacePos = vLightSpacePos[lightIndex]; - return textureProj(DirectionalSpotLightShadowMap[lightIndex], lightSpacePos.xyw).x >= (lightSpacePos.z - 0.0005)/lightSpacePos.w; + + float visibility = 1.0; + float x,y; + for (y = -3.5; y <= 3.5; y+= 1.0) + for (x = -3.5; x <= 3.5; x+= 1.0) + visibility += textureProj(DirectionalSpotLightShadowMap[lightIndex], lightSpacePos + vec4(x/1024.0 * lightSpacePos.w, y/1024.0 * lightSpacePos.w, 0.05, 0.0)); + + visibility /= 64.0; + + return visibility; } void main() @@ -211,22 +220,30 @@ void main() // Ambient lightAmbient += lightColor.rgb * lightAmbientFactor * (MaterialAmbient.rgb + SceneAmbient.rgb); + float att = 1.0; + #if SHADOW_MAPPING - if (Lights[i].shadowMapping && !TestShadowDirectional(i)) - break; + if (Lights[i].shadowMapping) + { + float shadowFactor = CalculateDirectionalShadowFactor(i); + if (shadowFactor == 0.0) + break; + + att *= shadowFactor; + } #endif // Diffuse float lambert = max(dot(normal, lightDir), 0.0); - lightDiffuse += lambert * lightColor.rgb * lightDiffuseFactor; + lightDiffuse += att * lambert * lightColor.rgb * lightDiffuseFactor; // Specular vec3 reflection = reflect(-lightDir, normal); float specularFactor = max(dot(reflection, eyeVec), 0.0); specularFactor = pow(specularFactor, MaterialShininess); - lightSpecular += specularFactor * lightColor.rgb; + lightSpecular += att * specularFactor * lightColor.rgb; break; } @@ -246,8 +263,14 @@ void main() lightAmbient += att * lightColor.rgb * lightAmbientFactor * (MaterialAmbient.rgb + SceneAmbient.rgb); #if SHADOW_MAPPING - if (Lights[i].shadowMapping && !TestShadowPoint(i, vWorldPos - lightPos, 0.1, 50.0)) - break; + if (Lights[i].shadowMapping) + { + float shadowFactor = CalculatePointShadowFactor(i, vWorldPos - lightPos, 0.1, 50.0); + if (shadowFactor == 0.0) + break; + + att *= shadowFactor; + } #endif // Diffuse @@ -283,8 +306,14 @@ void main() lightAmbient += att * lightColor.rgb * lightAmbientFactor * (MaterialAmbient.rgb + SceneAmbient.rgb); #if SHADOW_MAPPING - if (Lights[i].shadowMapping && !TestShadowSpot(i)) - break; + if (Lights[i].shadowMapping) + { + float shadowFactor = CalculateSpotShadowFactor(i); + if (shadowFactor == 0.0) + break; + + att *= shadowFactor; + } #endif // Modification de l'atténuation pour gérer le spot @@ -328,10 +357,23 @@ void main() // Ambient lightAmbient += lightColor.rgb * lightAmbientFactor * (MaterialAmbient.rgb + SceneAmbient.rgb); + float att = 1.0; + + #if SHADOW_MAPPING + if (Lights[i].shadowMapping) + { + float shadowFactor = CalculateDirectionalShadowFactor(i); + if (shadowFactor == 0.0) + break; + + att *= shadowFactor; + } + #endif + // Diffuse float lambert = max(dot(normal, lightDir), 0.0); - lightDiffuse += lambert * lightColor.rgb * lightDiffuseFactor; + lightDiffuse += att * lambert * lightColor.rgb * lightDiffuseFactor; break; } @@ -351,8 +393,14 @@ void main() lightAmbient += att * lightColor.rgb * lightAmbientFactor * (MaterialAmbient.rgb + SceneAmbient.rgb); #if SHADOW_MAPPING - if (Lights[i].shadowMapping && !TestShadowPoint(i, vWorldPos - lightPos, 0.1, 1.0 / lightInvRadius)) - break; + if (Lights[i].shadowMapping) + { + float shadowFactor = CalculatePointShadowFactor(i, vWorldPos - lightPos, 0.1, 50.0); + if (shadowFactor == 0.0) + break; + + att *= shadowFactor; + } #endif // Diffuse @@ -381,8 +429,14 @@ void main() lightAmbient += att * lightColor.rgb * lightAmbientFactor * (MaterialAmbient.rgb + SceneAmbient.rgb); #if SHADOW_MAPPING - if (Lights[i].shadowMapping && !TestShadowSpot(i)) - break; + if (Lights[i].shadowMapping) + { + float shadowFactor = CalculateSpotShadowFactor(i); + if (shadowFactor == 0.0) + break; + + att *= shadowFactor; + } #endif // Modification de l'atténuation pour gérer le spot diff --git a/src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.frag.h b/src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.frag.h index d617f915b..2fdfa2e06 100644 --- a/src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.frag.h +++ b/src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.frag.h @@ -1 +1 @@ -35,105,102,32,69,65,82,76,89,95,70,82,65,71,77,69,78,84,95,84,69,83,84,83,32,38,38,32,33,65,76,80,72,65,95,84,69,83,84,13,10,108,97,121,111,117,116,40,101,97,114,108,121,95,102,114,97,103,109,101,110,116,95,116,101,115,116,115,41,32,105,110,59,13,10,35,101,110,100,105,102,13,10,13,10,35,100,101,102,105,110,101,32,76,73,71,72,84,95,68,73,82,69,67,84,73,79,78,65,76,32,48,13,10,35,100,101,102,105,110,101,32,76,73,71,72,84,95,80,79,73,78,84,32,49,13,10,35,100,101,102,105,110,101,32,76,73,71,72,84,95,83,80,79,84,32,50,13,10,13,10,47,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,69,110,116,114,97,110,116,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,47,13,10,105,110,32,118,101,99,52,32,118,67,111,108,111,114,59,13,10,105,110,32,118,101,99,52,32,118,76,105,103,104,116,83,112,97,99,101,80,111,115,91,51,93,59,13,10,105,110,32,109,97,116,51,32,118,76,105,103,104,116,84,111,87,111,114,108,100,59,13,10,105,110,32,118,101,99,51,32,118,78,111,114,109,97,108,59,13,10,105,110,32,118,101,99,50,32,118,84,101,120,67,111,111,114,100,59,13,10,105,110,32,118,101,99,51,32,118,86,105,101,119,68,105,114,59,13,10,105,110,32,118,101,99,51,32,118,87,111,114,108,100,80,111,115,59,13,10,13,10,47,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,83,111,114,116,97,110,116,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,47,13,10,111,117,116,32,118,101,99,52,32,82,101,110,100,101,114,84,97,114,103,101,116,48,59,13,10,111,117,116,32,118,101,99,52,32,82,101,110,100,101,114,84,97,114,103,101,116,49,59,13,10,111,117,116,32,118,101,99,52,32,82,101,110,100,101,114,84,97,114,103,101,116,50,59,13,10,13,10,47,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,85,110,105,102,111,114,109,101,115,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,47,13,10,115,116,114,117,99,116,32,76,105,103,104,116,13,10,123,13,10,9,105,110,116,32,116,121,112,101,59,13,10,9,118,101,99,52,32,99,111,108,111,114,59,13,10,9,118,101,99,50,32,102,97,99,116,111,114,115,59,13,10,13,10,9,118,101,99,52,32,112,97,114,97,109,101,116,101,114,115,49,59,13,10,9,118,101,99,52,32,112,97,114,97,109,101,116,101,114,115,50,59,13,10,9,118,101,99,50,32,112,97,114,97,109,101,116,101,114,115,51,59,13,10,9,98,111,111,108,32,115,104,97,100,111,119,77,97,112,112,105,110,103,59,13,10,125,59,13,10,13,10,47,47,32,76,117,109,105,195,168,114,101,115,13,10,117,110,105,102,111,114,109,32,76,105,103,104,116,32,76,105,103,104,116,115,91,51,93,59,13,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,67,117,98,101,32,80,111,105,110,116,76,105,103,104,116,83,104,97,100,111,119,77,97,112,91,51,93,59,13,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,68,105,114,101,99,116,105,111,110,97,108,83,112,111,116,76,105,103,104,116,83,104,97,100,111,119,77,97,112,91,51,93,59,13,10,13,10,47,47,32,77,97,116,195,169,114,105,97,117,13,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,77,97,116,101,114,105,97,108,65,108,112,104,97,77,97,112,59,13,10,117,110,105,102,111,114,109,32,102,108,111,97,116,32,77,97,116,101,114,105,97,108,65,108,112,104,97,84,104,114,101,115,104,111,108,100,59,13,10,117,110,105,102,111,114,109,32,118,101,99,52,32,77,97,116,101,114,105,97,108,65,109,98,105,101,110,116,59,13,10,117,110,105,102,111,114,109,32,118,101,99,52,32,77,97,116,101,114,105,97,108,68,105,102,102,117,115,101,59,13,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,77,97,116,101,114,105,97,108,68,105,102,102,117,115,101,77,97,112,59,13,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,77,97,116,101,114,105,97,108,69,109,105,115,115,105,118,101,77,97,112,59,13,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,77,97,116,101,114,105,97,108,72,101,105,103,104,116,77,97,112,59,13,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,77,97,116,101,114,105,97,108,78,111,114,109,97,108,77,97,112,59,13,10,117,110,105,102,111,114,109,32,102,108,111,97,116,32,77,97,116,101,114,105,97,108,83,104,105,110,105,110,101,115,115,59,13,10,117,110,105,102,111,114,109,32,118,101,99,52,32,77,97,116,101,114,105,97,108,83,112,101,99,117,108,97,114,59,13,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,77,97,116,101,114,105,97,108,83,112,101,99,117,108,97,114,77,97,112,59,13,10,13,10,47,47,32,65,117,116,114,101,115,13,10,117,110,105,102,111,114,109,32,102,108,111,97,116,32,80,97,114,97,108,108,97,120,66,105,97,115,32,61,32,45,48,46,48,51,59,13,10,117,110,105,102,111,114,109,32,102,108,111,97,116,32,80,97,114,97,108,108,97,120,83,99,97,108,101,32,61,32,48,46,48,50,59,13,10,117,110,105,102,111,114,109,32,118,101,99,50,32,73,110,118,84,97,114,103,101,116,83,105,122,101,59,13,10,117,110,105,102,111,114,109,32,118,101,99,51,32,69,121,101,80,111,115,105,116,105,111,110,59,13,10,117,110,105,102,111,114,109,32,118,101,99,52,32,83,99,101,110,101,65,109,98,105,101,110,116,59,13,10,13,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,84,101,120,116,117,114,101,79,118,101,114,108,97,121,59,13,10,13,10,47,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,70,111,110,99,116,105,111,110,115,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,47,13,10,118,101,99,51,32,70,108,111,97,116,84,111,67,111,108,111,114,40,102,108,111,97,116,32,102,41,13,10,123,13,10,9,118,101,99,51,32,99,111,108,111,114,59,13,10,13,10,9,102,32,42,61,32,50,53,54,46,48,59,13,10,9,99,111,108,111,114,46,120,32,61,32,102,108,111,111,114,40,102,41,59,13,10,13,10,9,102,32,61,32,40,102,32,45,32,99,111,108,111,114,46,120,41,32,42,32,50,53,54,46,48,59,13,10,9,99,111,108,111,114,46,121,32,61,32,102,108,111,111,114,40,102,41,59,13,10,13,10,9,99,111,108,111,114,46,122,32,61,32,102,32,45,32,99,111,108,111,114,46,121,59,13,10,9,99,111,108,111,114,46,120,121,32,42,61,32,48,46,48,48,51,57,48,54,50,53,59,32,47,47,32,42,61,32,49,46,48,47,50,53,54,13,10,13,10,9,114,101,116,117,114,110,32,99,111,108,111,114,59,13,10,125,13,10,13,10,35,100,101,102,105,110,101,32,107,80,73,32,51,46,49,52,49,53,57,50,54,53,51,54,13,10,13,10,118,101,99,52,32,69,110,99,111,100,101,78,111,114,109,97,108,40,105,110,32,118,101,99,51,32,110,111,114,109,97,108,41,13,10,123,13,10,9,47,47,114,101,116,117,114,110,32,118,101,99,52,40,110,111,114,109,97,108,42,48,46,53,32,43,32,48,46,53,44,32,48,46,48,41,59,13,10,9,114,101,116,117,114,110,32,118,101,99,52,40,118,101,99,50,40,97,116,97,110,40,110,111,114,109,97,108,46,121,44,32,110,111,114,109,97,108,46,120,41,47,107,80,73,44,32,110,111,114,109,97,108,46,122,41,44,32,48,46,48,44,32,48,46,48,41,59,13,10,125,13,10,13,10,102,108,111,97,116,32,86,101,99,116,111,114,84,111,68,101,112,116,104,86,97,108,117,101,40,118,101,99,51,32,118,101,99,44,32,102,108,111,97,116,32,122,78,101,97,114,44,32,102,108,111,97,116,32,122,70,97,114,41,13,10,123,13,10,32,32,32,32,118,101,99,51,32,97,98,115,86,101,99,32,61,32,97,98,115,40,118,101,99,41,59,13,10,32,32,32,32,102,108,111,97,116,32,108,111,99,97,108,90,32,61,32,109,97,120,40,97,98,115,86,101,99,46,120,44,32,109,97,120,40,97,98,115,86,101,99,46,121,44,32,97,98,115,86,101,99,46,122,41,41,59,13,10,13,10,9,102,108,111,97,116,32,110,111,114,109,90,32,61,32,40,40,122,70,97,114,32,43,32,122,78,101,97,114,41,32,42,32,108,111,99,97,108,90,32,45,32,40,50,46,48,42,122,70,97,114,42,122,78,101,97,114,41,41,32,47,32,40,40,122,70,97,114,32,45,32,122,78,101,97,114,41,42,108,111,99,97,108,90,41,59,13,10,9,114,101,116,117,114,110,32,40,110,111,114,109,90,32,43,32,49,46,48,41,32,42,32,48,46,53,59,13,10,125,13,10,13,10,98,111,111,108,32,84,101,115,116,83,104,97,100,111,119,68,105,114,101,99,116,105,111,110,97,108,40,105,110,116,32,108,105,103,104,116,73,110,100,101,120,41,13,10,123,13,10,9,118,101,99,52,32,108,105,103,104,116,83,112,97,99,101,80,111,115,32,61,32,118,76,105,103,104,116,83,112,97,99,101,80,111,115,91,108,105,103,104,116,73,110,100,101,120,93,59,13,10,9,114,101,116,117,114,110,32,116,101,120,116,117,114,101,40,68,105,114,101,99,116,105,111,110,97,108,83,112,111,116,76,105,103,104,116,83,104,97,100,111,119,77,97,112,91,108,105,103,104,116,73,110,100,101,120,93,44,32,108,105,103,104,116,83,112,97,99,101,80,111,115,46,120,121,41,46,120,32,62,61,32,40,108,105,103,104,116,83,112,97,99,101,80,111,115,46,122,32,45,32,48,46,48,48,48,53,41,59,13,10,125,13,10,13,10,98,111,111,108,32,84,101,115,116,83,104,97,100,111,119,80,111,105,110,116,40,105,110,116,32,108,105,103,104,116,73,110,100,101,120,44,32,118,101,99,51,32,108,105,103,104,116,84,111,87,111,114,108,100,44,32,102,108,111,97,116,32,122,78,101,97,114,44,32,102,108,111,97,116,32,122,70,97,114,41,13,10,123,13,10,9,114,101,116,117,114,110,32,116,101,120,116,117,114,101,40,80,111,105,110,116,76,105,103,104,116,83,104,97,100,111,119,77,97,112,91,108,105,103,104,116,73,110,100,101,120,93,44,32,118,101,99,51,40,108,105,103,104,116,84,111,87,111,114,108,100,46,120,44,32,45,108,105,103,104,116,84,111,87,111,114,108,100,46,121,44,32,45,108,105,103,104,116,84,111,87,111,114,108,100,46,122,41,41,46,120,32,62,61,32,86,101,99,116,111,114,84,111,68,101,112,116,104,86,97,108,117,101,40,108,105,103,104,116,84,111,87,111,114,108,100,44,32,122,78,101,97,114,44,32,122,70,97,114,41,59,13,10,125,13,10,13,10,98,111,111,108,32,84,101,115,116,83,104,97,100,111,119,83,112,111,116,40,105,110,116,32,108,105,103,104,116,73,110,100,101,120,41,13,10,123,13,10,9,118,101,99,52,32,108,105,103,104,116,83,112,97,99,101,80,111,115,32,61,32,118,76,105,103,104,116,83,112,97,99,101,80,111,115,91,108,105,103,104,116,73,110,100,101,120,93,59,13,10,9,114,101,116,117,114,110,32,116,101,120,116,117,114,101,80,114,111,106,40,68,105,114,101,99,116,105,111,110,97,108,83,112,111,116,76,105,103,104,116,83,104,97,100,111,119,77,97,112,91,108,105,103,104,116,73,110,100,101,120,93,44,32,108,105,103,104,116,83,112,97,99,101,80,111,115,46,120,121,119,41,46,120,32,62,61,32,40,108,105,103,104,116,83,112,97,99,101,80,111,115,46,122,32,45,32,48,46,48,48,48,53,41,47,108,105,103,104,116,83,112,97,99,101,80,111,115,46,119,59,13,10,125,13,10,13,10,118,111,105,100,32,109,97,105,110,40,41,13,10,123,13,10,9,118,101,99,52,32,100,105,102,102,117,115,101,67,111,108,111,114,32,61,32,77,97,116,101,114,105,97,108,68,105,102,102,117,115,101,32,42,32,118,67,111,108,111,114,59,13,10,13,10,35,105,102,32,65,85,84,79,95,84,69,88,67,79,79,82,68,83,13,10,9,118,101,99,50,32,116,101,120,67,111,111,114,100,32,61,32,103,108,95,70,114,97,103,67,111,111,114,100,46,120,121,32,42,32,73,110,118,84,97,114,103,101,116,83,105,122,101,59,13,10,35,101,108,115,101,13,10,9,118,101,99,50,32,116,101,120,67,111,111,114,100,32,61,32,118,84,101,120,67,111,111,114,100,59,13,10,35,101,110,100,105,102,13,10,13,10,35,105,102,32,76,73,71,72,84,73,78,71,32,38,38,32,80,65,82,65,76,76,65,88,95,77,65,80,80,73,78,71,13,10,9,102,108,111,97,116,32,104,101,105,103,104,116,32,61,32,116,101,120,116,117,114,101,40,77,97,116,101,114,105,97,108,72,101,105,103,104,116,77,97,112,44,32,116,101,120,67,111,111,114,100,41,46,114,59,13,10,9,102,108,111,97,116,32,118,32,61,32,104,101,105,103,104,116,42,80,97,114,97,108,108,97,120,83,99,97,108,101,32,43,32,80,97,114,97,108,108,97,120,66,105,97,115,59,13,10,13,10,9,118,101,99,51,32,118,105,101,119,68,105,114,32,61,32,110,111,114,109,97,108,105,122,101,40,118,86,105,101,119,68,105,114,41,59,13,10,9,116,101,120,67,111,111,114,100,32,43,61,32,118,32,42,32,118,105,101,119,68,105,114,46,120,121,59,13,10,35,101,110,100,105,102,13,10,13,10,35,105,102,32,68,73,70,70,85,83,69,95,77,65,80,80,73,78,71,13,10,9,100,105,102,102,117,115,101,67,111,108,111,114,32,42,61,32,116,101,120,116,117,114,101,40,77,97,116,101,114,105,97,108,68,105,102,102,117,115,101,77,97,112,44,32,116,101,120,67,111,111,114,100,41,59,13,10,35,101,110,100,105,102,13,10,13,10,35,105,102,32,70,76,65,71,95,84,69,88,84,85,82,69,79,86,69,82,76,65,89,13,10,9,100,105,102,102,117,115,101,67,111,108,111,114,32,42,61,32,116,101,120,116,117,114,101,40,84,101,120,116,117,114,101,79,118,101,114,108,97,121,44,32,116,101,120,67,111,111,114,100,41,59,13,10,35,101,110,100,105,102,13,10,13,10,35,105,102,32,70,76,65,71,95,68,69,70,69,82,82,69,68,13,10,9,35,105,102,32,65,76,80,72,65,95,84,69,83,84,13,10,9,9,47,47,32,73,110,117,116,105,108,101,32,100,101,32,102,97,105,114,101,32,100,101,32,108,39,97,108,112,104,97,45,109,97,112,112,105,110,103,32,115,97,110,115,32,97,108,112,104,97,45,116,101,115,116,32,101,110,32,68,101,102,101,114,114,101,100,32,40,108,39,97,108,112,104,97,32,110,39,101,115,116,32,112,97,115,32,115,97,117,118,101,103,97,114,100,195,169,32,100,97,110,115,32,108,101,32,71,45,66,117,102,102,101,114,41,13,10,9,9,35,105,102,32,65,76,80,72,65,95,77,65,80,80,73,78,71,13,10,9,100,105,102,102,117,115,101,67,111,108,111,114,46,97,32,42,61,32,116,101,120,116,117,114,101,40,77,97,116,101,114,105,97,108,65,108,112,104,97,77,97,112,44,32,116,101,120,67,111,111,114,100,41,46,114,59,13,10,9,9,35,101,110,100,105,102,13,10,9,9,13,10,9,105,102,32,40,100,105,102,102,117,115,101,67,111,108,111,114,46,97,32,60,32,77,97,116,101,114,105,97,108,65,108,112,104,97,84,104,114,101,115,104,111,108,100,41,13,10,9,9,100,105,115,99,97,114,100,59,13,10,9,35,101,110,100,105,102,32,47,47,32,65,76,80,72,65,95,84,69,83,84,13,10,13,10,9,35,105,102,32,76,73,71,72,84,73,78,71,13,10,9,9,35,105,102,32,78,79,82,77,65,76,95,77,65,80,80,73,78,71,13,10,9,118,101,99,51,32,110,111,114,109,97,108,32,61,32,110,111,114,109,97,108,105,122,101,40,118,76,105,103,104,116,84,111,87,111,114,108,100,32,42,32,40,50,46,48,32,42,32,118,101,99,51,40,116,101,120,116,117,114,101,40,77,97,116,101,114,105,97,108,78,111,114,109,97,108,77,97,112,44,32,116,101,120,67,111,111,114,100,41,41,32,45,32,49,46,48,41,41,59,13,10,9,9,35,101,108,115,101,13,10,9,118,101,99,51,32,110,111,114,109,97,108,32,61,32,110,111,114,109,97,108,105,122,101,40,118,78,111,114,109,97,108,41,59,13,10,9,9,35,101,110,100,105,102,32,47,47,32,78,79,82,77,65,76,95,77,65,80,80,73,78,71,13,10,13,10,9,118,101,99,51,32,115,112,101,99,117,108,97,114,67,111,108,111,114,32,61,32,77,97,116,101,114,105,97,108,83,112,101,99,117,108,97,114,46,114,103,98,59,13,10,9,9,35,105,102,32,83,80,69,67,85,76,65,82,95,77,65,80,80,73,78,71,13,10,9,115,112,101,99,117,108,97,114,67,111,108,111,114,32,42,61,32,116,101,120,116,117,114,101,40,77,97,116,101,114,105,97,108,83,112,101,99,117,108,97,114,77,97,112,44,32,116,101,120,67,111,111,114,100,41,46,114,103,98,59,13,10,9,9,35,101,110,100,105,102,13,10,13,10,9,47,42,13,10,9,84,101,120,116,117,114,101,48,58,32,68,105,102,102,117,115,101,32,67,111,108,111,114,32,43,32,83,112,101,99,117,108,97,114,13,10,9,84,101,120,116,117,114,101,49,58,32,78,111,114,109,97,108,32,43,32,83,112,101,99,117,108,97,114,13,10,9,84,101,120,116,117,114,101,50,58,32,69,110,99,111,100,101,100,32,100,101,112,116,104,32,43,32,83,104,105,110,105,110,101,115,115,13,10,9,42,47,13,10,9,82,101,110,100,101,114,84,97,114,103,101,116,48,32,61,32,118,101,99,52,40,100,105,102,102,117,115,101,67,111,108,111,114,46,114,103,98,44,32,100,111,116,40,115,112,101,99,117,108,97,114,67,111,108,111,114,44,32,118,101,99,51,40,48,46,51,44,32,48,46,53,57,44,32,48,46,49,49,41,41,41,59,13,10,9,82,101,110,100,101,114,84,97,114,103,101,116,49,32,61,32,118,101,99,52,40,69,110,99,111,100,101,78,111,114,109,97,108,40,110,111,114,109,97,108,41,41,59,13,10,9,82,101,110,100,101,114,84,97,114,103,101,116,50,32,61,32,118,101,99,52,40,70,108,111,97,116,84,111,67,111,108,111,114,40,103,108,95,70,114,97,103,67,111,111,114,100,46,122,41,44,32,40,77,97,116,101,114,105,97,108,83,104,105,110,105,110,101,115,115,32,61,61,32,48,46,48,41,32,63,32,48,46,48,32,58,32,109,97,120,40,108,111,103,50,40,77,97,116,101,114,105,97,108,83,104,105,110,105,110,101,115,115,41,44,32,48,46,49,41,47,49,48,46,53,41,59,32,47,47,32,104,116,116,112,58,47,47,119,119,119,46,103,117,101,114,114,105,108,108,97,45,103,97,109,101,115,46,99,111,109,47,112,117,98,108,105,99,97,116,105,111,110,115,47,100,114,95,107,122,50,95,114,115,120,95,100,101,118,48,55,46,112,100,102,13,10,9,35,101,108,115,101,32,47,47,32,76,73,71,72,84,73,78,71,13,10,9,82,101,110,100,101,114,84,97,114,103,101,116,48,32,61,32,118,101,99,52,40,100,105,102,102,117,115,101,67,111,108,111,114,46,114,103,98,44,32,48,46,48,41,59,13,10,9,35,101,110,100,105,102,13,10,35,101,108,115,101,32,47,47,32,70,76,65,71,95,68,69,70,69,82,82,69,68,13,10,9,35,105,102,32,65,76,80,72,65,95,77,65,80,80,73,78,71,13,10,9,100,105,102,102,117,115,101,67,111,108,111,114,46,97,32,42,61,32,116,101,120,116,117,114,101,40,77,97,116,101,114,105,97,108,65,108,112,104,97,77,97,112,44,32,116,101,120,67,111,111,114,100,41,46,114,59,13,10,9,35,101,110,100,105,102,13,10,13,10,9,35,105,102,32,65,76,80,72,65,95,84,69,83,84,13,10,9,105,102,32,40,100,105,102,102,117,115,101,67,111,108,111,114,46,97,32,60,32,77,97,116,101,114,105,97,108,65,108,112,104,97,84,104,114,101,115,104,111,108,100,41,13,10,9,9,100,105,115,99,97,114,100,59,13,10,9,35,101,110,100,105,102,13,10,13,10,9,35,105,102,32,76,73,71,72,84,73,78,71,13,10,9,118,101,99,51,32,108,105,103,104,116,65,109,98,105,101,110,116,32,61,32,118,101,99,51,40,48,46,48,41,59,13,10,9,118,101,99,51,32,108,105,103,104,116,68,105,102,102,117,115,101,32,61,32,118,101,99,51,40,48,46,48,41,59,13,10,9,118,101,99,51,32,108,105,103,104,116,83,112,101,99,117,108,97,114,32,61,32,118,101,99,51,40,48,46,48,41,59,13,10,13,10,9,9,35,105,102,32,78,79,82,77,65,76,95,77,65,80,80,73,78,71,13,10,9,118,101,99,51,32,110,111,114,109,97,108,32,61,32,110,111,114,109,97,108,105,122,101,40,118,76,105,103,104,116,84,111,87,111,114,108,100,32,42,32,40,50,46,48,32,42,32,118,101,99,51,40,116,101,120,116,117,114,101,40,77,97,116,101,114,105,97,108,78,111,114,109,97,108,77,97,112,44,32,116,101,120,67,111,111,114,100,41,41,32,45,32,49,46,48,41,41,59,13,10,9,9,35,101,108,115,101,13,10,9,118,101,99,51,32,110,111,114,109,97,108,32,61,32,110,111,114,109,97,108,105,122,101,40,118,78,111,114,109,97,108,41,59,13,10,9,9,35,101,110,100,105,102,13,10,13,10,9,105,102,32,40,77,97,116,101,114,105,97,108,83,104,105,110,105,110,101,115,115,32,62,32,48,46,48,41,13,10,9,123,13,10,9,9,118,101,99,51,32,101,121,101,86,101,99,32,61,32,110,111,114,109,97,108,105,122,101,40,69,121,101,80,111,115,105,116,105,111,110,32,45,32,118,87,111,114,108,100,80,111,115,41,59,13,10,13,10,9,9,102,111,114,32,40,105,110,116,32,105,32,61,32,48,59,32,105,32,60,32,51,59,32,43,43,105,41,13,10,9,9,123,13,10,9,9,9,118,101,99,52,32,108,105,103,104,116,67,111,108,111,114,32,61,32,76,105,103,104,116,115,91,105,93,46,99,111,108,111,114,59,13,10,9,9,9,102,108,111,97,116,32,108,105,103,104,116,65,109,98,105,101,110,116,70,97,99,116,111,114,32,61,32,76,105,103,104,116,115,91,105,93,46,102,97,99,116,111,114,115,46,120,59,13,10,9,9,9,102,108,111,97,116,32,108,105,103,104,116,68,105,102,102,117,115,101,70,97,99,116,111,114,32,61,32,76,105,103,104,116,115,91,105,93,46,102,97,99,116,111,114,115,46,121,59,13,10,13,10,9,9,9,115,119,105,116,99,104,32,40,76,105,103,104,116,115,91,105,93,46,116,121,112,101,41,13,10,9,9,9,123,13,10,9,9,9,9,99,97,115,101,32,76,73,71,72,84,95,68,73,82,69,67,84,73,79,78,65,76,58,13,10,9,9,9,9,123,13,10,9,9,9,9,9,118,101,99,51,32,108,105,103,104,116,68,105,114,32,61,32,45,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,49,46,120,121,122,59,13,10,13,10,9,9,9,9,9,47,47,32,65,109,98,105,101,110,116,13,10,9,9,9,9,9,108,105,103,104,116,65,109,98,105,101,110,116,32,43,61,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,32,42,32,108,105,103,104,116,65,109,98,105,101,110,116,70,97,99,116,111,114,32,42,32,40,77,97,116,101,114,105,97,108,65,109,98,105,101,110,116,46,114,103,98,32,43,32,83,99,101,110,101,65,109,98,105,101,110,116,46,114,103,98,41,59,13,10,13,10,9,9,9,9,9,35,105,102,32,83,72,65,68,79,87,95,77,65,80,80,73,78,71,13,10,9,9,9,9,9,105,102,32,40,76,105,103,104,116,115,91,105,93,46,115,104,97,100,111,119,77,97,112,112,105,110,103,32,38,38,32,33,84,101,115,116,83,104,97,100,111,119,68,105,114,101,99,116,105,111,110,97,108,40,105,41,41,13,10,9,9,9,9,9,9,98,114,101,97,107,59,13,10,9,9,9,9,9,35,101,110,100,105,102,13,10,13,10,9,9,9,9,9,47,47,32,68,105,102,102,117,115,101,13,10,9,9,9,9,9,102,108,111,97,116,32,108,97,109,98,101,114,116,32,61,32,109,97,120,40,100,111,116,40,110,111,114,109,97,108,44,32,108,105,103,104,116,68,105,114,41,44,32,48,46,48,41,59,13,10,13,10,9,9,9,9,9,108,105,103,104,116,68,105,102,102,117,115,101,32,43,61,32,108,97,109,98,101,114,116,32,42,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,32,42,32,108,105,103,104,116,68,105,102,102,117,115,101,70,97,99,116,111,114,59,13,10,13,10,9,9,9,9,9,47,47,32,83,112,101,99,117,108,97,114,13,10,9,9,9,9,9,118,101,99,51,32,114,101,102,108,101,99,116,105,111,110,32,61,32,114,101,102,108,101,99,116,40,45,108,105,103,104,116,68,105,114,44,32,110,111,114,109,97,108,41,59,13,10,9,9,9,9,9,102,108,111,97,116,32,115,112,101,99,117,108,97,114,70,97,99,116,111,114,32,61,32,109,97,120,40,100,111,116,40,114,101,102,108,101,99,116,105,111,110,44,32,101,121,101,86,101,99,41,44,32,48,46,48,41,59,13,10,9,9,9,9,9,115,112,101,99,117,108,97,114,70,97,99,116,111,114,32,61,32,112,111,119,40,115,112,101,99,117,108,97,114,70,97,99,116,111,114,44,32,77,97,116,101,114,105,97,108,83,104,105,110,105,110,101,115,115,41,59,13,10,13,10,9,9,9,9,9,108,105,103,104,116,83,112,101,99,117,108,97,114,32,43,61,32,115,112,101,99,117,108,97,114,70,97,99,116,111,114,32,42,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,59,13,10,9,9,9,9,9,98,114,101,97,107,59,13,10,9,9,9,9,125,13,10,13,10,9,9,9,9,99,97,115,101,32,76,73,71,72,84,95,80,79,73,78,84,58,13,10,9,9,9,9,123,13,10,9,9,9,9,9,118,101,99,51,32,108,105,103,104,116,80,111,115,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,49,46,120,121,122,59,13,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,65,116,116,101,110,117,97,116,105,111,110,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,49,46,119,59,13,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,73,110,118,82,97,100,105,117,115,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,50,46,119,59,13,10,9,9,9,9,9,13,10,9,9,9,9,9,118,101,99,51,32,119,111,114,108,100,84,111,76,105,103,104,116,32,61,32,108,105,103,104,116,80,111,115,32,45,32,118,87,111,114,108,100,80,111,115,59,13,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,68,105,114,76,101,110,103,116,104,32,61,32,108,101,110,103,116,104,40,119,111,114,108,100,84,111,76,105,103,104,116,41,59,13,10,9,9,9,9,9,118,101,99,51,32,108,105,103,104,116,68,105,114,32,61,32,119,111,114,108,100,84,111,76,105,103,104,116,32,47,32,108,105,103,104,116,68,105,114,76,101,110,103,116,104,59,32,47,47,32,78,111,114,109,97,108,105,115,97,116,105,111,110,13,10,9,9,9,9,9,13,10,9,9,9,9,9,102,108,111,97,116,32,97,116,116,32,61,32,109,97,120,40,108,105,103,104,116,65,116,116,101,110,117,97,116,105,111,110,32,45,32,108,105,103,104,116,73,110,118,82,97,100,105,117,115,32,42,32,108,105,103,104,116,68,105,114,76,101,110,103,116,104,44,32,48,46,48,41,59,13,10,13,10,9,9,9,9,9,47,47,32,65,109,98,105,101,110,116,13,10,9,9,9,9,9,108,105,103,104,116,65,109,98,105,101,110,116,32,43,61,32,97,116,116,32,42,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,32,42,32,108,105,103,104,116,65,109,98,105,101,110,116,70,97,99,116,111,114,32,42,32,40,77,97,116,101,114,105,97,108,65,109,98,105,101,110,116,46,114,103,98,32,43,32,83,99,101,110,101,65,109,98,105,101,110,116,46,114,103,98,41,59,13,10,13,10,9,9,9,9,9,35,105,102,32,83,72,65,68,79,87,95,77,65,80,80,73,78,71,13,10,9,9,9,9,9,105,102,32,40,76,105,103,104,116,115,91,105,93,46,115,104,97,100,111,119,77,97,112,112,105,110,103,32,38,38,32,33,84,101,115,116,83,104,97,100,111,119,80,111,105,110,116,40,105,44,32,118,87,111,114,108,100,80,111,115,32,45,32,108,105,103,104,116,80,111,115,44,32,48,46,49,44,32,53,48,46,48,41,41,13,10,9,9,9,9,9,9,98,114,101,97,107,59,13,10,9,9,9,9,9,35,101,110,100,105,102,13,10,13,10,9,9,9,9,9,47,47,32,68,105,102,102,117,115,101,13,10,9,9,9,9,9,102,108,111,97,116,32,108,97,109,98,101,114,116,32,61,32,109,97,120,40,100,111,116,40,110,111,114,109,97,108,44,32,108,105,103,104,116,68,105,114,41,44,32,48,46,48,41,59,13,10,9,9,9,9,9,13,10,9,9,9,9,9,108,105,103,104,116,68,105,102,102,117,115,101,32,43,61,32,97,116,116,32,42,32,108,97,109,98,101,114,116,32,42,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,32,42,32,108,105,103,104,116,68,105,102,102,117,115,101,70,97,99,116,111,114,59,13,10,13,10,9,9,9,9,9,47,47,32,83,112,101,99,117,108,97,114,13,10,9,9,9,9,9,118,101,99,51,32,114,101,102,108,101,99,116,105,111,110,32,61,32,114,101,102,108,101,99,116,40,45,108,105,103,104,116,68,105,114,44,32,110,111,114,109,97,108,41,59,13,10,9,9,9,9,9,102,108,111,97,116,32,115,112,101,99,117,108,97,114,70,97,99,116,111,114,32,61,32,109,97,120,40,100,111,116,40,114,101,102,108,101,99,116,105,111,110,44,32,101,121,101,86,101,99,41,44,32,48,46,48,41,59,13,10,9,9,9,9,9,115,112,101,99,117,108,97,114,70,97,99,116,111,114,32,61,32,112,111,119,40,115,112,101,99,117,108,97,114,70,97,99,116,111,114,44,32,77,97,116,101,114,105,97,108,83,104,105,110,105,110,101,115,115,41,59,13,10,13,10,9,9,9,9,9,108,105,103,104,116,83,112,101,99,117,108,97,114,32,43,61,32,97,116,116,32,42,32,115,112,101,99,117,108,97,114,70,97,99,116,111,114,32,42,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,59,13,10,9,9,9,9,9,98,114,101,97,107,59,13,10,9,9,9,9,125,13,10,13,10,9,9,9,9,99,97,115,101,32,76,73,71,72,84,95,83,80,79,84,58,13,10,9,9,9,9,123,13,10,9,9,9,9,9,118,101,99,51,32,108,105,103,104,116,80,111,115,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,49,46,120,121,122,59,13,10,9,9,9,9,9,118,101,99,51,32,108,105,103,104,116,68,105,114,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,50,46,120,121,122,59,13,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,65,116,116,101,110,117,97,116,105,111,110,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,49,46,119,59,13,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,73,110,118,82,97,100,105,117,115,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,50,46,119,59,13,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,73,110,110,101,114,65,110,103,108,101,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,51,46,120,59,13,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,79,117,116,101,114,65,110,103,108,101,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,51,46,121,59,13,10,13,10,9,9,9,9,9,118,101,99,51,32,119,111,114,108,100,84,111,76,105,103,104,116,32,61,32,108,105,103,104,116,80,111,115,32,45,32,118,87,111,114,108,100,80,111,115,59,13,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,68,105,115,116,97,110,99,101,32,61,32,108,101,110,103,116,104,40,119,111,114,108,100,84,111,76,105,103,104,116,41,59,13,10,9,9,9,9,9,119,111,114,108,100,84,111,76,105,103,104,116,32,47,61,32,108,105,103,104,116,68,105,115,116,97,110,99,101,59,32,47,47,32,78,111,114,109,97,108,105,115,97,116,105,111,110,13,10,9,9,9,9,9,13,10,9,9,9,9,9,102,108,111,97,116,32,97,116,116,32,61,32,109,97,120,40,108,105,103,104,116,65,116,116,101,110,117,97,116,105,111,110,32,45,32,108,105,103,104,116,73,110,118,82,97,100,105,117,115,32,42,32,108,105,103,104,116,68,105,115,116,97,110,99,101,44,32,48,46,48,41,59,13,10,13,10,9,9,9,9,9,47,47,32,65,109,98,105,101,110,116,13,10,9,9,9,9,9,108,105,103,104,116,65,109,98,105,101,110,116,32,43,61,32,97,116,116,32,42,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,32,42,32,108,105,103,104,116,65,109,98,105,101,110,116,70,97,99,116,111,114,32,42,32,40,77,97,116,101,114,105,97,108,65,109,98,105,101,110,116,46,114,103,98,32,43,32,83,99,101,110,101,65,109,98,105,101,110,116,46,114,103,98,41,59,13,10,13,10,9,9,9,9,9,35,105,102,32,83,72,65,68,79,87,95,77,65,80,80,73,78,71,13,10,9,9,9,9,9,105,102,32,40,76,105,103,104,116,115,91,105,93,46,115,104,97,100,111,119,77,97,112,112,105,110,103,32,38,38,32,33,84,101,115,116,83,104,97,100,111,119,83,112,111,116,40,105,41,41,13,10,9,9,9,9,9,9,98,114,101,97,107,59,13,10,9,9,9,9,9,35,101,110,100,105,102,13,10,13,10,9,9,9,9,9,47,47,32,77,111,100,105,102,105,99,97,116,105,111,110,32,100,101,32,108,39,97,116,116,195,169,110,117,97,116,105,111,110,32,112,111,117,114,32,103,195,169,114,101,114,32,108,101,32,115,112,111,116,13,10,9,9,9,9,9,102,108,111,97,116,32,99,117,114,65,110,103,108,101,32,61,32,100,111,116,40,108,105,103,104,116,68,105,114,44,32,45,119,111,114,108,100,84,111,76,105,103,104,116,41,59,13,10,9,9,9,9,9,102,108,111,97,116,32,105,110,110,101,114,77,105,110,117,115,79,117,116,101,114,65,110,103,108,101,32,61,32,108,105,103,104,116,73,110,110,101,114,65,110,103,108,101,32,45,32,108,105,103,104,116,79,117,116,101,114,65,110,103,108,101,59,13,10,9,9,9,9,9,97,116,116,32,42,61,32,109,97,120,40,40,99,117,114,65,110,103,108,101,32,45,32,108,105,103,104,116,79,117,116,101,114,65,110,103,108,101,41,32,47,32,105,110,110,101,114,77,105,110,117,115,79,117,116,101,114,65,110,103,108,101,44,32,48,46,48,41,59,13,10,13,10,9,9,9,9,9,47,47,32,68,105,102,102,117,115,101,13,10,9,9,9,9,9,102,108,111,97,116,32,108,97,109,98,101,114,116,32,61,32,109,97,120,40,100,111,116,40,110,111,114,109,97,108,44,32,119,111,114,108,100,84,111,76,105,103,104,116,41,44,32,48,46,48,41,59,13,10,13,10,9,9,9,9,9,108,105,103,104,116,68,105,102,102,117,115,101,32,43,61,32,97,116,116,32,42,32,108,97,109,98,101,114,116,32,42,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,32,42,32,108,105,103,104,116,68,105,102,102,117,115,101,70,97,99,116,111,114,59,13,10,13,10,9,9,9,9,9,47,47,32,83,112,101,99,117,108,97,114,13,10,9,9,9,9,9,118,101,99,51,32,114,101,102,108,101,99,116,105,111,110,32,61,32,114,101,102,108,101,99,116,40,45,119,111,114,108,100,84,111,76,105,103,104,116,44,32,110,111,114,109,97,108,41,59,13,10,9,9,9,9,9,102,108,111,97,116,32,115,112,101,99,117,108,97,114,70,97,99,116,111,114,32,61,32,109,97,120,40,100,111,116,40,114,101,102,108,101,99,116,105,111,110,44,32,101,121,101,86,101,99,41,44,32,48,46,48,41,59,13,10,9,9,9,9,9,115,112,101,99,117,108,97,114,70,97,99,116,111,114,32,61,32,112,111,119,40,115,112,101,99,117,108,97,114,70,97,99,116,111,114,44,32,77,97,116,101,114,105,97,108,83,104,105,110,105,110,101,115,115,41,59,13,10,13,10,9,9,9,9,9,108,105,103,104,116,83,112,101,99,117,108,97,114,32,43,61,32,97,116,116,32,42,32,115,112,101,99,117,108,97,114,70,97,99,116,111,114,32,42,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,59,13,10,9,9,9,9,9,98,114,101,97,107,59,13,10,9,9,9,9,125,13,10,9,9,9,9,13,10,9,9,9,9,100,101,102,97,117,108,116,58,13,10,9,9,9,9,9,98,114,101,97,107,59,13,10,9,9,9,125,13,10,9,9,125,13,10,9,125,13,10,9,101,108,115,101,13,10,9,123,13,10,9,9,102,111,114,32,40,105,110,116,32,105,32,61,32,48,59,32,105,32,60,32,51,59,32,43,43,105,41,13,10,9,9,123,13,10,9,9,9,118,101,99,52,32,108,105,103,104,116,67,111,108,111,114,32,61,32,76,105,103,104,116,115,91,105,93,46,99,111,108,111,114,59,13,10,9,9,9,102,108,111,97,116,32,108,105,103,104,116,65,109,98,105,101,110,116,70,97,99,116,111,114,32,61,32,76,105,103,104,116,115,91,105,93,46,102,97,99,116,111,114,115,46,120,59,13,10,9,9,9,102,108,111,97,116,32,108,105,103,104,116,68,105,102,102,117,115,101,70,97,99,116,111,114,32,61,32,76,105,103,104,116,115,91,105,93,46,102,97,99,116,111,114,115,46,121,59,13,10,13,10,9,9,9,115,119,105,116,99,104,32,40,76,105,103,104,116,115,91,105,93,46,116,121,112,101,41,13,10,9,9,9,123,13,10,9,9,9,9,99,97,115,101,32,76,73,71,72,84,95,68,73,82,69,67,84,73,79,78,65,76,58,13,10,9,9,9,9,123,13,10,9,9,9,9,9,118,101,99,51,32,108,105,103,104,116,68,105,114,32,61,32,45,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,49,46,120,121,122,59,13,10,13,10,9,9,9,9,9,47,47,32,65,109,98,105,101,110,116,13,10,9,9,9,9,9,108,105,103,104,116,65,109,98,105,101,110,116,32,43,61,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,32,42,32,108,105,103,104,116,65,109,98,105,101,110,116,70,97,99,116,111,114,32,42,32,40,77,97,116,101,114,105,97,108,65,109,98,105,101,110,116,46,114,103,98,32,43,32,83,99,101,110,101,65,109,98,105,101,110,116,46,114,103,98,41,59,13,10,13,10,9,9,9,9,9,47,47,32,68,105,102,102,117,115,101,13,10,9,9,9,9,9,102,108,111,97,116,32,108,97,109,98,101,114,116,32,61,32,109,97,120,40,100,111,116,40,110,111,114,109,97,108,44,32,108,105,103,104,116,68,105,114,41,44,32,48,46,48,41,59,13,10,13,10,9,9,9,9,9,108,105,103,104,116,68,105,102,102,117,115,101,32,43,61,32,108,97,109,98,101,114,116,32,42,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,32,42,32,108,105,103,104,116,68,105,102,102,117,115,101,70,97,99,116,111,114,59,13,10,9,9,9,9,9,98,114,101,97,107,59,13,10,9,9,9,9,125,13,10,13,10,9,9,9,9,99,97,115,101,32,76,73,71,72,84,95,80,79,73,78,84,58,13,10,9,9,9,9,123,13,10,9,9,9,9,9,118,101,99,51,32,108,105,103,104,116,80,111,115,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,49,46,120,121,122,59,13,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,65,116,116,101,110,117,97,116,105,111,110,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,49,46,119,59,13,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,73,110,118,82,97,100,105,117,115,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,50,46,119,59,13,10,9,9,9,9,9,13,10,9,9,9,9,9,118,101,99,51,32,119,111,114,108,100,84,111,76,105,103,104,116,32,61,32,108,105,103,104,116,80,111,115,32,45,32,118,87,111,114,108,100,80,111,115,59,13,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,68,105,114,76,101,110,103,116,104,32,61,32,108,101,110,103,116,104,40,119,111,114,108,100,84,111,76,105,103,104,116,41,59,13,10,9,9,9,9,9,118,101,99,51,32,108,105,103,104,116,68,105,114,32,61,32,119,111,114,108,100,84,111,76,105,103,104,116,32,47,32,108,105,103,104,116,68,105,114,76,101,110,103,116,104,59,32,47,47,32,78,111,114,109,97,108,105,115,97,116,105,111,110,13,10,9,9,9,9,9,13,10,9,9,9,9,9,102,108,111,97,116,32,97,116,116,32,61,32,109,97,120,40,108,105,103,104,116,65,116,116,101,110,117,97,116,105,111,110,32,45,32,108,105,103,104,116,73,110,118,82,97,100,105,117,115,32,42,32,108,105,103,104,116,68,105,114,76,101,110,103,116,104,44,32,48,46,48,41,59,13,10,13,10,9,9,9,9,9,47,47,32,65,109,98,105,101,110,116,13,10,9,9,9,9,9,108,105,103,104,116,65,109,98,105,101,110,116,32,43,61,32,97,116,116,32,42,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,32,42,32,108,105,103,104,116,65,109,98,105,101,110,116,70,97,99,116,111,114,32,42,32,40,77,97,116,101,114,105,97,108,65,109,98,105,101,110,116,46,114,103,98,32,43,32,83,99,101,110,101,65,109,98,105,101,110,116,46,114,103,98,41,59,13,10,13,10,9,9,9,9,9,35,105,102,32,83,72,65,68,79,87,95,77,65,80,80,73,78,71,13,10,9,9,9,9,9,105,102,32,40,76,105,103,104,116,115,91,105,93,46,115,104,97,100,111,119,77,97,112,112,105,110,103,32,38,38,32,33,84,101,115,116,83,104,97,100,111,119,80,111,105,110,116,40,105,44,32,118,87,111,114,108,100,80,111,115,32,45,32,108,105,103,104,116,80,111,115,44,32,48,46,49,44,32,49,46,48,32,47,32,108,105,103,104,116,73,110,118,82,97,100,105,117,115,41,41,13,10,9,9,9,9,9,9,98,114,101,97,107,59,13,10,9,9,9,9,9,35,101,110,100,105,102,13,10,13,10,9,9,9,9,9,47,47,32,68,105,102,102,117,115,101,13,10,9,9,9,9,9,102,108,111,97,116,32,108,97,109,98,101,114,116,32,61,32,109,97,120,40,100,111,116,40,110,111,114,109,97,108,44,32,108,105,103,104,116,68,105,114,41,44,32,48,46,48,41,59,13,10,9,9,9,9,9,13,10,9,9,9,9,9,108,105,103,104,116,68,105,102,102,117,115,101,32,43,61,32,97,116,116,32,42,32,108,97,109,98,101,114,116,32,42,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,32,42,32,108,105,103,104,116,68,105,102,102,117,115,101,70,97,99,116,111,114,59,13,10,9,9,9,9,9,98,114,101,97,107,59,13,10,9,9,9,9,125,13,10,13,10,9,9,9,9,99,97,115,101,32,76,73,71,72,84,95,83,80,79,84,58,13,10,9,9,9,9,123,13,10,9,9,9,9,9,118,101,99,51,32,108,105,103,104,116,80,111,115,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,49,46,120,121,122,59,13,10,9,9,9,9,9,118,101,99,51,32,108,105,103,104,116,68,105,114,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,50,46,120,121,122,59,13,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,65,116,116,101,110,117,97,116,105,111,110,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,49,46,119,59,13,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,73,110,118,82,97,100,105,117,115,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,50,46,119,59,13,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,73,110,110,101,114,65,110,103,108,101,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,51,46,120,59,13,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,79,117,116,101,114,65,110,103,108,101,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,51,46,121,59,13,10,13,10,9,9,9,9,9,118,101,99,51,32,119,111,114,108,100,84,111,76,105,103,104,116,32,61,32,108,105,103,104,116,80,111,115,32,45,32,118,87,111,114,108,100,80,111,115,59,13,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,68,105,115,116,97,110,99,101,32,61,32,108,101,110,103,116,104,40,119,111,114,108,100,84,111,76,105,103,104,116,41,59,13,10,9,9,9,9,9,119,111,114,108,100,84,111,76,105,103,104,116,32,47,61,32,108,105,103,104,116,68,105,115,116,97,110,99,101,59,32,47,47,32,78,111,114,109,97,108,105,115,97,116,105,111,110,13,10,9,9,9,9,9,13,10,9,9,9,9,9,102,108,111,97,116,32,97,116,116,32,61,32,109,97,120,40,108,105,103,104,116,65,116,116,101,110,117,97,116,105,111,110,32,45,32,108,105,103,104,116,73,110,118,82,97,100,105,117,115,32,42,32,108,105,103,104,116,68,105,115,116,97,110,99,101,44,32,48,46,48,41,59,13,10,13,10,9,9,9,9,9,47,47,32,65,109,98,105,101,110,116,13,10,9,9,9,9,9,108,105,103,104,116,65,109,98,105,101,110,116,32,43,61,32,97,116,116,32,42,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,32,42,32,108,105,103,104,116,65,109,98,105,101,110,116,70,97,99,116,111,114,32,42,32,40,77,97,116,101,114,105,97,108,65,109,98,105,101,110,116,46,114,103,98,32,43,32,83,99,101,110,101,65,109,98,105,101,110,116,46,114,103,98,41,59,13,10,13,10,9,9,9,9,9,35,105,102,32,83,72,65,68,79,87,95,77,65,80,80,73,78,71,13,10,9,9,9,9,9,105,102,32,40,76,105,103,104,116,115,91,105,93,46,115,104,97,100,111,119,77,97,112,112,105,110,103,32,38,38,32,33,84,101,115,116,83,104,97,100,111,119,83,112,111,116,40,105,41,41,13,10,9,9,9,9,9,9,98,114,101,97,107,59,13,10,9,9,9,9,9,35,101,110,100,105,102,13,10,13,10,9,9,9,9,9,47,47,32,77,111,100,105,102,105,99,97,116,105,111,110,32,100,101,32,108,39,97,116,116,195,169,110,117,97,116,105,111,110,32,112,111,117,114,32,103,195,169,114,101,114,32,108,101,32,115,112,111,116,13,10,9,9,9,9,9,102,108,111,97,116,32,99,117,114,65,110,103,108,101,32,61,32,100,111,116,40,108,105,103,104,116,68,105,114,44,32,45,119,111,114,108,100,84,111,76,105,103,104,116,41,59,13,10,9,9,9,9,9,102,108,111,97,116,32,105,110,110,101,114,77,105,110,117,115,79,117,116,101,114,65,110,103,108,101,32,61,32,108,105,103,104,116,73,110,110,101,114,65,110,103,108,101,32,45,32,108,105,103,104,116,79,117,116,101,114,65,110,103,108,101,59,13,10,9,9,9,9,9,97,116,116,32,42,61,32,109,97,120,40,40,99,117,114,65,110,103,108,101,32,45,32,108,105,103,104,116,79,117,116,101,114,65,110,103,108,101,41,32,47,32,105,110,110,101,114,77,105,110,117,115,79,117,116,101,114,65,110,103,108,101,44,32,48,46,48,41,59,13,10,13,10,9,9,9,9,9,47,47,32,68,105,102,102,117,115,101,13,10,9,9,9,9,9,102,108,111,97,116,32,108,97,109,98,101,114,116,32,61,32,109,97,120,40,100,111,116,40,110,111,114,109,97,108,44,32,119,111,114,108,100,84,111,76,105,103,104,116,41,44,32,48,46,48,41,59,13,10,13,10,9,9,9,9,9,108,105,103,104,116,68,105,102,102,117,115,101,32,43,61,32,97,116,116,32,42,32,108,97,109,98,101,114,116,32,42,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,32,42,32,108,105,103,104,116,68,105,102,102,117,115,101,70,97,99,116,111,114,59,13,10,9,9,9,9,125,13,10,9,9,9,9,13,10,9,9,9,9,100,101,102,97,117,108,116,58,13,10,9,9,9,9,9,98,114,101,97,107,59,13,10,9,9,9,125,13,10,9,9,125,13,10,9,125,13,10,9,13,10,9,108,105,103,104,116,83,112,101,99,117,108,97,114,32,42,61,32,77,97,116,101,114,105,97,108,83,112,101,99,117,108,97,114,46,114,103,98,59,13,10,9,9,35,105,102,32,83,80,69,67,85,76,65,82,95,77,65,80,80,73,78,71,13,10,9,108,105,103,104,116,83,112,101,99,117,108,97,114,32,42,61,32,116,101,120,116,117,114,101,40,77,97,116,101,114,105,97,108,83,112,101,99,117,108,97,114,77,97,112,44,32,116,101,120,67,111,111,114,100,41,46,114,103,98,59,32,47,47,32,85,116,105,108,105,115,101,114,32,108,39,97,108,112,104,97,32,100,101,32,77,97,116,101,114,105,97,108,83,112,101,99,117,108,97,114,32,110,39,97,117,114,97,105,116,32,97,117,99,117,110,32,115,101,110,115,13,10,9,9,35,101,110,100,105,102,13,10,9,9,13,10,9,118,101,99,51,32,108,105,103,104,116,67,111,108,111,114,32,61,32,40,108,105,103,104,116,65,109,98,105,101,110,116,32,43,32,108,105,103,104,116,68,105,102,102,117,115,101,32,43,32,108,105,103,104,116,83,112,101,99,117,108,97,114,41,59,13,10,9,118,101,99,52,32,102,114,97,103,109,101,110,116,67,111,108,111,114,32,61,32,118,101,99,52,40,108,105,103,104,116,67,111,108,111,114,44,32,49,46,48,41,32,42,32,100,105,102,102,117,115,101,67,111,108,111,114,59,13,10,13,10,9,9,35,105,102,32,69,77,73,83,83,73,86,69,95,77,65,80,80,73,78,71,13,10,9,102,108,111,97,116,32,108,105,103,104,116,73,110,116,101,110,115,105,116,121,32,61,32,100,111,116,40,108,105,103,104,116,67,111,108,111,114,44,32,118,101,99,51,40,48,46,51,44,32,48,46,53,57,44,32,48,46,49,49,41,41,59,13,10,13,10,9,118,101,99,51,32,101,109,105,115,115,105,111,110,67,111,108,111,114,32,61,32,77,97,116,101,114,105,97,108,68,105,102,102,117,115,101,46,114,103,98,32,42,32,116,101,120,116,117,114,101,40,77,97,116,101,114,105,97,108,69,109,105,115,115,105,118,101,77,97,112,44,32,116,101,120,67,111,111,114,100,41,46,114,103,98,59,13,10,9,82,101,110,100,101,114,84,97,114,103,101,116,48,32,61,32,118,101,99,52,40,109,105,120,40,102,114,97,103,109,101,110,116,67,111,108,111,114,46,114,103,98,44,32,101,109,105,115,115,105,111,110,67,111,108,111,114,44,32,99,108,97,109,112,40,49,46,48,32,45,32,51,46,48,42,108,105,103,104,116,73,110,116,101,110,115,105,116,121,44,32,48,46,48,44,32,49,46,48,41,41,44,32,102,114,97,103,109,101,110,116,67,111,108,111,114,46,97,41,59,13,10,9,9,35,101,108,115,101,13,10,9,82,101,110,100,101,114,84,97,114,103,101,116,48,32,61,32,102,114,97,103,109,101,110,116,67,111,108,111,114,59,13,10,9,9,35,101,110,100,105,102,32,47,47,32,69,77,73,83,83,73,86,69,95,77,65,80,80,73,78,71,13,10,9,35,101,108,115,101,13,10,9,82,101,110,100,101,114,84,97,114,103,101,116,48,32,61,32,100,105,102,102,117,115,101,67,111,108,111,114,59,13,10,9,35,101,110,100,105,102,32,47,47,32,76,73,71,72,84,73,78,71,13,10,35,101,110,100,105,102,32,47,47,32,70,76,65,71,95,68,69,70,69,82,82,69,68,13,10,125,13,10,13,10, \ No newline at end of file +35,105,102,32,69,65,82,76,89,95,70,82,65,71,77,69,78,84,95,84,69,83,84,83,32,38,38,32,33,65,76,80,72,65,95,84,69,83,84,10,108,97,121,111,117,116,40,101,97,114,108,121,95,102,114,97,103,109,101,110,116,95,116,101,115,116,115,41,32,105,110,59,10,35,101,110,100,105,102,10,10,35,100,101,102,105,110,101,32,76,73,71,72,84,95,68,73,82,69,67,84,73,79,78,65,76,32,48,10,35,100,101,102,105,110,101,32,76,73,71,72,84,95,80,79,73,78,84,32,49,10,35,100,101,102,105,110,101,32,76,73,71,72,84,95,83,80,79,84,32,50,10,10,47,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,69,110,116,114,97,110,116,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,47,10,105,110,32,118,101,99,52,32,118,67,111,108,111,114,59,10,105,110,32,118,101,99,52,32,118,76,105,103,104,116,83,112,97,99,101,80,111,115,91,51,93,59,10,105,110,32,109,97,116,51,32,118,76,105,103,104,116,84,111,87,111,114,108,100,59,10,105,110,32,118,101,99,51,32,118,78,111,114,109,97,108,59,10,105,110,32,118,101,99,50,32,118,84,101,120,67,111,111,114,100,59,10,105,110,32,118,101,99,51,32,118,86,105,101,119,68,105,114,59,10,105,110,32,118,101,99,51,32,118,87,111,114,108,100,80,111,115,59,10,10,47,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,83,111,114,116,97,110,116,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,47,10,111,117,116,32,118,101,99,52,32,82,101,110,100,101,114,84,97,114,103,101,116,48,59,10,111,117,116,32,118,101,99,52,32,82,101,110,100,101,114,84,97,114,103,101,116,49,59,10,111,117,116,32,118,101,99,52,32,82,101,110,100,101,114,84,97,114,103,101,116,50,59,10,10,47,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,85,110,105,102,111,114,109,101,115,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,47,10,115,116,114,117,99,116,32,76,105,103,104,116,10,123,10,9,105,110,116,32,116,121,112,101,59,10,9,118,101,99,52,32,99,111,108,111,114,59,10,9,118,101,99,50,32,102,97,99,116,111,114,115,59,10,10,9,118,101,99,52,32,112,97,114,97,109,101,116,101,114,115,49,59,10,9,118,101,99,52,32,112,97,114,97,109,101,116,101,114,115,50,59,10,9,118,101,99,50,32,112,97,114,97,109,101,116,101,114,115,51,59,10,9,98,111,111,108,32,115,104,97,100,111,119,77,97,112,112,105,110,103,59,10,125,59,10,10,47,47,32,76,117,109,105,195,168,114,101,115,10,117,110,105,102,111,114,109,32,76,105,103,104,116,32,76,105,103,104,116,115,91,51,93,59,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,67,117,98,101,32,80,111,105,110,116,76,105,103,104,116,83,104,97,100,111,119,77,97,112,91,51,93,59,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,83,104,97,100,111,119,32,68,105,114,101,99,116,105,111,110,97,108,83,112,111,116,76,105,103,104,116,83,104,97,100,111,119,77,97,112,91,51,93,59,10,10,47,47,32,77,97,116,195,169,114,105,97,117,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,77,97,116,101,114,105,97,108,65,108,112,104,97,77,97,112,59,10,117,110,105,102,111,114,109,32,102,108,111,97,116,32,77,97,116,101,114,105,97,108,65,108,112,104,97,84,104,114,101,115,104,111,108,100,59,10,117,110,105,102,111,114,109,32,118,101,99,52,32,77,97,116,101,114,105,97,108,65,109,98,105,101,110,116,59,10,117,110,105,102,111,114,109,32,118,101,99,52,32,77,97,116,101,114,105,97,108,68,105,102,102,117,115,101,59,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,77,97,116,101,114,105,97,108,68,105,102,102,117,115,101,77,97,112,59,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,77,97,116,101,114,105,97,108,69,109,105,115,115,105,118,101,77,97,112,59,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,77,97,116,101,114,105,97,108,72,101,105,103,104,116,77,97,112,59,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,77,97,116,101,114,105,97,108,78,111,114,109,97,108,77,97,112,59,10,117,110,105,102,111,114,109,32,102,108,111,97,116,32,77,97,116,101,114,105,97,108,83,104,105,110,105,110,101,115,115,59,10,117,110,105,102,111,114,109,32,118,101,99,52,32,77,97,116,101,114,105,97,108,83,112,101,99,117,108,97,114,59,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,77,97,116,101,114,105,97,108,83,112,101,99,117,108,97,114,77,97,112,59,10,10,47,47,32,65,117,116,114,101,115,10,117,110,105,102,111,114,109,32,102,108,111,97,116,32,80,97,114,97,108,108,97,120,66,105,97,115,32,61,32,45,48,46,48,51,59,10,117,110,105,102,111,114,109,32,102,108,111,97,116,32,80,97,114,97,108,108,97,120,83,99,97,108,101,32,61,32,48,46,48,50,59,10,117,110,105,102,111,114,109,32,118,101,99,50,32,73,110,118,84,97,114,103,101,116,83,105,122,101,59,10,117,110,105,102,111,114,109,32,118,101,99,51,32,69,121,101,80,111,115,105,116,105,111,110,59,10,117,110,105,102,111,114,109,32,118,101,99,52,32,83,99,101,110,101,65,109,98,105,101,110,116,59,10,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,84,101,120,116,117,114,101,79,118,101,114,108,97,121,59,10,10,47,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,70,111,110,99,116,105,111,110,115,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,47,10,118,101,99,51,32,70,108,111,97,116,84,111,67,111,108,111,114,40,102,108,111,97,116,32,102,41,10,123,10,9,118,101,99,51,32,99,111,108,111,114,59,10,10,9,102,32,42,61,32,50,53,54,46,48,59,10,9,99,111,108,111,114,46,120,32,61,32,102,108,111,111,114,40,102,41,59,10,10,9,102,32,61,32,40,102,32,45,32,99,111,108,111,114,46,120,41,32,42,32,50,53,54,46,48,59,10,9,99,111,108,111,114,46,121,32,61,32,102,108,111,111,114,40,102,41,59,10,10,9,99,111,108,111,114,46,122,32,61,32,102,32,45,32,99,111,108,111,114,46,121,59,10,9,99,111,108,111,114,46,120,121,32,42,61,32,48,46,48,48,51,57,48,54,50,53,59,32,47,47,32,42,61,32,49,46,48,47,50,53,54,10,10,9,114,101,116,117,114,110,32,99,111,108,111,114,59,10,125,10,10,35,100,101,102,105,110,101,32,107,80,73,32,51,46,49,52,49,53,57,50,54,53,51,54,10,10,118,101,99,52,32,69,110,99,111,100,101,78,111,114,109,97,108,40,105,110,32,118,101,99,51,32,110,111,114,109,97,108,41,10,123,10,9,47,47,114,101,116,117,114,110,32,118,101,99,52,40,110,111,114,109,97,108,42,48,46,53,32,43,32,48,46,53,44,32,48,46,48,41,59,10,9,114,101,116,117,114,110,32,118,101,99,52,40,118,101,99,50,40,97,116,97,110,40,110,111,114,109,97,108,46,121,44,32,110,111,114,109,97,108,46,120,41,47,107,80,73,44,32,110,111,114,109,97,108,46,122,41,44,32,48,46,48,44,32,48,46,48,41,59,10,125,10,10,102,108,111,97,116,32,86,101,99,116,111,114,84,111,68,101,112,116,104,86,97,108,117,101,40,118,101,99,51,32,118,101,99,44,32,102,108,111,97,116,32,122,78,101,97,114,44,32,102,108,111,97,116,32,122,70,97,114,41,10,123,10,9,118,101,99,51,32,97,98,115,86,101,99,32,61,32,97,98,115,40,118,101,99,41,59,10,9,102,108,111,97,116,32,108,111,99,97,108,90,32,61,32,109,97,120,40,97,98,115,86,101,99,46,120,44,32,109,97,120,40,97,98,115,86,101,99,46,121,44,32,97,98,115,86,101,99,46,122,41,41,59,10,10,9,102,108,111,97,116,32,110,111,114,109,90,32,61,32,40,40,122,70,97,114,32,43,32,122,78,101,97,114,41,32,42,32,108,111,99,97,108,90,32,45,32,40,50,46,48,42,122,70,97,114,42,122,78,101,97,114,41,41,32,47,32,40,40,122,70,97,114,32,45,32,122,78,101,97,114,41,42,108,111,99,97,108,90,41,59,10,9,114,101,116,117,114,110,32,40,110,111,114,109,90,32,43,32,49,46,48,41,32,42,32,48,46,53,59,10,125,10,10,102,108,111,97,116,32,67,97,108,99,117,108,97,116,101,68,105,114,101,99,116,105,111,110,97,108,83,104,97,100,111,119,70,97,99,116,111,114,40,105,110,116,32,108,105,103,104,116,73,110,100,101,120,41,10,123,10,9,118,101,99,52,32,108,105,103,104,116,83,112,97,99,101,80,111,115,32,61,32,118,76,105,103,104,116,83,112,97,99,101,80,111,115,91,108,105,103,104,116,73,110,100,101,120,93,59,10,9,47,47,114,101,116,117,114,110,32,40,116,101,120,116,117,114,101,40,68,105,114,101,99,116,105,111,110,97,108,83,112,111,116,76,105,103,104,116,83,104,97,100,111,119,77,97,112,91,108,105,103,104,116,73,110,100,101,120,93,44,32,108,105,103,104,116,83,112,97,99,101,80,111,115,46,120,121,41,46,120,32,62,61,32,40,108,105,103,104,116,83,112,97,99,101,80,111,115,46,122,32,45,32,48,46,48,48,48,53,41,41,32,63,32,49,46,48,32,58,32,48,46,48,59,10,32,32,32,32,114,101,116,117,114,110,32,48,46,48,59,10,125,10,10,102,108,111,97,116,32,67,97,108,99,117,108,97,116,101,80,111,105,110,116,83,104,97,100,111,119,70,97,99,116,111,114,40,105,110,116,32,108,105,103,104,116,73,110,100,101,120,44,32,118,101,99,51,32,108,105,103,104,116,84,111,87,111,114,108,100,44,32,102,108,111,97,116,32,122,78,101,97,114,44,32,102,108,111,97,116,32,122,70,97,114,41,10,123,10,9,114,101,116,117,114,110,32,40,116,101,120,116,117,114,101,40,80,111,105,110,116,76,105,103,104,116,83,104,97,100,111,119,77,97,112,91,108,105,103,104,116,73,110,100,101,120,93,44,32,118,101,99,51,40,108,105,103,104,116,84,111,87,111,114,108,100,46,120,44,32,45,108,105,103,104,116,84,111,87,111,114,108,100,46,121,44,32,45,108,105,103,104,116,84,111,87,111,114,108,100,46,122,41,41,46,120,32,62,61,32,86,101,99,116,111,114,84,111,68,101,112,116,104,86,97,108,117,101,40,108,105,103,104,116,84,111,87,111,114,108,100,44,32,122,78,101,97,114,44,32,122,70,97,114,41,41,32,63,32,49,46,48,32,58,32,48,46,48,59,10,125,10,10,102,108,111,97,116,32,67,97,108,99,117,108,97,116,101,83,112,111,116,83,104,97,100,111,119,70,97,99,116,111,114,40,105,110,116,32,108,105,103,104,116,73,110,100,101,120,41,10,123,10,9,118,101,99,52,32,108,105,103,104,116,83,112,97,99,101,80,111,115,32,61,32,118,76,105,103,104,116,83,112,97,99,101,80,111,115,91,108,105,103,104,116,73,110,100,101,120,93,59,10,10,9,102,108,111,97,116,32,118,105,115,105,98,105,108,105,116,121,32,61,32,49,46,48,59,10,9,102,108,111,97,116,32,120,44,121,59,10,9,102,111,114,32,40,121,32,61,32,45,51,46,53,59,32,121,32,60,61,32,51,46,53,59,32,121,43,61,32,49,46,48,41,10,9,9,102,111,114,32,40,120,32,61,32,45,51,46,53,59,32,120,32,60,61,32,51,46,53,59,32,120,43,61,32,49,46,48,41,10,47,47,9,9,9,32,32,118,105,115,105,98,105,108,105,116,121,32,43,61,32,40,116,101,120,116,117,114,101,80,114,111,106,40,68,105,114,101,99,116,105,111,110,97,108,83,112,111,116,76,105,103,104,116,83,104,97,100,111,119,77,97,112,91,108,105,103,104,116,73,110,100,101,120,93,44,32,108,105,103,104,116,83,112,97,99,101,80,111,115,46,120,121,119,32,43,32,118,101,99,51,40,120,47,49,48,50,52,46,48,32,42,32,108,105,103,104,116,83,112,97,99,101,80,111,115,46,119,44,32,121,47,49,48,50,52,46,48,32,42,32,108,105,103,104,116,83,112,97,99,101,80,111,115,46,119,44,32,48,46,48,41,41,46,120,32,62,61,32,40,108,105,103,104,116,83,112,97,99,101,80,111,115,46,122,32,45,32,48,46,48,48,53,41,47,108,105,103,104,116,83,112,97,99,101,80,111,115,46,119,41,32,63,32,49,46,48,32,58,32,48,46,48,59,10,9,9,9,118,105,115,105,98,105,108,105,116,121,32,43,61,32,116,101,120,116,117,114,101,80,114,111,106,40,68,105,114,101,99,116,105,111,110,97,108,83,112,111,116,76,105,103,104,116,83,104,97,100,111,119,77,97,112,91,108,105,103,104,116,73,110,100,101,120,93,44,32,108,105,103,104,116,83,112,97,99,101,80,111,115,32,43,32,118,101,99,52,40,120,47,49,48,50,52,46,48,32,42,32,108,105,103,104,116,83,112,97,99,101,80,111,115,46,119,44,32,121,47,49,48,50,52,46,48,32,42,32,108,105,103,104,116,83,112,97,99,101,80,111,115,46,119,44,32,48,46,48,53,44,32,48,46,48,41,41,59,10,10,9,118,105,115,105,98,105,108,105,116,121,32,47,61,32,54,52,46,48,59,10,9,10,9,114,101,116,117,114,110,32,118,105,115,105,98,105,108,105,116,121,59,10,125,10,10,118,111,105,100,32,109,97,105,110,40,41,10,123,10,9,118,101,99,52,32,100,105,102,102,117,115,101,67,111,108,111,114,32,61,32,77,97,116,101,114,105,97,108,68,105,102,102,117,115,101,32,42,32,118,67,111,108,111,114,59,10,10,35,105,102,32,65,85,84,79,95,84,69,88,67,79,79,82,68,83,10,9,118,101,99,50,32,116,101,120,67,111,111,114,100,32,61,32,103,108,95,70,114,97,103,67,111,111,114,100,46,120,121,32,42,32,73,110,118,84,97,114,103,101,116,83,105,122,101,59,10,35,101,108,115,101,10,9,118,101,99,50,32,116,101,120,67,111,111,114,100,32,61,32,118,84,101,120,67,111,111,114,100,59,10,35,101,110,100,105,102,10,10,35,105,102,32,76,73,71,72,84,73,78,71,32,38,38,32,80,65,82,65,76,76,65,88,95,77,65,80,80,73,78,71,10,9,102,108,111,97,116,32,104,101,105,103,104,116,32,61,32,116,101,120,116,117,114,101,40,77,97,116,101,114,105,97,108,72,101,105,103,104,116,77,97,112,44,32,116,101,120,67,111,111,114,100,41,46,114,59,10,9,102,108,111,97,116,32,118,32,61,32,104,101,105,103,104,116,42,80,97,114,97,108,108,97,120,83,99,97,108,101,32,43,32,80,97,114,97,108,108,97,120,66,105,97,115,59,10,10,9,118,101,99,51,32,118,105,101,119,68,105,114,32,61,32,110,111,114,109,97,108,105,122,101,40,118,86,105,101,119,68,105,114,41,59,10,9,116,101,120,67,111,111,114,100,32,43,61,32,118,32,42,32,118,105,101,119,68,105,114,46,120,121,59,10,35,101,110,100,105,102,10,10,35,105,102,32,68,73,70,70,85,83,69,95,77,65,80,80,73,78,71,10,9,100,105,102,102,117,115,101,67,111,108,111,114,32,42,61,32,116,101,120,116,117,114,101,40,77,97,116,101,114,105,97,108,68,105,102,102,117,115,101,77,97,112,44,32,116,101,120,67,111,111,114,100,41,59,10,35,101,110,100,105,102,10,10,35,105,102,32,70,76,65,71,95,84,69,88,84,85,82,69,79,86,69,82,76,65,89,10,9,100,105,102,102,117,115,101,67,111,108,111,114,32,42,61,32,116,101,120,116,117,114,101,40,84,101,120,116,117,114,101,79,118,101,114,108,97,121,44,32,116,101,120,67,111,111,114,100,41,59,10,35,101,110,100,105,102,10,10,35,105,102,32,70,76,65,71,95,68,69,70,69,82,82,69,68,10,9,35,105,102,32,65,76,80,72,65,95,84,69,83,84,10,9,9,47,47,32,73,110,117,116,105,108,101,32,100,101,32,102,97,105,114,101,32,100,101,32,108,39,97,108,112,104,97,45,109,97,112,112,105,110,103,32,115,97,110,115,32,97,108,112,104,97,45,116,101,115,116,32,101,110,32,68,101,102,101,114,114,101,100,32,40,108,39,97,108,112,104,97,32,110,39,101,115,116,32,112,97,115,32,115,97,117,118,101,103,97,114,100,195,169,32,100,97,110,115,32,108,101,32,71,45,66,117,102,102,101,114,41,10,9,9,35,105,102,32,65,76,80,72,65,95,77,65,80,80,73,78,71,10,9,100,105,102,102,117,115,101,67,111,108,111,114,46,97,32,42,61,32,116,101,120,116,117,114,101,40,77,97,116,101,114,105,97,108,65,108,112,104,97,77,97,112,44,32,116,101,120,67,111,111,114,100,41,46,114,59,10,9,9,35,101,110,100,105,102,10,9,9,10,9,105,102,32,40,100,105,102,102,117,115,101,67,111,108,111,114,46,97,32,60,32,77,97,116,101,114,105,97,108,65,108,112,104,97,84,104,114,101,115,104,111,108,100,41,10,9,9,100,105,115,99,97,114,100,59,10,9,35,101,110,100,105,102,32,47,47,32,65,76,80,72,65,95,84,69,83,84,10,10,9,35,105,102,32,76,73,71,72,84,73,78,71,10,9,9,35,105,102,32,78,79,82,77,65,76,95,77,65,80,80,73,78,71,10,9,118,101,99,51,32,110,111,114,109,97,108,32,61,32,110,111,114,109,97,108,105,122,101,40,118,76,105,103,104,116,84,111,87,111,114,108,100,32,42,32,40,50,46,48,32,42,32,118,101,99,51,40,116,101,120,116,117,114,101,40,77,97,116,101,114,105,97,108,78,111,114,109,97,108,77,97,112,44,32,116,101,120,67,111,111,114,100,41,41,32,45,32,49,46,48,41,41,59,10,9,9,35,101,108,115,101,10,9,118,101,99,51,32,110,111,114,109,97,108,32,61,32,110,111,114,109,97,108,105,122,101,40,118,78,111,114,109,97,108,41,59,10,9,9,35,101,110,100,105,102,32,47,47,32,78,79,82,77,65,76,95,77,65,80,80,73,78,71,10,10,9,118,101,99,51,32,115,112,101,99,117,108,97,114,67,111,108,111,114,32,61,32,77,97,116,101,114,105,97,108,83,112,101,99,117,108,97,114,46,114,103,98,59,10,9,9,35,105,102,32,83,80,69,67,85,76,65,82,95,77,65,80,80,73,78,71,10,9,115,112,101,99,117,108,97,114,67,111,108,111,114,32,42,61,32,116,101,120,116,117,114,101,40,77,97,116,101,114,105,97,108,83,112,101,99,117,108,97,114,77,97,112,44,32,116,101,120,67,111,111,114,100,41,46,114,103,98,59,10,9,9,35,101,110,100,105,102,10,10,9,47,42,10,9,84,101,120,116,117,114,101,48,58,32,68,105,102,102,117,115,101,32,67,111,108,111,114,32,43,32,83,112,101,99,117,108,97,114,10,9,84,101,120,116,117,114,101,49,58,32,78,111,114,109,97,108,32,43,32,83,112,101,99,117,108,97,114,10,9,84,101,120,116,117,114,101,50,58,32,69,110,99,111,100,101,100,32,100,101,112,116,104,32,43,32,83,104,105,110,105,110,101,115,115,10,9,42,47,10,9,82,101,110,100,101,114,84,97,114,103,101,116,48,32,61,32,118,101,99,52,40,100,105,102,102,117,115,101,67,111,108,111,114,46,114,103,98,44,32,100,111,116,40,115,112,101,99,117,108,97,114,67,111,108,111,114,44,32,118,101,99,51,40,48,46,51,44,32,48,46,53,57,44,32,48,46,49,49,41,41,41,59,10,9,82,101,110,100,101,114,84,97,114,103,101,116,49,32,61,32,118,101,99,52,40,69,110,99,111,100,101,78,111,114,109,97,108,40,110,111,114,109,97,108,41,41,59,10,9,82,101,110,100,101,114,84,97,114,103,101,116,50,32,61,32,118,101,99,52,40,70,108,111,97,116,84,111,67,111,108,111,114,40,103,108,95,70,114,97,103,67,111,111,114,100,46,122,41,44,32,40,77,97,116,101,114,105,97,108,83,104,105,110,105,110,101,115,115,32,61,61,32,48,46,48,41,32,63,32,48,46,48,32,58,32,109,97,120,40,108,111,103,50,40,77,97,116,101,114,105,97,108,83,104,105,110,105,110,101,115,115,41,44,32,48,46,49,41,47,49,48,46,53,41,59,32,47,47,32,104,116,116,112,58,47,47,119,119,119,46,103,117,101,114,114,105,108,108,97,45,103,97,109,101,115,46,99,111,109,47,112,117,98,108,105,99,97,116,105,111,110,115,47,100,114,95,107,122,50,95,114,115,120,95,100,101,118,48,55,46,112,100,102,10,9,35,101,108,115,101,32,47,47,32,76,73,71,72,84,73,78,71,10,9,82,101,110,100,101,114,84,97,114,103,101,116,48,32,61,32,118,101,99,52,40,100,105,102,102,117,115,101,67,111,108,111,114,46,114,103,98,44,32,48,46,48,41,59,10,9,35,101,110,100,105,102,10,35,101,108,115,101,32,47,47,32,70,76,65,71,95,68,69,70,69,82,82,69,68,10,9,35,105,102,32,65,76,80,72,65,95,77,65,80,80,73,78,71,10,9,100,105,102,102,117,115,101,67,111,108,111,114,46,97,32,42,61,32,116,101,120,116,117,114,101,40,77,97,116,101,114,105,97,108,65,108,112,104,97,77,97,112,44,32,116,101,120,67,111,111,114,100,41,46,114,59,10,9,35,101,110,100,105,102,10,10,9,35,105,102,32,65,76,80,72,65,95,84,69,83,84,10,9,105,102,32,40,100,105,102,102,117,115,101,67,111,108,111,114,46,97,32,60,32,77,97,116,101,114,105,97,108,65,108,112,104,97,84,104,114,101,115,104,111,108,100,41,10,9,9,100,105,115,99,97,114,100,59,10,9,35,101,110,100,105,102,10,10,9,35,105,102,32,76,73,71,72,84,73,78,71,10,9,118,101,99,51,32,108,105,103,104,116,65,109,98,105,101,110,116,32,61,32,118,101,99,51,40,48,46,48,41,59,10,9,118,101,99,51,32,108,105,103,104,116,68,105,102,102,117,115,101,32,61,32,118,101,99,51,40,48,46,48,41,59,10,9,118,101,99,51,32,108,105,103,104,116,83,112,101,99,117,108,97,114,32,61,32,118,101,99,51,40,48,46,48,41,59,10,10,9,9,35,105,102,32,78,79,82,77,65,76,95,77,65,80,80,73,78,71,10,9,118,101,99,51,32,110,111,114,109,97,108,32,61,32,110,111,114,109,97,108,105,122,101,40,118,76,105,103,104,116,84,111,87,111,114,108,100,32,42,32,40,50,46,48,32,42,32,118,101,99,51,40,116,101,120,116,117,114,101,40,77,97,116,101,114,105,97,108,78,111,114,109,97,108,77,97,112,44,32,116,101,120,67,111,111,114,100,41,41,32,45,32,49,46,48,41,41,59,10,9,9,35,101,108,115,101,10,9,118,101,99,51,32,110,111,114,109,97,108,32,61,32,110,111,114,109,97,108,105,122,101,40,118,78,111,114,109,97,108,41,59,10,9,9,35,101,110,100,105,102,10,10,9,105,102,32,40,77,97,116,101,114,105,97,108,83,104,105,110,105,110,101,115,115,32,62,32,48,46,48,41,10,9,123,10,9,9,118,101,99,51,32,101,121,101,86,101,99,32,61,32,110,111,114,109,97,108,105,122,101,40,69,121,101,80,111,115,105,116,105,111,110,32,45,32,118,87,111,114,108,100,80,111,115,41,59,10,10,9,9,102,111,114,32,40,105,110,116,32,105,32,61,32,48,59,32,105,32,60,32,51,59,32,43,43,105,41,10,9,9,123,10,9,9,9,118,101,99,52,32,108,105,103,104,116,67,111,108,111,114,32,61,32,76,105,103,104,116,115,91,105,93,46,99,111,108,111,114,59,10,9,9,9,102,108,111,97,116,32,108,105,103,104,116,65,109,98,105,101,110,116,70,97,99,116,111,114,32,61,32,76,105,103,104,116,115,91,105,93,46,102,97,99,116,111,114,115,46,120,59,10,9,9,9,102,108,111,97,116,32,108,105,103,104,116,68,105,102,102,117,115,101,70,97,99,116,111,114,32,61,32,76,105,103,104,116,115,91,105,93,46,102,97,99,116,111,114,115,46,121,59,10,10,9,9,9,115,119,105,116,99,104,32,40,76,105,103,104,116,115,91,105,93,46,116,121,112,101,41,10,9,9,9,123,10,9,9,9,9,99,97,115,101,32,76,73,71,72,84,95,68,73,82,69,67,84,73,79,78,65,76,58,10,9,9,9,9,123,10,9,9,9,9,9,118,101,99,51,32,108,105,103,104,116,68,105,114,32,61,32,45,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,49,46,120,121,122,59,10,10,9,9,9,9,9,47,47,32,65,109,98,105,101,110,116,10,9,9,9,9,9,108,105,103,104,116,65,109,98,105,101,110,116,32,43,61,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,32,42,32,108,105,103,104,116,65,109,98,105,101,110,116,70,97,99,116,111,114,32,42,32,40,77,97,116,101,114,105,97,108,65,109,98,105,101,110,116,46,114,103,98,32,43,32,83,99,101,110,101,65,109,98,105,101,110,116,46,114,103,98,41,59,10,10,9,9,9,9,9,102,108,111,97,116,32,97,116,116,32,61,32,49,46,48,59,10,10,9,9,9,9,9,35,105,102,32,83,72,65,68,79,87,95,77,65,80,80,73,78,71,10,9,9,9,9,9,105,102,32,40,76,105,103,104,116,115,91,105,93,46,115,104,97,100,111,119,77,97,112,112,105,110,103,41,10,9,9,9,9,9,123,10,9,9,9,9,9,9,102,108,111,97,116,32,115,104,97,100,111,119,70,97,99,116,111,114,32,61,32,67,97,108,99,117,108,97,116,101,68,105,114,101,99,116,105,111,110,97,108,83,104,97,100,111,119,70,97,99,116,111,114,40,105,41,59,10,9,9,9,9,9,9,105,102,32,40,115,104,97,100,111,119,70,97,99,116,111,114,32,61,61,32,48,46,48,41,10,9,9,9,9,9,9,9,98,114,101,97,107,59,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,97,116,116,32,42,61,32,115,104,97,100,111,119,70,97,99,116,111,114,59,10,9,9,9,9,9,125,10,9,9,9,9,9,35,101,110,100,105,102,10,10,9,9,9,9,9,47,47,32,68,105,102,102,117,115,101,10,9,9,9,9,9,102,108,111,97,116,32,108,97,109,98,101,114,116,32,61,32,109,97,120,40,100,111,116,40,110,111,114,109,97,108,44,32,108,105,103,104,116,68,105,114,41,44,32,48,46,48,41,59,10,10,9,9,9,9,9,108,105,103,104,116,68,105,102,102,117,115,101,32,43,61,32,97,116,116,32,42,32,108,97,109,98,101,114,116,32,42,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,32,42,32,108,105,103,104,116,68,105,102,102,117,115,101,70,97,99,116,111,114,59,10,10,9,9,9,9,9,47,47,32,83,112,101,99,117,108,97,114,10,9,9,9,9,9,118,101,99,51,32,114,101,102,108,101,99,116,105,111,110,32,61,32,114,101,102,108,101,99,116,40,45,108,105,103,104,116,68,105,114,44,32,110,111,114,109,97,108,41,59,10,9,9,9,9,9,102,108,111,97,116,32,115,112,101,99,117,108,97,114,70,97,99,116,111,114,32,61,32,109,97,120,40,100,111,116,40,114,101,102,108,101,99,116,105,111,110,44,32,101,121,101,86,101,99,41,44,32,48,46,48,41,59,10,9,9,9,9,9,115,112,101,99,117,108,97,114,70,97,99,116,111,114,32,61,32,112,111,119,40,115,112,101,99,117,108,97,114,70,97,99,116,111,114,44,32,77,97,116,101,114,105,97,108,83,104,105,110,105,110,101,115,115,41,59,10,10,9,9,9,9,9,108,105,103,104,116,83,112,101,99,117,108,97,114,32,43,61,32,97,116,116,32,42,32,115,112,101,99,117,108,97,114,70,97,99,116,111,114,32,42,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,59,10,9,9,9,9,9,98,114,101,97,107,59,10,9,9,9,9,125,10,10,9,9,9,9,99,97,115,101,32,76,73,71,72,84,95,80,79,73,78,84,58,10,9,9,9,9,123,10,9,9,9,9,9,118,101,99,51,32,108,105,103,104,116,80,111,115,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,49,46,120,121,122,59,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,65,116,116,101,110,117,97,116,105,111,110,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,49,46,119,59,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,73,110,118,82,97,100,105,117,115,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,50,46,119,59,10,9,9,9,9,9,10,9,9,9,9,9,118,101,99,51,32,119,111,114,108,100,84,111,76,105,103,104,116,32,61,32,108,105,103,104,116,80,111,115,32,45,32,118,87,111,114,108,100,80,111,115,59,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,68,105,114,76,101,110,103,116,104,32,61,32,108,101,110,103,116,104,40,119,111,114,108,100,84,111,76,105,103,104,116,41,59,10,9,9,9,9,9,118,101,99,51,32,108,105,103,104,116,68,105,114,32,61,32,119,111,114,108,100,84,111,76,105,103,104,116,32,47,32,108,105,103,104,116,68,105,114,76,101,110,103,116,104,59,32,47,47,32,78,111,114,109,97,108,105,115,97,116,105,111,110,10,9,9,9,9,9,10,9,9,9,9,9,102,108,111,97,116,32,97,116,116,32,61,32,109,97,120,40,108,105,103,104,116,65,116,116,101,110,117,97,116,105,111,110,32,45,32,108,105,103,104,116,73,110,118,82,97,100,105,117,115,32,42,32,108,105,103,104,116,68,105,114,76,101,110,103,116,104,44,32,48,46,48,41,59,10,10,9,9,9,9,9,47,47,32,65,109,98,105,101,110,116,10,9,9,9,9,9,108,105,103,104,116,65,109,98,105,101,110,116,32,43,61,32,97,116,116,32,42,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,32,42,32,108,105,103,104,116,65,109,98,105,101,110,116,70,97,99,116,111,114,32,42,32,40,77,97,116,101,114,105,97,108,65,109,98,105,101,110,116,46,114,103,98,32,43,32,83,99,101,110,101,65,109,98,105,101,110,116,46,114,103,98,41,59,10,10,9,9,9,9,9,35,105,102,32,83,72,65,68,79,87,95,77,65,80,80,73,78,71,10,9,9,9,9,9,105,102,32,40,76,105,103,104,116,115,91,105,93,46,115,104,97,100,111,119,77,97,112,112,105,110,103,41,10,9,9,9,9,9,123,10,9,9,9,9,9,9,102,108,111,97,116,32,115,104,97,100,111,119,70,97,99,116,111,114,32,61,32,67,97,108,99,117,108,97,116,101,80,111,105,110,116,83,104,97,100,111,119,70,97,99,116,111,114,40,105,44,32,118,87,111,114,108,100,80,111,115,32,45,32,108,105,103,104,116,80,111,115,44,32,48,46,49,44,32,53,48,46,48,41,59,10,9,9,9,9,9,9,105,102,32,40,115,104,97,100,111,119,70,97,99,116,111,114,32,61,61,32,48,46,48,41,10,9,9,9,9,9,9,9,98,114,101,97,107,59,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,97,116,116,32,42,61,32,115,104,97,100,111,119,70,97,99,116,111,114,59,10,9,9,9,9,9,125,10,9,9,9,9,9,35,101,110,100,105,102,10,10,9,9,9,9,9,47,47,32,68,105,102,102,117,115,101,10,9,9,9,9,9,102,108,111,97,116,32,108,97,109,98,101,114,116,32,61,32,109,97,120,40,100,111,116,40,110,111,114,109,97,108,44,32,108,105,103,104,116,68,105,114,41,44,32,48,46,48,41,59,10,9,9,9,9,9,10,9,9,9,9,9,108,105,103,104,116,68,105,102,102,117,115,101,32,43,61,32,97,116,116,32,42,32,108,97,109,98,101,114,116,32,42,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,32,42,32,108,105,103,104,116,68,105,102,102,117,115,101,70,97,99,116,111,114,59,10,10,9,9,9,9,9,47,47,32,83,112,101,99,117,108,97,114,10,9,9,9,9,9,118,101,99,51,32,114,101,102,108,101,99,116,105,111,110,32,61,32,114,101,102,108,101,99,116,40,45,108,105,103,104,116,68,105,114,44,32,110,111,114,109,97,108,41,59,10,9,9,9,9,9,102,108,111,97,116,32,115,112,101,99,117,108,97,114,70,97,99,116,111,114,32,61,32,109,97,120,40,100,111,116,40,114,101,102,108,101,99,116,105,111,110,44,32,101,121,101,86,101,99,41,44,32,48,46,48,41,59,10,9,9,9,9,9,115,112,101,99,117,108,97,114,70,97,99,116,111,114,32,61,32,112,111,119,40,115,112,101,99,117,108,97,114,70,97,99,116,111,114,44,32,77,97,116,101,114,105,97,108,83,104,105,110,105,110,101,115,115,41,59,10,10,9,9,9,9,9,108,105,103,104,116,83,112,101,99,117,108,97,114,32,43,61,32,97,116,116,32,42,32,115,112,101,99,117,108,97,114,70,97,99,116,111,114,32,42,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,59,10,9,9,9,9,9,98,114,101,97,107,59,10,9,9,9,9,125,10,10,9,9,9,9,99,97,115,101,32,76,73,71,72,84,95,83,80,79,84,58,10,9,9,9,9,123,10,9,9,9,9,9,118,101,99,51,32,108,105,103,104,116,80,111,115,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,49,46,120,121,122,59,10,9,9,9,9,9,118,101,99,51,32,108,105,103,104,116,68,105,114,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,50,46,120,121,122,59,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,65,116,116,101,110,117,97,116,105,111,110,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,49,46,119,59,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,73,110,118,82,97,100,105,117,115,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,50,46,119,59,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,73,110,110,101,114,65,110,103,108,101,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,51,46,120,59,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,79,117,116,101,114,65,110,103,108,101,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,51,46,121,59,10,10,9,9,9,9,9,118,101,99,51,32,119,111,114,108,100,84,111,76,105,103,104,116,32,61,32,108,105,103,104,116,80,111,115,32,45,32,118,87,111,114,108,100,80,111,115,59,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,68,105,115,116,97,110,99,101,32,61,32,108,101,110,103,116,104,40,119,111,114,108,100,84,111,76,105,103,104,116,41,59,10,9,9,9,9,9,119,111,114,108,100,84,111,76,105,103,104,116,32,47,61,32,108,105,103,104,116,68,105,115,116,97,110,99,101,59,32,47,47,32,78,111,114,109,97,108,105,115,97,116,105,111,110,10,9,9,9,9,9,10,9,9,9,9,9,102,108,111,97,116,32,97,116,116,32,61,32,109,97,120,40,108,105,103,104,116,65,116,116,101,110,117,97,116,105,111,110,32,45,32,108,105,103,104,116,73,110,118,82,97,100,105,117,115,32,42,32,108,105,103,104,116,68,105,115,116,97,110,99,101,44,32,48,46,48,41,59,10,10,9,9,9,9,9,47,47,32,65,109,98,105,101,110,116,10,9,9,9,9,9,108,105,103,104,116,65,109,98,105,101,110,116,32,43,61,32,97,116,116,32,42,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,32,42,32,108,105,103,104,116,65,109,98,105,101,110,116,70,97,99,116,111,114,32,42,32,40,77,97,116,101,114,105,97,108,65,109,98,105,101,110,116,46,114,103,98,32,43,32,83,99,101,110,101,65,109,98,105,101,110,116,46,114,103,98,41,59,10,10,9,9,9,9,9,35,105,102,32,83,72,65,68,79,87,95,77,65,80,80,73,78,71,10,9,9,9,9,9,105,102,32,40,76,105,103,104,116,115,91,105,93,46,115,104,97,100,111,119,77,97,112,112,105,110,103,41,10,9,9,9,9,9,123,10,9,9,9,9,9,9,102,108,111,97,116,32,115,104,97,100,111,119,70,97,99,116,111,114,32,61,32,67,97,108,99,117,108,97,116,101,83,112,111,116,83,104,97,100,111,119,70,97,99,116,111,114,40,105,41,59,10,9,9,9,9,9,9,105,102,32,40,115,104,97,100,111,119,70,97,99,116,111,114,32,61,61,32,48,46,48,41,10,9,9,9,9,9,9,9,98,114,101,97,107,59,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,97,116,116,32,42,61,32,115,104,97,100,111,119,70,97,99,116,111,114,59,10,9,9,9,9,9,125,10,9,9,9,9,9,35,101,110,100,105,102,10,10,9,9,9,9,9,47,47,32,77,111,100,105,102,105,99,97,116,105,111,110,32,100,101,32,108,39,97,116,116,195,169,110,117,97,116,105,111,110,32,112,111,117,114,32,103,195,169,114,101,114,32,108,101,32,115,112,111,116,10,9,9,9,9,9,102,108,111,97,116,32,99,117,114,65,110,103,108,101,32,61,32,100,111,116,40,108,105,103,104,116,68,105,114,44,32,45,119,111,114,108,100,84,111,76,105,103,104,116,41,59,10,9,9,9,9,9,102,108,111,97,116,32,105,110,110,101,114,77,105,110,117,115,79,117,116,101,114,65,110,103,108,101,32,61,32,108,105,103,104,116,73,110,110,101,114,65,110,103,108,101,32,45,32,108,105,103,104,116,79,117,116,101,114,65,110,103,108,101,59,10,9,9,9,9,9,97,116,116,32,42,61,32,109,97,120,40,40,99,117,114,65,110,103,108,101,32,45,32,108,105,103,104,116,79,117,116,101,114,65,110,103,108,101,41,32,47,32,105,110,110,101,114,77,105,110,117,115,79,117,116,101,114,65,110,103,108,101,44,32,48,46,48,41,59,10,10,9,9,9,9,9,47,47,32,68,105,102,102,117,115,101,10,9,9,9,9,9,102,108,111,97,116,32,108,97,109,98,101,114,116,32,61,32,109,97,120,40,100,111,116,40,110,111,114,109,97,108,44,32,119,111,114,108,100,84,111,76,105,103,104,116,41,44,32,48,46,48,41,59,10,10,9,9,9,9,9,108,105,103,104,116,68,105,102,102,117,115,101,32,43,61,32,97,116,116,32,42,32,108,97,109,98,101,114,116,32,42,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,32,42,32,108,105,103,104,116,68,105,102,102,117,115,101,70,97,99,116,111,114,59,10,10,9,9,9,9,9,47,47,32,83,112,101,99,117,108,97,114,10,9,9,9,9,9,118,101,99,51,32,114,101,102,108,101,99,116,105,111,110,32,61,32,114,101,102,108,101,99,116,40,45,119,111,114,108,100,84,111,76,105,103,104,116,44,32,110,111,114,109,97,108,41,59,10,9,9,9,9,9,102,108,111,97,116,32,115,112,101,99,117,108,97,114,70,97,99,116,111,114,32,61,32,109,97,120,40,100,111,116,40,114,101,102,108,101,99,116,105,111,110,44,32,101,121,101,86,101,99,41,44,32,48,46,48,41,59,10,9,9,9,9,9,115,112,101,99,117,108,97,114,70,97,99,116,111,114,32,61,32,112,111,119,40,115,112,101,99,117,108,97,114,70,97,99,116,111,114,44,32,77,97,116,101,114,105,97,108,83,104,105,110,105,110,101,115,115,41,59,10,10,9,9,9,9,9,108,105,103,104,116,83,112,101,99,117,108,97,114,32,43,61,32,97,116,116,32,42,32,115,112,101,99,117,108,97,114,70,97,99,116,111,114,32,42,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,59,10,9,9,9,9,9,98,114,101,97,107,59,10,9,9,9,9,125,10,9,9,9,9,10,9,9,9,9,100,101,102,97,117,108,116,58,10,9,9,9,9,9,98,114,101,97,107,59,10,9,9,9,125,10,9,9,125,10,9,125,10,9,101,108,115,101,10,9,123,10,9,9,102,111,114,32,40,105,110,116,32,105,32,61,32,48,59,32,105,32,60,32,51,59,32,43,43,105,41,10,9,9,123,10,9,9,9,118,101,99,52,32,108,105,103,104,116,67,111,108,111,114,32,61,32,76,105,103,104,116,115,91,105,93,46,99,111,108,111,114,59,10,9,9,9,102,108,111,97,116,32,108,105,103,104,116,65,109,98,105,101,110,116,70,97,99,116,111,114,32,61,32,76,105,103,104,116,115,91,105,93,46,102,97,99,116,111,114,115,46,120,59,10,9,9,9,102,108,111,97,116,32,108,105,103,104,116,68,105,102,102,117,115,101,70,97,99,116,111,114,32,61,32,76,105,103,104,116,115,91,105,93,46,102,97,99,116,111,114,115,46,121,59,10,10,9,9,9,115,119,105,116,99,104,32,40,76,105,103,104,116,115,91,105,93,46,116,121,112,101,41,10,9,9,9,123,10,9,9,9,9,99,97,115,101,32,76,73,71,72,84,95,68,73,82,69,67,84,73,79,78,65,76,58,10,9,9,9,9,123,10,9,9,9,9,9,118,101,99,51,32,108,105,103,104,116,68,105,114,32,61,32,45,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,49,46,120,121,122,59,10,10,9,9,9,9,9,47,47,32,65,109,98,105,101,110,116,10,9,9,9,9,9,108,105,103,104,116,65,109,98,105,101,110,116,32,43,61,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,32,42,32,108,105,103,104,116,65,109,98,105,101,110,116,70,97,99,116,111,114,32,42,32,40,77,97,116,101,114,105,97,108,65,109,98,105,101,110,116,46,114,103,98,32,43,32,83,99,101,110,101,65,109,98,105,101,110,116,46,114,103,98,41,59,10,10,9,9,9,9,9,102,108,111,97,116,32,97,116,116,32,61,32,49,46,48,59,10,10,9,9,9,9,9,35,105,102,32,83,72,65,68,79,87,95,77,65,80,80,73,78,71,10,9,9,9,9,9,105,102,32,40,76,105,103,104,116,115,91,105,93,46,115,104,97,100,111,119,77,97,112,112,105,110,103,41,10,9,9,9,9,9,123,10,9,9,9,9,9,9,102,108,111,97,116,32,115,104,97,100,111,119,70,97,99,116,111,114,32,61,32,67,97,108,99,117,108,97,116,101,68,105,114,101,99,116,105,111,110,97,108,83,104,97,100,111,119,70,97,99,116,111,114,40,105,41,59,10,9,9,9,9,9,9,105,102,32,40,115,104,97,100,111,119,70,97,99,116,111,114,32,61,61,32,48,46,48,41,10,9,9,9,9,9,9,9,98,114,101,97,107,59,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,97,116,116,32,42,61,32,115,104,97,100,111,119,70,97,99,116,111,114,59,10,9,9,9,9,9,125,10,9,9,9,9,9,35,101,110,100,105,102,10,10,9,9,9,9,9,47,47,32,68,105,102,102,117,115,101,10,9,9,9,9,9,102,108,111,97,116,32,108,97,109,98,101,114,116,32,61,32,109,97,120,40,100,111,116,40,110,111,114,109,97,108,44,32,108,105,103,104,116,68,105,114,41,44,32,48,46,48,41,59,10,10,9,9,9,9,9,108,105,103,104,116,68,105,102,102,117,115,101,32,43,61,32,97,116,116,32,42,32,108,97,109,98,101,114,116,32,42,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,32,42,32,108,105,103,104,116,68,105,102,102,117,115,101,70,97,99,116,111,114,59,10,9,9,9,9,9,98,114,101,97,107,59,10,9,9,9,9,125,10,10,9,9,9,9,99,97,115,101,32,76,73,71,72,84,95,80,79,73,78,84,58,10,9,9,9,9,123,10,9,9,9,9,9,118,101,99,51,32,108,105,103,104,116,80,111,115,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,49,46,120,121,122,59,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,65,116,116,101,110,117,97,116,105,111,110,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,49,46,119,59,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,73,110,118,82,97,100,105,117,115,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,50,46,119,59,10,9,9,9,9,9,10,9,9,9,9,9,118,101,99,51,32,119,111,114,108,100,84,111,76,105,103,104,116,32,61,32,108,105,103,104,116,80,111,115,32,45,32,118,87,111,114,108,100,80,111,115,59,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,68,105,114,76,101,110,103,116,104,32,61,32,108,101,110,103,116,104,40,119,111,114,108,100,84,111,76,105,103,104,116,41,59,10,9,9,9,9,9,118,101,99,51,32,108,105,103,104,116,68,105,114,32,61,32,119,111,114,108,100,84,111,76,105,103,104,116,32,47,32,108,105,103,104,116,68,105,114,76,101,110,103,116,104,59,32,47,47,32,78,111,114,109,97,108,105,115,97,116,105,111,110,10,9,9,9,9,9,10,9,9,9,9,9,102,108,111,97,116,32,97,116,116,32,61,32,109,97,120,40,108,105,103,104,116,65,116,116,101,110,117,97,116,105,111,110,32,45,32,108,105,103,104,116,73,110,118,82,97,100,105,117,115,32,42,32,108,105,103,104,116,68,105,114,76,101,110,103,116,104,44,32,48,46,48,41,59,10,10,9,9,9,9,9,47,47,32,65,109,98,105,101,110,116,10,9,9,9,9,9,108,105,103,104,116,65,109,98,105,101,110,116,32,43,61,32,97,116,116,32,42,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,32,42,32,108,105,103,104,116,65,109,98,105,101,110,116,70,97,99,116,111,114,32,42,32,40,77,97,116,101,114,105,97,108,65,109,98,105,101,110,116,46,114,103,98,32,43,32,83,99,101,110,101,65,109,98,105,101,110,116,46,114,103,98,41,59,10,10,9,9,9,9,9,35,105,102,32,83,72,65,68,79,87,95,77,65,80,80,73,78,71,10,9,9,9,9,9,105,102,32,40,76,105,103,104,116,115,91,105,93,46,115,104,97,100,111,119,77,97,112,112,105,110,103,41,10,9,9,9,9,9,123,10,9,9,9,9,9,9,102,108,111,97,116,32,115,104,97,100,111,119,70,97,99,116,111,114,32,61,32,67,97,108,99,117,108,97,116,101,80,111,105,110,116,83,104,97,100,111,119,70,97,99,116,111,114,40,105,44,32,118,87,111,114,108,100,80,111,115,32,45,32,108,105,103,104,116,80,111,115,44,32,48,46,49,44,32,53,48,46,48,41,59,10,9,9,9,9,9,9,105,102,32,40,115,104,97,100,111,119,70,97,99,116,111,114,32,61,61,32,48,46,48,41,10,9,9,9,9,9,9,9,98,114,101,97,107,59,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,97,116,116,32,42,61,32,115,104,97,100,111,119,70,97,99,116,111,114,59,10,9,9,9,9,9,125,10,9,9,9,9,9,35,101,110,100,105,102,10,10,9,9,9,9,9,47,47,32,68,105,102,102,117,115,101,10,9,9,9,9,9,102,108,111,97,116,32,108,97,109,98,101,114,116,32,61,32,109,97,120,40,100,111,116,40,110,111,114,109,97,108,44,32,108,105,103,104,116,68,105,114,41,44,32,48,46,48,41,59,10,9,9,9,9,9,10,9,9,9,9,9,108,105,103,104,116,68,105,102,102,117,115,101,32,43,61,32,97,116,116,32,42,32,108,97,109,98,101,114,116,32,42,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,32,42,32,108,105,103,104,116,68,105,102,102,117,115,101,70,97,99,116,111,114,59,10,9,9,9,9,9,98,114,101,97,107,59,10,9,9,9,9,125,10,10,9,9,9,9,99,97,115,101,32,76,73,71,72,84,95,83,80,79,84,58,10,9,9,9,9,123,10,9,9,9,9,9,118,101,99,51,32,108,105,103,104,116,80,111,115,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,49,46,120,121,122,59,10,9,9,9,9,9,118,101,99,51,32,108,105,103,104,116,68,105,114,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,50,46,120,121,122,59,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,65,116,116,101,110,117,97,116,105,111,110,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,49,46,119,59,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,73,110,118,82,97,100,105,117,115,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,50,46,119,59,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,73,110,110,101,114,65,110,103,108,101,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,51,46,120,59,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,79,117,116,101,114,65,110,103,108,101,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,51,46,121,59,10,10,9,9,9,9,9,118,101,99,51,32,119,111,114,108,100,84,111,76,105,103,104,116,32,61,32,108,105,103,104,116,80,111,115,32,45,32,118,87,111,114,108,100,80,111,115,59,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,68,105,115,116,97,110,99,101,32,61,32,108,101,110,103,116,104,40,119,111,114,108,100,84,111,76,105,103,104,116,41,59,10,9,9,9,9,9,119,111,114,108,100,84,111,76,105,103,104,116,32,47,61,32,108,105,103,104,116,68,105,115,116,97,110,99,101,59,32,47,47,32,78,111,114,109,97,108,105,115,97,116,105,111,110,10,9,9,9,9,9,10,9,9,9,9,9,102,108,111,97,116,32,97,116,116,32,61,32,109,97,120,40,108,105,103,104,116,65,116,116,101,110,117,97,116,105,111,110,32,45,32,108,105,103,104,116,73,110,118,82,97,100,105,117,115,32,42,32,108,105,103,104,116,68,105,115,116,97,110,99,101,44,32,48,46,48,41,59,10,10,9,9,9,9,9,47,47,32,65,109,98,105,101,110,116,10,9,9,9,9,9,108,105,103,104,116,65,109,98,105,101,110,116,32,43,61,32,97,116,116,32,42,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,32,42,32,108,105,103,104,116,65,109,98,105,101,110,116,70,97,99,116,111,114,32,42,32,40,77,97,116,101,114,105,97,108,65,109,98,105,101,110,116,46,114,103,98,32,43,32,83,99,101,110,101,65,109,98,105,101,110,116,46,114,103,98,41,59,10,10,9,9,9,9,9,35,105,102,32,83,72,65,68,79,87,95,77,65,80,80,73,78,71,10,9,9,9,9,9,105,102,32,40,76,105,103,104,116,115,91,105,93,46,115,104,97,100,111,119,77,97,112,112,105,110,103,41,10,9,9,9,9,9,123,10,9,9,9,9,9,9,102,108,111,97,116,32,115,104,97,100,111,119,70,97,99,116,111,114,32,61,32,67,97,108,99,117,108,97,116,101,83,112,111,116,83,104,97,100,111,119,70,97,99,116,111,114,40,105,41,59,10,9,9,9,9,9,9,105,102,32,40,115,104,97,100,111,119,70,97,99,116,111,114,32,61,61,32,48,46,48,41,10,9,9,9,9,9,9,9,98,114,101,97,107,59,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,97,116,116,32,42,61,32,115,104,97,100,111,119,70,97,99,116,111,114,59,10,9,9,9,9,9,125,10,9,9,9,9,9,35,101,110,100,105,102,10,10,9,9,9,9,9,47,47,32,77,111,100,105,102,105,99,97,116,105,111,110,32,100,101,32,108,39,97,116,116,195,169,110,117,97,116,105,111,110,32,112,111,117,114,32,103,195,169,114,101,114,32,108,101,32,115,112,111,116,10,9,9,9,9,9,102,108,111,97,116,32,99,117,114,65,110,103,108,101,32,61,32,100,111,116,40,108,105,103,104,116,68,105,114,44,32,45,119,111,114,108,100,84,111,76,105,103,104,116,41,59,10,9,9,9,9,9,102,108,111,97,116,32,105,110,110,101,114,77,105,110,117,115,79,117,116,101,114,65,110,103,108,101,32,61,32,108,105,103,104,116,73,110,110,101,114,65,110,103,108,101,32,45,32,108,105,103,104,116,79,117,116,101,114,65,110,103,108,101,59,10,9,9,9,9,9,97,116,116,32,42,61,32,109,97,120,40,40,99,117,114,65,110,103,108,101,32,45,32,108,105,103,104,116,79,117,116,101,114,65,110,103,108,101,41,32,47,32,105,110,110,101,114,77,105,110,117,115,79,117,116,101,114,65,110,103,108,101,44,32,48,46,48,41,59,10,10,9,9,9,9,9,47,47,32,68,105,102,102,117,115,101,10,9,9,9,9,9,102,108,111,97,116,32,108,97,109,98,101,114,116,32,61,32,109,97,120,40,100,111,116,40,110,111,114,109,97,108,44,32,119,111,114,108,100,84,111,76,105,103,104,116,41,44,32,48,46,48,41,59,10,10,9,9,9,9,9,108,105,103,104,116,68,105,102,102,117,115,101,32,43,61,32,97,116,116,32,42,32,108,97,109,98,101,114,116,32,42,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,32,42,32,108,105,103,104,116,68,105,102,102,117,115,101,70,97,99,116,111,114,59,10,9,9,9,9,125,10,9,9,9,9,10,9,9,9,9,100,101,102,97,117,108,116,58,10,9,9,9,9,9,98,114,101,97,107,59,10,9,9,9,125,10,9,9,125,10,9,125,10,9,10,9,108,105,103,104,116,83,112,101,99,117,108,97,114,32,42,61,32,77,97,116,101,114,105,97,108,83,112,101,99,117,108,97,114,46,114,103,98,59,10,9,9,35,105,102,32,83,80,69,67,85,76,65,82,95,77,65,80,80,73,78,71,10,9,108,105,103,104,116,83,112,101,99,117,108,97,114,32,42,61,32,116,101,120,116,117,114,101,40,77,97,116,101,114,105,97,108,83,112,101,99,117,108,97,114,77,97,112,44,32,116,101,120,67,111,111,114,100,41,46,114,103,98,59,32,47,47,32,85,116,105,108,105,115,101,114,32,108,39,97,108,112,104,97,32,100,101,32,77,97,116,101,114,105,97,108,83,112,101,99,117,108,97,114,32,110,39,97,117,114,97,105,116,32,97,117,99,117,110,32,115,101,110,115,10,9,9,35,101,110,100,105,102,10,9,9,10,9,118,101,99,51,32,108,105,103,104,116,67,111,108,111,114,32,61,32,40,108,105,103,104,116,65,109,98,105,101,110,116,32,43,32,108,105,103,104,116,68,105,102,102,117,115,101,32,43,32,108,105,103,104,116,83,112,101,99,117,108,97,114,41,59,10,9,118,101,99,52,32,102,114,97,103,109,101,110,116,67,111,108,111,114,32,61,32,118,101,99,52,40,108,105,103,104,116,67,111,108,111,114,44,32,49,46,48,41,32,42,32,100,105,102,102,117,115,101,67,111,108,111,114,59,10,10,9,9,35,105,102,32,69,77,73,83,83,73,86,69,95,77,65,80,80,73,78,71,10,9,102,108,111,97,116,32,108,105,103,104,116,73,110,116,101,110,115,105,116,121,32,61,32,100,111,116,40,108,105,103,104,116,67,111,108,111,114,44,32,118,101,99,51,40,48,46,51,44,32,48,46,53,57,44,32,48,46,49,49,41,41,59,10,10,9,118,101,99,51,32,101,109,105,115,115,105,111,110,67,111,108,111,114,32,61,32,77,97,116,101,114,105,97,108,68,105,102,102,117,115,101,46,114,103,98,32,42,32,116,101,120,116,117,114,101,40,77,97,116,101,114,105,97,108,69,109,105,115,115,105,118,101,77,97,112,44,32,116,101,120,67,111,111,114,100,41,46,114,103,98,59,10,9,82,101,110,100,101,114,84,97,114,103,101,116,48,32,61,32,118,101,99,52,40,109,105,120,40,102,114,97,103,109,101,110,116,67,111,108,111,114,46,114,103,98,44,32,101,109,105,115,115,105,111,110,67,111,108,111,114,44,32,99,108,97,109,112,40,49,46,48,32,45,32,51,46,48,42,108,105,103,104,116,73,110,116,101,110,115,105,116,121,44,32,48,46,48,44,32,49,46,48,41,41,44,32,102,114,97,103,109,101,110,116,67,111,108,111,114,46,97,41,59,10,9,9,35,101,108,115,101,10,9,82,101,110,100,101,114,84,97,114,103,101,116,48,32,61,32,102,114,97,103,109,101,110,116,67,111,108,111,114,59,10,9,9,35,101,110,100,105,102,32,47,47,32,69,77,73,83,83,73,86,69,95,77,65,80,80,73,78,71,10,9,35,101,108,115,101,10,9,82,101,110,100,101,114,84,97,114,103,101,116,48,32,61,32,100,105,102,102,117,115,101,67,111,108,111,114,59,10,9,35,101,110,100,105,102,32,47,47,32,76,73,71,72,84,73,78,71,10,35,101,110,100,105,102,32,47,47,32,70,76,65,71,95,68,69,70,69,82,82,69,68,10,125,10,10, \ No newline at end of file From cd3b19ca799564b2facf04a01b53dbc3ecb51f47 Mon Sep 17 00:00:00 2001 From: Lynix Date: Wed, 19 Aug 2015 13:46:11 +0200 Subject: [PATCH 32/37] Graphics/Shader: Fix shadowing Former-commit-id: 54fc9a019217eef85281c33a8a7becb6fec4f851 --- src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.frag | 2 +- src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.frag.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.frag b/src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.frag index 9e446aefd..94184d6ab 100644 --- a/src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.frag +++ b/src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.frag @@ -113,7 +113,7 @@ float CalculateSpotShadowFactor(int lightIndex) float x,y; for (y = -3.5; y <= 3.5; y+= 1.0) for (x = -3.5; x <= 3.5; x+= 1.0) - visibility += textureProj(DirectionalSpotLightShadowMap[lightIndex], lightSpacePos + vec4(x/1024.0 * lightSpacePos.w, y/1024.0 * lightSpacePos.w, 0.05, 0.0)); + visibility += (textureProj(DirectionalSpotLightShadowMap[lightIndex], lightSpacePos.xyw + vec3(x/1024.0 * lightSpacePos.w, y/1024.0 * lightSpacePos.w, 0.0)).x >= (lightSpacePos.z - 0.0005)/lightSpacePos.w) ? 1.0 : 0.0; visibility /= 64.0; diff --git a/src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.frag.h b/src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.frag.h index 441a300c1..b3c3f2c63 100644 --- a/src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.frag.h +++ b/src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.frag.h @@ -1 +1 @@ -35,105,102,32,69,65,82,76,89,95,70,82,65,71,77,69,78,84,95,84,69,83,84,83,32,38,38,32,33,65,76,80,72,65,95,84,69,83,84,10,108,97,121,111,117,116,40,101,97,114,108,121,95,102,114,97,103,109,101,110,116,95,116,101,115,116,115,41,32,105,110,59,10,35,101,110,100,105,102,10,10,35,100,101,102,105,110,101,32,76,73,71,72,84,95,68,73,82,69,67,84,73,79,78,65,76,32,48,10,35,100,101,102,105,110,101,32,76,73,71,72,84,95,80,79,73,78,84,32,49,10,35,100,101,102,105,110,101,32,76,73,71,72,84,95,83,80,79,84,32,50,10,10,47,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,69,110,116,114,97,110,116,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,47,10,105,110,32,118,101,99,52,32,118,67,111,108,111,114,59,10,105,110,32,118,101,99,52,32,118,76,105,103,104,116,83,112,97,99,101,80,111,115,91,51,93,59,10,105,110,32,109,97,116,51,32,118,76,105,103,104,116,84,111,87,111,114,108,100,59,10,105,110,32,118,101,99,51,32,118,78,111,114,109,97,108,59,10,105,110,32,118,101,99,50,32,118,84,101,120,67,111,111,114,100,59,10,105,110,32,118,101,99,51,32,118,86,105,101,119,68,105,114,59,10,105,110,32,118,101,99,51,32,118,87,111,114,108,100,80,111,115,59,10,10,47,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,83,111,114,116,97,110,116,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,47,10,111,117,116,32,118,101,99,52,32,82,101,110,100,101,114,84,97,114,103,101,116,48,59,10,111,117,116,32,118,101,99,52,32,82,101,110,100,101,114,84,97,114,103,101,116,49,59,10,111,117,116,32,118,101,99,52,32,82,101,110,100,101,114,84,97,114,103,101,116,50,59,10,10,47,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,85,110,105,102,111,114,109,101,115,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,47,10,115,116,114,117,99,116,32,76,105,103,104,116,10,123,10,9,105,110,116,32,116,121,112,101,59,10,9,118,101,99,52,32,99,111,108,111,114,59,10,9,118,101,99,50,32,102,97,99,116,111,114,115,59,10,10,9,118,101,99,52,32,112,97,114,97,109,101,116,101,114,115,49,59,10,9,118,101,99,52,32,112,97,114,97,109,101,116,101,114,115,50,59,10,9,118,101,99,50,32,112,97,114,97,109,101,116,101,114,115,51,59,10,9,98,111,111,108,32,115,104,97,100,111,119,77,97,112,112,105,110,103,59,10,125,59,10,10,47,47,32,76,117,109,105,195,168,114,101,115,10,117,110,105,102,111,114,109,32,76,105,103,104,116,32,76,105,103,104,116,115,91,51,93,59,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,67,117,98,101,32,80,111,105,110,116,76,105,103,104,116,83,104,97,100,111,119,77,97,112,91,51,93,59,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,68,105,114,101,99,116,105,111,110,97,108,83,112,111,116,76,105,103,104,116,83,104,97,100,111,119,77,97,112,91,51,93,59,10,10,47,47,32,77,97,116,195,169,114,105,97,117,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,77,97,116,101,114,105,97,108,65,108,112,104,97,77,97,112,59,10,117,110,105,102,111,114,109,32,102,108,111,97,116,32,77,97,116,101,114,105,97,108,65,108,112,104,97,84,104,114,101,115,104,111,108,100,59,10,117,110,105,102,111,114,109,32,118,101,99,52,32,77,97,116,101,114,105,97,108,65,109,98,105,101,110,116,59,10,117,110,105,102,111,114,109,32,118,101,99,52,32,77,97,116,101,114,105,97,108,68,105,102,102,117,115,101,59,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,77,97,116,101,114,105,97,108,68,105,102,102,117,115,101,77,97,112,59,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,77,97,116,101,114,105,97,108,69,109,105,115,115,105,118,101,77,97,112,59,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,77,97,116,101,114,105,97,108,72,101,105,103,104,116,77,97,112,59,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,77,97,116,101,114,105,97,108,78,111,114,109,97,108,77,97,112,59,10,117,110,105,102,111,114,109,32,102,108,111,97,116,32,77,97,116,101,114,105,97,108,83,104,105,110,105,110,101,115,115,59,10,117,110,105,102,111,114,109,32,118,101,99,52,32,77,97,116,101,114,105,97,108,83,112,101,99,117,108,97,114,59,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,77,97,116,101,114,105,97,108,83,112,101,99,117,108,97,114,77,97,112,59,10,10,47,47,32,65,117,116,114,101,115,10,117,110,105,102,111,114,109,32,102,108,111,97,116,32,80,97,114,97,108,108,97,120,66,105,97,115,32,61,32,45,48,46,48,51,59,10,117,110,105,102,111,114,109,32,102,108,111,97,116,32,80,97,114,97,108,108,97,120,83,99,97,108,101,32,61,32,48,46,48,50,59,10,117,110,105,102,111,114,109,32,118,101,99,50,32,73,110,118,84,97,114,103,101,116,83,105,122,101,59,10,117,110,105,102,111,114,109,32,118,101,99,51,32,69,121,101,80,111,115,105,116,105,111,110,59,10,117,110,105,102,111,114,109,32,118,101,99,52,32,83,99,101,110,101,65,109,98,105,101,110,116,59,10,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,84,101,120,116,117,114,101,79,118,101,114,108,97,121,59,10,10,47,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,70,111,110,99,116,105,111,110,115,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,47,10,118,101,99,51,32,70,108,111,97,116,84,111,67,111,108,111,114,40,102,108,111,97,116,32,102,41,10,123,10,9,118,101,99,51,32,99,111,108,111,114,59,10,10,9,102,32,42,61,32,50,53,54,46,48,59,10,9,99,111,108,111,114,46,120,32,61,32,102,108,111,111,114,40,102,41,59,10,10,9,102,32,61,32,40,102,32,45,32,99,111,108,111,114,46,120,41,32,42,32,50,53,54,46,48,59,10,9,99,111,108,111,114,46,121,32,61,32,102,108,111,111,114,40,102,41,59,10,10,9,99,111,108,111,114,46,122,32,61,32,102,32,45,32,99,111,108,111,114,46,121,59,10,9,99,111,108,111,114,46,120,121,32,42,61,32,48,46,48,48,51,57,48,54,50,53,59,32,47,47,32,42,61,32,49,46,48,47,50,53,54,10,10,9,114,101,116,117,114,110,32,99,111,108,111,114,59,10,125,10,10,35,100,101,102,105,110,101,32,107,80,73,32,51,46,49,52,49,53,57,50,54,53,51,54,10,10,118,101,99,52,32,69,110,99,111,100,101,78,111,114,109,97,108,40,105,110,32,118,101,99,51,32,110,111,114,109,97,108,41,10,123,10,9,47,47,114,101,116,117,114,110,32,118,101,99,52,40,110,111,114,109,97,108,42,48,46,53,32,43,32,48,46,53,44,32,48,46,48,41,59,10,9,114,101,116,117,114,110,32,118,101,99,52,40,118,101,99,50,40,97,116,97,110,40,110,111,114,109,97,108,46,121,44,32,110,111,114,109,97,108,46,120,41,47,107,80,73,44,32,110,111,114,109,97,108,46,122,41,44,32,48,46,48,44,32,48,46,48,41,59,10,125,10,10,102,108,111,97,116,32,86,101,99,116,111,114,84,111,68,101,112,116,104,86,97,108,117,101,40,118,101,99,51,32,118,101,99,44,32,102,108,111,97,116,32,122,78,101,97,114,44,32,102,108,111,97,116,32,122,70,97,114,41,10,123,10,9,118,101,99,51,32,97,98,115,86,101,99,32,61,32,97,98,115,40,118,101,99,41,59,10,9,102,108,111,97,116,32,108,111,99,97,108,90,32,61,32,109,97,120,40,97,98,115,86,101,99,46,120,44,32,109,97,120,40,97,98,115,86,101,99,46,121,44,32,97,98,115,86,101,99,46,122,41,41,59,10,10,9,102,108,111,97,116,32,110,111,114,109,90,32,61,32,40,40,122,70,97,114,32,43,32,122,78,101,97,114,41,32,42,32,108,111,99,97,108,90,32,45,32,40,50,46,48,42,122,70,97,114,42,122,78,101,97,114,41,41,32,47,32,40,40,122,70,97,114,32,45,32,122,78,101,97,114,41,42,108,111,99,97,108,90,41,59,10,9,114,101,116,117,114,110,32,40,110,111,114,109,90,32,43,32,49,46,48,41,32,42,32,48,46,53,59,10,125,10,10,102,108,111,97,116,32,67,97,108,99,117,108,97,116,101,68,105,114,101,99,116,105,111,110,97,108,83,104,97,100,111,119,70,97,99,116,111,114,40,105,110,116,32,108,105,103,104,116,73,110,100,101,120,41,10,123,10,9,118,101,99,52,32,108,105,103,104,116,83,112,97,99,101,80,111,115,32,61,32,118,76,105,103,104,116,83,112,97,99,101,80,111,115,91,108,105,103,104,116,73,110,100,101,120,93,59,10,9,114,101,116,117,114,110,32,40,116,101,120,116,117,114,101,40,68,105,114,101,99,116,105,111,110,97,108,83,112,111,116,76,105,103,104,116,83,104,97,100,111,119,77,97,112,91,108,105,103,104,116,73,110,100,101,120,93,44,32,108,105,103,104,116,83,112,97,99,101,80,111,115,46,120,121,41,46,120,32,62,61,32,40,108,105,103,104,116,83,112,97,99,101,80,111,115,46,122,32,45,32,48,46,48,48,48,53,41,41,32,63,32,49,46,48,32,58,32,48,46,48,59,10,125,10,10,102,108,111,97,116,32,67,97,108,99,117,108,97,116,101,80,111,105,110,116,83,104,97,100,111,119,70,97,99,116,111,114,40,105,110,116,32,108,105,103,104,116,73,110,100,101,120,44,32,118,101,99,51,32,108,105,103,104,116,84,111,87,111,114,108,100,44,32,102,108,111,97,116,32,122,78,101,97,114,44,32,102,108,111,97,116,32,122,70,97,114,41,10,123,10,9,114,101,116,117,114,110,32,40,116,101,120,116,117,114,101,40,80,111,105,110,116,76,105,103,104,116,83,104,97,100,111,119,77,97,112,91,108,105,103,104,116,73,110,100,101,120,93,44,32,118,101,99,51,40,108,105,103,104,116,84,111,87,111,114,108,100,46,120,44,32,45,108,105,103,104,116,84,111,87,111,114,108,100,46,121,44,32,45,108,105,103,104,116,84,111,87,111,114,108,100,46,122,41,41,46,120,32,62,61,32,86,101,99,116,111,114,84,111,68,101,112,116,104,86,97,108,117,101,40,108,105,103,104,116,84,111,87,111,114,108,100,44,32,122,78,101,97,114,44,32,122,70,97,114,41,41,32,63,32,49,46,48,32,58,32,48,46,48,59,10,125,10,10,102,108,111,97,116,32,67,97,108,99,117,108,97,116,101,83,112,111,116,83,104,97,100,111,119,70,97,99,116,111,114,40,105,110,116,32,108,105,103,104,116,73,110,100,101,120,41,10,123,10,9,118,101,99,52,32,108,105,103,104,116,83,112,97,99,101,80,111,115,32,61,32,118,76,105,103,104,116,83,112,97,99,101,80,111,115,91,108,105,103,104,116,73,110,100,101,120,93,59,10,10,9,102,108,111,97,116,32,118,105,115,105,98,105,108,105,116,121,32,61,32,49,46,48,59,10,9,102,108,111,97,116,32,120,44,121,59,10,9,102,111,114,32,40,121,32,61,32,45,51,46,53,59,32,121,32,60,61,32,51,46,53,59,32,121,43,61,32,49,46,48,41,10,9,9,102,111,114,32,40,120,32,61,32,45,51,46,53,59,32,120,32,60,61,32,51,46,53,59,32,120,43,61,32,49,46,48,41,10,9,9,9,118,105,115,105,98,105,108,105,116,121,32,43,61,32,116,101,120,116,117,114,101,80,114,111,106,40,68,105,114,101,99,116,105,111,110,97,108,83,112,111,116,76,105,103,104,116,83,104,97,100,111,119,77,97,112,91,108,105,103,104,116,73,110,100,101,120,93,44,32,108,105,103,104,116,83,112,97,99,101,80,111,115,32,43,32,118,101,99,52,40,120,47,49,48,50,52,46,48,32,42,32,108,105,103,104,116,83,112,97,99,101,80,111,115,46,119,44,32,121,47,49,48,50,52,46,48,32,42,32,108,105,103,104,116,83,112,97,99,101,80,111,115,46,119,44,32,48,46,48,53,44,32,48,46,48,41,41,59,10,10,9,118,105,115,105,98,105,108,105,116,121,32,47,61,32,54,52,46,48,59,10,9,10,9,114,101,116,117,114,110,32,118,105,115,105,98,105,108,105,116,121,59,10,125,10,10,118,111,105,100,32,109,97,105,110,40,41,10,123,10,9,118,101,99,52,32,100,105,102,102,117,115,101,67,111,108,111,114,32,61,32,77,97,116,101,114,105,97,108,68,105,102,102,117,115,101,32,42,32,118,67,111,108,111,114,59,10,10,35,105,102,32,65,85,84,79,95,84,69,88,67,79,79,82,68,83,10,9,118,101,99,50,32,116,101,120,67,111,111,114,100,32,61,32,103,108,95,70,114,97,103,67,111,111,114,100,46,120,121,32,42,32,73,110,118,84,97,114,103,101,116,83,105,122,101,59,10,35,101,108,115,101,10,9,118,101,99,50,32,116,101,120,67,111,111,114,100,32,61,32,118,84,101,120,67,111,111,114,100,59,10,35,101,110,100,105,102,10,10,35,105,102,32,76,73,71,72,84,73,78,71,32,38,38,32,80,65,82,65,76,76,65,88,95,77,65,80,80,73,78,71,10,9,102,108,111,97,116,32,104,101,105,103,104,116,32,61,32,116,101,120,116,117,114,101,40,77,97,116,101,114,105,97,108,72,101,105,103,104,116,77,97,112,44,32,116,101,120,67,111,111,114,100,41,46,114,59,10,9,102,108,111,97,116,32,118,32,61,32,104,101,105,103,104,116,42,80,97,114,97,108,108,97,120,83,99,97,108,101,32,43,32,80,97,114,97,108,108,97,120,66,105,97,115,59,10,10,9,118,101,99,51,32,118,105,101,119,68,105,114,32,61,32,110,111,114,109,97,108,105,122,101,40,118,86,105,101,119,68,105,114,41,59,10,9,116,101,120,67,111,111,114,100,32,43,61,32,118,32,42,32,118,105,101,119,68,105,114,46,120,121,59,10,35,101,110,100,105,102,10,10,35,105,102,32,68,73,70,70,85,83,69,95,77,65,80,80,73,78,71,10,9,100,105,102,102,117,115,101,67,111,108,111,114,32,42,61,32,116,101,120,116,117,114,101,40,77,97,116,101,114,105,97,108,68,105,102,102,117,115,101,77,97,112,44,32,116,101,120,67,111,111,114,100,41,59,10,35,101,110,100,105,102,10,10,35,105,102,32,70,76,65,71,95,84,69,88,84,85,82,69,79,86,69,82,76,65,89,10,9,100,105,102,102,117,115,101,67,111,108,111,114,32,42,61,32,116,101,120,116,117,114,101,40,84,101,120,116,117,114,101,79,118,101,114,108,97,121,44,32,116,101,120,67,111,111,114,100,41,59,10,35,101,110,100,105,102,10,10,35,105,102,32,70,76,65,71,95,68,69,70,69,82,82,69,68,10,9,35,105,102,32,65,76,80,72,65,95,84,69,83,84,10,9,9,47,47,32,73,110,117,116,105,108,101,32,100,101,32,102,97,105,114,101,32,100,101,32,108,39,97,108,112,104,97,45,109,97,112,112,105,110,103,32,115,97,110,115,32,97,108,112,104,97,45,116,101,115,116,32,101,110,32,68,101,102,101,114,114,101,100,32,40,108,39,97,108,112,104,97,32,110,39,101,115,116,32,112,97,115,32,115,97,117,118,101,103,97,114,100,195,169,32,100,97,110,115,32,108,101,32,71,45,66,117,102,102,101,114,41,10,9,9,35,105,102,32,65,76,80,72,65,95,77,65,80,80,73,78,71,10,9,100,105,102,102,117,115,101,67,111,108,111,114,46,97,32,42,61,32,116,101,120,116,117,114,101,40,77,97,116,101,114,105,97,108,65,108,112,104,97,77,97,112,44,32,116,101,120,67,111,111,114,100,41,46,114,59,10,9,9,35,101,110,100,105,102,10,9,9,10,9,105,102,32,40,100,105,102,102,117,115,101,67,111,108,111,114,46,97,32,60,32,77,97,116,101,114,105,97,108,65,108,112,104,97,84,104,114,101,115,104,111,108,100,41,10,9,9,100,105,115,99,97,114,100,59,10,9,35,101,110,100,105,102,32,47,47,32,65,76,80,72,65,95,84,69,83,84,10,10,9,35,105,102,32,76,73,71,72,84,73,78,71,10,9,9,35,105,102,32,78,79,82,77,65,76,95,77,65,80,80,73,78,71,10,9,118,101,99,51,32,110,111,114,109,97,108,32,61,32,110,111,114,109,97,108,105,122,101,40,118,76,105,103,104,116,84,111,87,111,114,108,100,32,42,32,40,50,46,48,32,42,32,118,101,99,51,40,116,101,120,116,117,114,101,40,77,97,116,101,114,105,97,108,78,111,114,109,97,108,77,97,112,44,32,116,101,120,67,111,111,114,100,41,41,32,45,32,49,46,48,41,41,59,10,9,9,35,101,108,115,101,10,9,118,101,99,51,32,110,111,114,109,97,108,32,61,32,110,111,114,109,97,108,105,122,101,40,118,78,111,114,109,97,108,41,59,10,9,9,35,101,110,100,105,102,32,47,47,32,78,79,82,77,65,76,95,77,65,80,80,73,78,71,10,10,9,118,101,99,51,32,115,112,101,99,117,108,97,114,67,111,108,111,114,32,61,32,77,97,116,101,114,105,97,108,83,112,101,99,117,108,97,114,46,114,103,98,59,10,9,9,35,105,102,32,83,80,69,67,85,76,65,82,95,77,65,80,80,73,78,71,10,9,115,112,101,99,117,108,97,114,67,111,108,111,114,32,42,61,32,116,101,120,116,117,114,101,40,77,97,116,101,114,105,97,108,83,112,101,99,117,108,97,114,77,97,112,44,32,116,101,120,67,111,111,114,100,41,46,114,103,98,59,10,9,9,35,101,110,100,105,102,10,10,9,47,42,10,9,84,101,120,116,117,114,101,48,58,32,68,105,102,102,117,115,101,32,67,111,108,111,114,32,43,32,83,112,101,99,117,108,97,114,10,9,84,101,120,116,117,114,101,49,58,32,78,111,114,109,97,108,32,43,32,83,112,101,99,117,108,97,114,10,9,84,101,120,116,117,114,101,50,58,32,69,110,99,111,100,101,100,32,100,101,112,116,104,32,43,32,83,104,105,110,105,110,101,115,115,10,9,42,47,10,9,82,101,110,100,101,114,84,97,114,103,101,116,48,32,61,32,118,101,99,52,40,100,105,102,102,117,115,101,67,111,108,111,114,46,114,103,98,44,32,100,111,116,40,115,112,101,99,117,108,97,114,67,111,108,111,114,44,32,118,101,99,51,40,48,46,51,44,32,48,46,53,57,44,32,48,46,49,49,41,41,41,59,10,9,82,101,110,100,101,114,84,97,114,103,101,116,49,32,61,32,118,101,99,52,40,69,110,99,111,100,101,78,111,114,109,97,108,40,110,111,114,109,97,108,41,41,59,10,9,82,101,110,100,101,114,84,97,114,103,101,116,50,32,61,32,118,101,99,52,40,70,108,111,97,116,84,111,67,111,108,111,114,40,103,108,95,70,114,97,103,67,111,111,114,100,46,122,41,44,32,40,77,97,116,101,114,105,97,108,83,104,105,110,105,110,101,115,115,32,61,61,32,48,46,48,41,32,63,32,48,46,48,32,58,32,109,97,120,40,108,111,103,50,40,77,97,116,101,114,105,97,108,83,104,105,110,105,110,101,115,115,41,44,32,48,46,49,41,47,49,48,46,53,41,59,32,47,47,32,104,116,116,112,58,47,47,119,119,119,46,103,117,101,114,114,105,108,108,97,45,103,97,109,101,115,46,99,111,109,47,112,117,98,108,105,99,97,116,105,111,110,115,47,100,114,95,107,122,50,95,114,115,120,95,100,101,118,48,55,46,112,100,102,10,9,35,101,108,115,101,32,47,47,32,76,73,71,72,84,73,78,71,10,9,82,101,110,100,101,114,84,97,114,103,101,116,48,32,61,32,118,101,99,52,40,100,105,102,102,117,115,101,67,111,108,111,114,46,114,103,98,44,32,48,46,48,41,59,10,9,35,101,110,100,105,102,10,35,101,108,115,101,32,47,47,32,70,76,65,71,95,68,69,70,69,82,82,69,68,10,9,35,105,102,32,65,76,80,72,65,95,77,65,80,80,73,78,71,10,9,100,105,102,102,117,115,101,67,111,108,111,114,46,97,32,42,61,32,116,101,120,116,117,114,101,40,77,97,116,101,114,105,97,108,65,108,112,104,97,77,97,112,44,32,116,101,120,67,111,111,114,100,41,46,114,59,10,9,35,101,110,100,105,102,10,10,9,35,105,102,32,65,76,80,72,65,95,84,69,83,84,10,9,105,102,32,40,100,105,102,102,117,115,101,67,111,108,111,114,46,97,32,60,32,77,97,116,101,114,105,97,108,65,108,112,104,97,84,104,114,101,115,104,111,108,100,41,10,9,9,100,105,115,99,97,114,100,59,10,9,35,101,110,100,105,102,10,10,9,35,105,102,32,76,73,71,72,84,73,78,71,10,9,118,101,99,51,32,108,105,103,104,116,65,109,98,105,101,110,116,32,61,32,118,101,99,51,40,48,46,48,41,59,10,9,118,101,99,51,32,108,105,103,104,116,68,105,102,102,117,115,101,32,61,32,118,101,99,51,40,48,46,48,41,59,10,9,118,101,99,51,32,108,105,103,104,116,83,112,101,99,117,108,97,114,32,61,32,118,101,99,51,40,48,46,48,41,59,10,10,9,9,35,105,102,32,78,79,82,77,65,76,95,77,65,80,80,73,78,71,10,9,118,101,99,51,32,110,111,114,109,97,108,32,61,32,110,111,114,109,97,108,105,122,101,40,118,76,105,103,104,116,84,111,87,111,114,108,100,32,42,32,40,50,46,48,32,42,32,118,101,99,51,40,116,101,120,116,117,114,101,40,77,97,116,101,114,105,97,108,78,111,114,109,97,108,77,97,112,44,32,116,101,120,67,111,111,114,100,41,41,32,45,32,49,46,48,41,41,59,10,9,9,35,101,108,115,101,10,9,118,101,99,51,32,110,111,114,109,97,108,32,61,32,110,111,114,109,97,108,105,122,101,40,118,78,111,114,109,97,108,41,59,10,9,9,35,101,110,100,105,102,10,10,9,105,102,32,40,77,97,116,101,114,105,97,108,83,104,105,110,105,110,101,115,115,32,62,32,48,46,48,41,10,9,123,10,9,9,118,101,99,51,32,101,121,101,86,101,99,32,61,32,110,111,114,109,97,108,105,122,101,40,69,121,101,80,111,115,105,116,105,111,110,32,45,32,118,87,111,114,108,100,80,111,115,41,59,10,10,9,9,102,111,114,32,40,105,110,116,32,105,32,61,32,48,59,32,105,32,60,32,51,59,32,43,43,105,41,10,9,9,123,10,9,9,9,118,101,99,52,32,108,105,103,104,116,67,111,108,111,114,32,61,32,76,105,103,104,116,115,91,105,93,46,99,111,108,111,114,59,10,9,9,9,102,108,111,97,116,32,108,105,103,104,116,65,109,98,105,101,110,116,70,97,99,116,111,114,32,61,32,76,105,103,104,116,115,91,105,93,46,102,97,99,116,111,114,115,46,120,59,10,9,9,9,102,108,111,97,116,32,108,105,103,104,116,68,105,102,102,117,115,101,70,97,99,116,111,114,32,61,32,76,105,103,104,116,115,91,105,93,46,102,97,99,116,111,114,115,46,121,59,10,10,9,9,9,115,119,105,116,99,104,32,40,76,105,103,104,116,115,91,105,93,46,116,121,112,101,41,10,9,9,9,123,10,9,9,9,9,99,97,115,101,32,76,73,71,72,84,95,68,73,82,69,67,84,73,79,78,65,76,58,10,9,9,9,9,123,10,9,9,9,9,9,118,101,99,51,32,108,105,103,104,116,68,105,114,32,61,32,45,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,49,46,120,121,122,59,10,10,9,9,9,9,9,47,47,32,65,109,98,105,101,110,116,10,9,9,9,9,9,108,105,103,104,116,65,109,98,105,101,110,116,32,43,61,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,32,42,32,108,105,103,104,116,65,109,98,105,101,110,116,70,97,99,116,111,114,32,42,32,40,77,97,116,101,114,105,97,108,65,109,98,105,101,110,116,46,114,103,98,32,43,32,83,99,101,110,101,65,109,98,105,101,110,116,46,114,103,98,41,59,10,10,9,9,9,9,9,102,108,111,97,116,32,97,116,116,32,61,32,49,46,48,59,10,10,9,9,9,9,9,35,105,102,32,83,72,65,68,79,87,95,77,65,80,80,73,78,71,10,9,9,9,9,9,105,102,32,40,76,105,103,104,116,115,91,105,93,46,115,104,97,100,111,119,77,97,112,112,105,110,103,41,10,9,9,9,9,9,123,10,9,9,9,9,9,9,102,108,111,97,116,32,115,104,97,100,111,119,70,97,99,116,111,114,32,61,32,67,97,108,99,117,108,97,116,101,68,105,114,101,99,116,105,111,110,97,108,83,104,97,100,111,119,70,97,99,116,111,114,40,105,41,59,10,9,9,9,9,9,9,105,102,32,40,115,104,97,100,111,119,70,97,99,116,111,114,32,61,61,32,48,46,48,41,10,9,9,9,9,9,9,9,98,114,101,97,107,59,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,97,116,116,32,42,61,32,115,104,97,100,111,119,70,97,99,116,111,114,59,10,9,9,9,9,9,125,10,9,9,9,9,9,35,101,110,100,105,102,10,10,9,9,9,9,9,47,47,32,68,105,102,102,117,115,101,10,9,9,9,9,9,102,108,111,97,116,32,108,97,109,98,101,114,116,32,61,32,109,97,120,40,100,111,116,40,110,111,114,109,97,108,44,32,108,105,103,104,116,68,105,114,41,44,32,48,46,48,41,59,10,10,9,9,9,9,9,108,105,103,104,116,68,105,102,102,117,115,101,32,43,61,32,97,116,116,32,42,32,108,97,109,98,101,114,116,32,42,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,32,42,32,108,105,103,104,116,68,105,102,102,117,115,101,70,97,99,116,111,114,59,10,10,9,9,9,9,9,47,47,32,83,112,101,99,117,108,97,114,10,9,9,9,9,9,118,101,99,51,32,114,101,102,108,101,99,116,105,111,110,32,61,32,114,101,102,108,101,99,116,40,45,108,105,103,104,116,68,105,114,44,32,110,111,114,109,97,108,41,59,10,9,9,9,9,9,102,108,111,97,116,32,115,112,101,99,117,108,97,114,70,97,99,116,111,114,32,61,32,109,97,120,40,100,111,116,40,114,101,102,108,101,99,116,105,111,110,44,32,101,121,101,86,101,99,41,44,32,48,46,48,41,59,10,9,9,9,9,9,115,112,101,99,117,108,97,114,70,97,99,116,111,114,32,61,32,112,111,119,40,115,112,101,99,117,108,97,114,70,97,99,116,111,114,44,32,77,97,116,101,114,105,97,108,83,104,105,110,105,110,101,115,115,41,59,10,10,9,9,9,9,9,108,105,103,104,116,83,112,101,99,117,108,97,114,32,43,61,32,97,116,116,32,42,32,115,112,101,99,117,108,97,114,70,97,99,116,111,114,32,42,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,59,10,9,9,9,9,9,98,114,101,97,107,59,10,9,9,9,9,125,10,10,9,9,9,9,99,97,115,101,32,76,73,71,72,84,95,80,79,73,78,84,58,10,9,9,9,9,123,10,9,9,9,9,9,118,101,99,51,32,108,105,103,104,116,80,111,115,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,49,46,120,121,122,59,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,65,116,116,101,110,117,97,116,105,111,110,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,49,46,119,59,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,73,110,118,82,97,100,105,117,115,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,50,46,119,59,10,9,9,9,9,9,10,9,9,9,9,9,118,101,99,51,32,119,111,114,108,100,84,111,76,105,103,104,116,32,61,32,108,105,103,104,116,80,111,115,32,45,32,118,87,111,114,108,100,80,111,115,59,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,68,105,114,76,101,110,103,116,104,32,61,32,108,101,110,103,116,104,40,119,111,114,108,100,84,111,76,105,103,104,116,41,59,10,9,9,9,9,9,118,101,99,51,32,108,105,103,104,116,68,105,114,32,61,32,119,111,114,108,100,84,111,76,105,103,104,116,32,47,32,108,105,103,104,116,68,105,114,76,101,110,103,116,104,59,32,47,47,32,78,111,114,109,97,108,105,115,97,116,105,111,110,10,9,9,9,9,9,10,9,9,9,9,9,102,108,111,97,116,32,97,116,116,32,61,32,109,97,120,40,108,105,103,104,116,65,116,116,101,110,117,97,116,105,111,110,32,45,32,108,105,103,104,116,73,110,118,82,97,100,105,117,115,32,42,32,108,105,103,104,116,68,105,114,76,101,110,103,116,104,44,32,48,46,48,41,59,10,10,9,9,9,9,9,47,47,32,65,109,98,105,101,110,116,10,9,9,9,9,9,108,105,103,104,116,65,109,98,105,101,110,116,32,43,61,32,97,116,116,32,42,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,32,42,32,108,105,103,104,116,65,109,98,105,101,110,116,70,97,99,116,111,114,32,42,32,40,77,97,116,101,114,105,97,108,65,109,98,105,101,110,116,46,114,103,98,32,43,32,83,99,101,110,101,65,109,98,105,101,110,116,46,114,103,98,41,59,10,10,9,9,9,9,9,35,105,102,32,83,72,65,68,79,87,95,77,65,80,80,73,78,71,10,9,9,9,9,9,105,102,32,40,76,105,103,104,116,115,91,105,93,46,115,104,97,100,111,119,77,97,112,112,105,110,103,41,10,9,9,9,9,9,123,10,9,9,9,9,9,9,102,108,111,97,116,32,115,104,97,100,111,119,70,97,99,116,111,114,32,61,32,67,97,108,99,117,108,97,116,101,80,111,105,110,116,83,104,97,100,111,119,70,97,99,116,111,114,40,105,44,32,118,87,111,114,108,100,80,111,115,32,45,32,108,105,103,104,116,80,111,115,44,32,48,46,49,44,32,53,48,46,48,41,59,10,9,9,9,9,9,9,105,102,32,40,115,104,97,100,111,119,70,97,99,116,111,114,32,61,61,32,48,46,48,41,10,9,9,9,9,9,9,9,98,114,101,97,107,59,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,97,116,116,32,42,61,32,115,104,97,100,111,119,70,97,99,116,111,114,59,10,9,9,9,9,9,125,10,9,9,9,9,9,35,101,110,100,105,102,10,10,9,9,9,9,9,47,47,32,68,105,102,102,117,115,101,10,9,9,9,9,9,102,108,111,97,116,32,108,97,109,98,101,114,116,32,61,32,109,97,120,40,100,111,116,40,110,111,114,109,97,108,44,32,108,105,103,104,116,68,105,114,41,44,32,48,46,48,41,59,10,9,9,9,9,9,10,9,9,9,9,9,108,105,103,104,116,68,105,102,102,117,115,101,32,43,61,32,97,116,116,32,42,32,108,97,109,98,101,114,116,32,42,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,32,42,32,108,105,103,104,116,68,105,102,102,117,115,101,70,97,99,116,111,114,59,10,10,9,9,9,9,9,47,47,32,83,112,101,99,117,108,97,114,10,9,9,9,9,9,118,101,99,51,32,114,101,102,108,101,99,116,105,111,110,32,61,32,114,101,102,108,101,99,116,40,45,108,105,103,104,116,68,105,114,44,32,110,111,114,109,97,108,41,59,10,9,9,9,9,9,102,108,111,97,116,32,115,112,101,99,117,108,97,114,70,97,99,116,111,114,32,61,32,109,97,120,40,100,111,116,40,114,101,102,108,101,99,116,105,111,110,44,32,101,121,101,86,101,99,41,44,32,48,46,48,41,59,10,9,9,9,9,9,115,112,101,99,117,108,97,114,70,97,99,116,111,114,32,61,32,112,111,119,40,115,112,101,99,117,108,97,114,70,97,99,116,111,114,44,32,77,97,116,101,114,105,97,108,83,104,105,110,105,110,101,115,115,41,59,10,10,9,9,9,9,9,108,105,103,104,116,83,112,101,99,117,108,97,114,32,43,61,32,97,116,116,32,42,32,115,112,101,99,117,108,97,114,70,97,99,116,111,114,32,42,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,59,10,9,9,9,9,9,98,114,101,97,107,59,10,9,9,9,9,125,10,10,9,9,9,9,99,97,115,101,32,76,73,71,72,84,95,83,80,79,84,58,10,9,9,9,9,123,10,9,9,9,9,9,118,101,99,51,32,108,105,103,104,116,80,111,115,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,49,46,120,121,122,59,10,9,9,9,9,9,118,101,99,51,32,108,105,103,104,116,68,105,114,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,50,46,120,121,122,59,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,65,116,116,101,110,117,97,116,105,111,110,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,49,46,119,59,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,73,110,118,82,97,100,105,117,115,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,50,46,119,59,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,73,110,110,101,114,65,110,103,108,101,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,51,46,120,59,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,79,117,116,101,114,65,110,103,108,101,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,51,46,121,59,10,10,9,9,9,9,9,118,101,99,51,32,119,111,114,108,100,84,111,76,105,103,104,116,32,61,32,108,105,103,104,116,80,111,115,32,45,32,118,87,111,114,108,100,80,111,115,59,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,68,105,115,116,97,110,99,101,32,61,32,108,101,110,103,116,104,40,119,111,114,108,100,84,111,76,105,103,104,116,41,59,10,9,9,9,9,9,119,111,114,108,100,84,111,76,105,103,104,116,32,47,61,32,108,105,103,104,116,68,105,115,116,97,110,99,101,59,32,47,47,32,78,111,114,109,97,108,105,115,97,116,105,111,110,10,9,9,9,9,9,10,9,9,9,9,9,102,108,111,97,116,32,97,116,116,32,61,32,109,97,120,40,108,105,103,104,116,65,116,116,101,110,117,97,116,105,111,110,32,45,32,108,105,103,104,116,73,110,118,82,97,100,105,117,115,32,42,32,108,105,103,104,116,68,105,115,116,97,110,99,101,44,32,48,46,48,41,59,10,10,9,9,9,9,9,47,47,32,65,109,98,105,101,110,116,10,9,9,9,9,9,108,105,103,104,116,65,109,98,105,101,110,116,32,43,61,32,97,116,116,32,42,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,32,42,32,108,105,103,104,116,65,109,98,105,101,110,116,70,97,99,116,111,114,32,42,32,40,77,97,116,101,114,105,97,108,65,109,98,105,101,110,116,46,114,103,98,32,43,32,83,99,101,110,101,65,109,98,105,101,110,116,46,114,103,98,41,59,10,10,9,9,9,9,9,35,105,102,32,83,72,65,68,79,87,95,77,65,80,80,73,78,71,10,9,9,9,9,9,105,102,32,40,76,105,103,104,116,115,91,105,93,46,115,104,97,100,111,119,77,97,112,112,105,110,103,41,10,9,9,9,9,9,123,10,9,9,9,9,9,9,102,108,111,97,116,32,115,104,97,100,111,119,70,97,99,116,111,114,32,61,32,67,97,108,99,117,108,97,116,101,83,112,111,116,83,104,97,100,111,119,70,97,99,116,111,114,40,105,41,59,10,9,9,9,9,9,9,105,102,32,40,115,104,97,100,111,119,70,97,99,116,111,114,32,61,61,32,48,46,48,41,10,9,9,9,9,9,9,9,98,114,101,97,107,59,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,97,116,116,32,42,61,32,115,104,97,100,111,119,70,97,99,116,111,114,59,10,9,9,9,9,9,125,10,9,9,9,9,9,35,101,110,100,105,102,10,10,9,9,9,9,9,47,47,32,77,111,100,105,102,105,99,97,116,105,111,110,32,100,101,32,108,39,97,116,116,195,169,110,117,97,116,105,111,110,32,112,111,117,114,32,103,195,169,114,101,114,32,108,101,32,115,112,111,116,10,9,9,9,9,9,102,108,111,97,116,32,99,117,114,65,110,103,108,101,32,61,32,100,111,116,40,108,105,103,104,116,68,105,114,44,32,45,119,111,114,108,100,84,111,76,105,103,104,116,41,59,10,9,9,9,9,9,102,108,111,97,116,32,105,110,110,101,114,77,105,110,117,115,79,117,116,101,114,65,110,103,108,101,32,61,32,108,105,103,104,116,73,110,110,101,114,65,110,103,108,101,32,45,32,108,105,103,104,116,79,117,116,101,114,65,110,103,108,101,59,10,9,9,9,9,9,97,116,116,32,42,61,32,109,97,120,40,40,99,117,114,65,110,103,108,101,32,45,32,108,105,103,104,116,79,117,116,101,114,65,110,103,108,101,41,32,47,32,105,110,110,101,114,77,105,110,117,115,79,117,116,101,114,65,110,103,108,101,44,32,48,46,48,41,59,10,10,9,9,9,9,9,47,47,32,68,105,102,102,117,115,101,10,9,9,9,9,9,102,108,111,97,116,32,108,97,109,98,101,114,116,32,61,32,109,97,120,40,100,111,116,40,110,111,114,109,97,108,44,32,119,111,114,108,100,84,111,76,105,103,104,116,41,44,32,48,46,48,41,59,10,10,9,9,9,9,9,108,105,103,104,116,68,105,102,102,117,115,101,32,43,61,32,97,116,116,32,42,32,108,97,109,98,101,114,116,32,42,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,32,42,32,108,105,103,104,116,68,105,102,102,117,115,101,70,97,99,116,111,114,59,10,10,9,9,9,9,9,47,47,32,83,112,101,99,117,108,97,114,10,9,9,9,9,9,118,101,99,51,32,114,101,102,108,101,99,116,105,111,110,32,61,32,114,101,102,108,101,99,116,40,45,119,111,114,108,100,84,111,76,105,103,104,116,44,32,110,111,114,109,97,108,41,59,10,9,9,9,9,9,102,108,111,97,116,32,115,112,101,99,117,108,97,114,70,97,99,116,111,114,32,61,32,109,97,120,40,100,111,116,40,114,101,102,108,101,99,116,105,111,110,44,32,101,121,101,86,101,99,41,44,32,48,46,48,41,59,10,9,9,9,9,9,115,112,101,99,117,108,97,114,70,97,99,116,111,114,32,61,32,112,111,119,40,115,112,101,99,117,108,97,114,70,97,99,116,111,114,44,32,77,97,116,101,114,105,97,108,83,104,105,110,105,110,101,115,115,41,59,10,10,9,9,9,9,9,108,105,103,104,116,83,112,101,99,117,108,97,114,32,43,61,32,97,116,116,32,42,32,115,112,101,99,117,108,97,114,70,97,99,116,111,114,32,42,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,59,10,9,9,9,9,9,98,114,101,97,107,59,10,9,9,9,9,125,10,9,9,9,9,10,9,9,9,9,100,101,102,97,117,108,116,58,10,9,9,9,9,9,98,114,101,97,107,59,10,9,9,9,125,10,9,9,125,10,9,125,10,9,101,108,115,101,10,9,123,10,9,9,102,111,114,32,40,105,110,116,32,105,32,61,32,48,59,32,105,32,60,32,51,59,32,43,43,105,41,10,9,9,123,10,9,9,9,118,101,99,52,32,108,105,103,104,116,67,111,108,111,114,32,61,32,76,105,103,104,116,115,91,105,93,46,99,111,108,111,114,59,10,9,9,9,102,108,111,97,116,32,108,105,103,104,116,65,109,98,105,101,110,116,70,97,99,116,111,114,32,61,32,76,105,103,104,116,115,91,105,93,46,102,97,99,116,111,114,115,46,120,59,10,9,9,9,102,108,111,97,116,32,108,105,103,104,116,68,105,102,102,117,115,101,70,97,99,116,111,114,32,61,32,76,105,103,104,116,115,91,105,93,46,102,97,99,116,111,114,115,46,121,59,10,10,9,9,9,115,119,105,116,99,104,32,40,76,105,103,104,116,115,91,105,93,46,116,121,112,101,41,10,9,9,9,123,10,9,9,9,9,99,97,115,101,32,76,73,71,72,84,95,68,73,82,69,67,84,73,79,78,65,76,58,10,9,9,9,9,123,10,9,9,9,9,9,118,101,99,51,32,108,105,103,104,116,68,105,114,32,61,32,45,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,49,46,120,121,122,59,10,10,9,9,9,9,9,47,47,32,65,109,98,105,101,110,116,10,9,9,9,9,9,108,105,103,104,116,65,109,98,105,101,110,116,32,43,61,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,32,42,32,108,105,103,104,116,65,109,98,105,101,110,116,70,97,99,116,111,114,32,42,32,40,77,97,116,101,114,105,97,108,65,109,98,105,101,110,116,46,114,103,98,32,43,32,83,99,101,110,101,65,109,98,105,101,110,116,46,114,103,98,41,59,10,10,9,9,9,9,9,102,108,111,97,116,32,97,116,116,32,61,32,49,46,48,59,10,10,9,9,9,9,9,35,105,102,32,83,72,65,68,79,87,95,77,65,80,80,73,78,71,10,9,9,9,9,9,105,102,32,40,76,105,103,104,116,115,91,105,93,46,115,104,97,100,111,119,77,97,112,112,105,110,103,41,10,9,9,9,9,9,123,10,9,9,9,9,9,9,102,108,111,97,116,32,115,104,97,100,111,119,70,97,99,116,111,114,32,61,32,67,97,108,99,117,108,97,116,101,68,105,114,101,99,116,105,111,110,97,108,83,104,97,100,111,119,70,97,99,116,111,114,40,105,41,59,10,9,9,9,9,9,9,105,102,32,40,115,104,97,100,111,119,70,97,99,116,111,114,32,61,61,32,48,46,48,41,10,9,9,9,9,9,9,9,98,114,101,97,107,59,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,97,116,116,32,42,61,32,115,104,97,100,111,119,70,97,99,116,111,114,59,10,9,9,9,9,9,125,10,9,9,9,9,9,35,101,110,100,105,102,10,10,9,9,9,9,9,47,47,32,68,105,102,102,117,115,101,10,9,9,9,9,9,102,108,111,97,116,32,108,97,109,98,101,114,116,32,61,32,109,97,120,40,100,111,116,40,110,111,114,109,97,108,44,32,108,105,103,104,116,68,105,114,41,44,32,48,46,48,41,59,10,10,9,9,9,9,9,108,105,103,104,116,68,105,102,102,117,115,101,32,43,61,32,97,116,116,32,42,32,108,97,109,98,101,114,116,32,42,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,32,42,32,108,105,103,104,116,68,105,102,102,117,115,101,70,97,99,116,111,114,59,10,9,9,9,9,9,98,114,101,97,107,59,10,9,9,9,9,125,10,10,9,9,9,9,99,97,115,101,32,76,73,71,72,84,95,80,79,73,78,84,58,10,9,9,9,9,123,10,9,9,9,9,9,118,101,99,51,32,108,105,103,104,116,80,111,115,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,49,46,120,121,122,59,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,65,116,116,101,110,117,97,116,105,111,110,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,49,46,119,59,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,73,110,118,82,97,100,105,117,115,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,50,46,119,59,10,9,9,9,9,9,10,9,9,9,9,9,118,101,99,51,32,119,111,114,108,100,84,111,76,105,103,104,116,32,61,32,108,105,103,104,116,80,111,115,32,45,32,118,87,111,114,108,100,80,111,115,59,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,68,105,114,76,101,110,103,116,104,32,61,32,108,101,110,103,116,104,40,119,111,114,108,100,84,111,76,105,103,104,116,41,59,10,9,9,9,9,9,118,101,99,51,32,108,105,103,104,116,68,105,114,32,61,32,119,111,114,108,100,84,111,76,105,103,104,116,32,47,32,108,105,103,104,116,68,105,114,76,101,110,103,116,104,59,32,47,47,32,78,111,114,109,97,108,105,115,97,116,105,111,110,10,9,9,9,9,9,10,9,9,9,9,9,102,108,111,97,116,32,97,116,116,32,61,32,109,97,120,40,108,105,103,104,116,65,116,116,101,110,117,97,116,105,111,110,32,45,32,108,105,103,104,116,73,110,118,82,97,100,105,117,115,32,42,32,108,105,103,104,116,68,105,114,76,101,110,103,116,104,44,32,48,46,48,41,59,10,10,9,9,9,9,9,47,47,32,65,109,98,105,101,110,116,10,9,9,9,9,9,108,105,103,104,116,65,109,98,105,101,110,116,32,43,61,32,97,116,116,32,42,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,32,42,32,108,105,103,104,116,65,109,98,105,101,110,116,70,97,99,116,111,114,32,42,32,40,77,97,116,101,114,105,97,108,65,109,98,105,101,110,116,46,114,103,98,32,43,32,83,99,101,110,101,65,109,98,105,101,110,116,46,114,103,98,41,59,10,10,9,9,9,9,9,35,105,102,32,83,72,65,68,79,87,95,77,65,80,80,73,78,71,10,9,9,9,9,9,105,102,32,40,76,105,103,104,116,115,91,105,93,46,115,104,97,100,111,119,77,97,112,112,105,110,103,41,10,9,9,9,9,9,123,10,9,9,9,9,9,9,102,108,111,97,116,32,115,104,97,100,111,119,70,97,99,116,111,114,32,61,32,67,97,108,99,117,108,97,116,101,80,111,105,110,116,83,104,97,100,111,119,70,97,99,116,111,114,40,105,44,32,118,87,111,114,108,100,80,111,115,32,45,32,108,105,103,104,116,80,111,115,44,32,48,46,49,44,32,53,48,46,48,41,59,10,9,9,9,9,9,9,105,102,32,40,115,104,97,100,111,119,70,97,99,116,111,114,32,61,61,32,48,46,48,41,10,9,9,9,9,9,9,9,98,114,101,97,107,59,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,97,116,116,32,42,61,32,115,104,97,100,111,119,70,97,99,116,111,114,59,10,9,9,9,9,9,125,10,9,9,9,9,9,35,101,110,100,105,102,10,10,9,9,9,9,9,47,47,32,68,105,102,102,117,115,101,10,9,9,9,9,9,102,108,111,97,116,32,108,97,109,98,101,114,116,32,61,32,109,97,120,40,100,111,116,40,110,111,114,109,97,108,44,32,108,105,103,104,116,68,105,114,41,44,32,48,46,48,41,59,10,9,9,9,9,9,10,9,9,9,9,9,108,105,103,104,116,68,105,102,102,117,115,101,32,43,61,32,97,116,116,32,42,32,108,97,109,98,101,114,116,32,42,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,32,42,32,108,105,103,104,116,68,105,102,102,117,115,101,70,97,99,116,111,114,59,10,9,9,9,9,9,98,114,101,97,107,59,10,9,9,9,9,125,10,10,9,9,9,9,99,97,115,101,32,76,73,71,72,84,95,83,80,79,84,58,10,9,9,9,9,123,10,9,9,9,9,9,118,101,99,51,32,108,105,103,104,116,80,111,115,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,49,46,120,121,122,59,10,9,9,9,9,9,118,101,99,51,32,108,105,103,104,116,68,105,114,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,50,46,120,121,122,59,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,65,116,116,101,110,117,97,116,105,111,110,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,49,46,119,59,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,73,110,118,82,97,100,105,117,115,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,50,46,119,59,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,73,110,110,101,114,65,110,103,108,101,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,51,46,120,59,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,79,117,116,101,114,65,110,103,108,101,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,51,46,121,59,10,10,9,9,9,9,9,118,101,99,51,32,119,111,114,108,100,84,111,76,105,103,104,116,32,61,32,108,105,103,104,116,80,111,115,32,45,32,118,87,111,114,108,100,80,111,115,59,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,68,105,115,116,97,110,99,101,32,61,32,108,101,110,103,116,104,40,119,111,114,108,100,84,111,76,105,103,104,116,41,59,10,9,9,9,9,9,119,111,114,108,100,84,111,76,105,103,104,116,32,47,61,32,108,105,103,104,116,68,105,115,116,97,110,99,101,59,32,47,47,32,78,111,114,109,97,108,105,115,97,116,105,111,110,10,9,9,9,9,9,10,9,9,9,9,9,102,108,111,97,116,32,97,116,116,32,61,32,109,97,120,40,108,105,103,104,116,65,116,116,101,110,117,97,116,105,111,110,32,45,32,108,105,103,104,116,73,110,118,82,97,100,105,117,115,32,42,32,108,105,103,104,116,68,105,115,116,97,110,99,101,44,32,48,46,48,41,59,10,10,9,9,9,9,9,47,47,32,65,109,98,105,101,110,116,10,9,9,9,9,9,108,105,103,104,116,65,109,98,105,101,110,116,32,43,61,32,97,116,116,32,42,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,32,42,32,108,105,103,104,116,65,109,98,105,101,110,116,70,97,99,116,111,114,32,42,32,40,77,97,116,101,114,105,97,108,65,109,98,105,101,110,116,46,114,103,98,32,43,32,83,99,101,110,101,65,109,98,105,101,110,116,46,114,103,98,41,59,10,10,9,9,9,9,9,35,105,102,32,83,72,65,68,79,87,95,77,65,80,80,73,78,71,10,9,9,9,9,9,105,102,32,40,76,105,103,104,116,115,91,105,93,46,115,104,97,100,111,119,77,97,112,112,105,110,103,41,10,9,9,9,9,9,123,10,9,9,9,9,9,9,102,108,111,97,116,32,115,104,97,100,111,119,70,97,99,116,111,114,32,61,32,67,97,108,99,117,108,97,116,101,83,112,111,116,83,104,97,100,111,119,70,97,99,116,111,114,40,105,41,59,10,9,9,9,9,9,9,105,102,32,40,115,104,97,100,111,119,70,97,99,116,111,114,32,61,61,32,48,46,48,41,10,9,9,9,9,9,9,9,98,114,101,97,107,59,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,97,116,116,32,42,61,32,115,104,97,100,111,119,70,97,99,116,111,114,59,10,9,9,9,9,9,125,10,9,9,9,9,9,35,101,110,100,105,102,10,10,9,9,9,9,9,47,47,32,77,111,100,105,102,105,99,97,116,105,111,110,32,100,101,32,108,39,97,116,116,195,169,110,117,97,116,105,111,110,32,112,111,117,114,32,103,195,169,114,101,114,32,108,101,32,115,112,111,116,10,9,9,9,9,9,102,108,111,97,116,32,99,117,114,65,110,103,108,101,32,61,32,100,111,116,40,108,105,103,104,116,68,105,114,44,32,45,119,111,114,108,100,84,111,76,105,103,104,116,41,59,10,9,9,9,9,9,102,108,111,97,116,32,105,110,110,101,114,77,105,110,117,115,79,117,116,101,114,65,110,103,108,101,32,61,32,108,105,103,104,116,73,110,110,101,114,65,110,103,108,101,32,45,32,108,105,103,104,116,79,117,116,101,114,65,110,103,108,101,59,10,9,9,9,9,9,97,116,116,32,42,61,32,109,97,120,40,40,99,117,114,65,110,103,108,101,32,45,32,108,105,103,104,116,79,117,116,101,114,65,110,103,108,101,41,32,47,32,105,110,110,101,114,77,105,110,117,115,79,117,116,101,114,65,110,103,108,101,44,32,48,46,48,41,59,10,10,9,9,9,9,9,47,47,32,68,105,102,102,117,115,101,10,9,9,9,9,9,102,108,111,97,116,32,108,97,109,98,101,114,116,32,61,32,109,97,120,40,100,111,116,40,110,111,114,109,97,108,44,32,119,111,114,108,100,84,111,76,105,103,104,116,41,44,32,48,46,48,41,59,10,10,9,9,9,9,9,108,105,103,104,116,68,105,102,102,117,115,101,32,43,61,32,97,116,116,32,42,32,108,97,109,98,101,114,116,32,42,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,32,42,32,108,105,103,104,116,68,105,102,102,117,115,101,70,97,99,116,111,114,59,10,9,9,9,9,125,10,9,9,9,9,10,9,9,9,9,100,101,102,97,117,108,116,58,10,9,9,9,9,9,98,114,101,97,107,59,10,9,9,9,125,10,9,9,125,10,9,125,10,9,10,9,108,105,103,104,116,83,112,101,99,117,108,97,114,32,42,61,32,77,97,116,101,114,105,97,108,83,112,101,99,117,108,97,114,46,114,103,98,59,10,9,9,35,105,102,32,83,80,69,67,85,76,65,82,95,77,65,80,80,73,78,71,10,9,108,105,103,104,116,83,112,101,99,117,108,97,114,32,42,61,32,116,101,120,116,117,114,101,40,77,97,116,101,114,105,97,108,83,112,101,99,117,108,97,114,77,97,112,44,32,116,101,120,67,111,111,114,100,41,46,114,103,98,59,32,47,47,32,85,116,105,108,105,115,101,114,32,108,39,97,108,112,104,97,32,100,101,32,77,97,116,101,114,105,97,108,83,112,101,99,117,108,97,114,32,110,39,97,117,114,97,105,116,32,97,117,99,117,110,32,115,101,110,115,10,9,9,35,101,110,100,105,102,10,9,9,10,9,118,101,99,51,32,108,105,103,104,116,67,111,108,111,114,32,61,32,40,108,105,103,104,116,65,109,98,105,101,110,116,32,43,32,108,105,103,104,116,68,105,102,102,117,115,101,32,43,32,108,105,103,104,116,83,112,101,99,117,108,97,114,41,59,10,9,118,101,99,52,32,102,114,97,103,109,101,110,116,67,111,108,111,114,32,61,32,118,101,99,52,40,108,105,103,104,116,67,111,108,111,114,44,32,49,46,48,41,32,42,32,100,105,102,102,117,115,101,67,111,108,111,114,59,10,10,9,9,35,105,102,32,69,77,73,83,83,73,86,69,95,77,65,80,80,73,78,71,10,9,102,108,111,97,116,32,108,105,103,104,116,73,110,116,101,110,115,105,116,121,32,61,32,100,111,116,40,108,105,103,104,116,67,111,108,111,114,44,32,118,101,99,51,40,48,46,51,44,32,48,46,53,57,44,32,48,46,49,49,41,41,59,10,10,9,118,101,99,51,32,101,109,105,115,115,105,111,110,67,111,108,111,114,32,61,32,77,97,116,101,114,105,97,108,68,105,102,102,117,115,101,46,114,103,98,32,42,32,116,101,120,116,117,114,101,40,77,97,116,101,114,105,97,108,69,109,105,115,115,105,118,101,77,97,112,44,32,116,101,120,67,111,111,114,100,41,46,114,103,98,59,10,9,82,101,110,100,101,114,84,97,114,103,101,116,48,32,61,32,118,101,99,52,40,109,105,120,40,102,114,97,103,109,101,110,116,67,111,108,111,114,46,114,103,98,44,32,101,109,105,115,115,105,111,110,67,111,108,111,114,44,32,99,108,97,109,112,40,49,46,48,32,45,32,51,46,48,42,108,105,103,104,116,73,110,116,101,110,115,105,116,121,44,32,48,46,48,44,32,49,46,48,41,41,44,32,102,114,97,103,109,101,110,116,67,111,108,111,114,46,97,41,59,10,9,9,35,101,108,115,101,10,9,82,101,110,100,101,114,84,97,114,103,101,116,48,32,61,32,102,114,97,103,109,101,110,116,67,111,108,111,114,59,10,9,9,35,101,110,100,105,102,32,47,47,32,69,77,73,83,83,73,86,69,95,77,65,80,80,73,78,71,10,9,35,101,108,115,101,10,9,82,101,110,100,101,114,84,97,114,103,101,116,48,32,61,32,100,105,102,102,117,115,101,67,111,108,111,114,59,10,9,35,101,110,100,105,102,32,47,47,32,76,73,71,72,84,73,78,71,10,35,101,110,100,105,102,32,47,47,32,70,76,65,71,95,68,69,70,69,82,82,69,68,10,125,10,10, \ No newline at end of file +35,105,102,32,69,65,82,76,89,95,70,82,65,71,77,69,78,84,95,84,69,83,84,83,32,38,38,32,33,65,76,80,72,65,95,84,69,83,84,10,108,97,121,111,117,116,40,101,97,114,108,121,95,102,114,97,103,109,101,110,116,95,116,101,115,116,115,41,32,105,110,59,10,35,101,110,100,105,102,10,10,35,100,101,102,105,110,101,32,76,73,71,72,84,95,68,73,82,69,67,84,73,79,78,65,76,32,48,10,35,100,101,102,105,110,101,32,76,73,71,72,84,95,80,79,73,78,84,32,49,10,35,100,101,102,105,110,101,32,76,73,71,72,84,95,83,80,79,84,32,50,10,10,47,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,69,110,116,114,97,110,116,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,47,10,105,110,32,118,101,99,52,32,118,67,111,108,111,114,59,10,105,110,32,118,101,99,52,32,118,76,105,103,104,116,83,112,97,99,101,80,111,115,91,51,93,59,10,105,110,32,109,97,116,51,32,118,76,105,103,104,116,84,111,87,111,114,108,100,59,10,105,110,32,118,101,99,51,32,118,78,111,114,109,97,108,59,10,105,110,32,118,101,99,50,32,118,84,101,120,67,111,111,114,100,59,10,105,110,32,118,101,99,51,32,118,86,105,101,119,68,105,114,59,10,105,110,32,118,101,99,51,32,118,87,111,114,108,100,80,111,115,59,10,10,47,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,83,111,114,116,97,110,116,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,47,10,111,117,116,32,118,101,99,52,32,82,101,110,100,101,114,84,97,114,103,101,116,48,59,10,111,117,116,32,118,101,99,52,32,82,101,110,100,101,114,84,97,114,103,101,116,49,59,10,111,117,116,32,118,101,99,52,32,82,101,110,100,101,114,84,97,114,103,101,116,50,59,10,10,47,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,85,110,105,102,111,114,109,101,115,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,47,10,115,116,114,117,99,116,32,76,105,103,104,116,10,123,10,9,105,110,116,32,116,121,112,101,59,10,9,118,101,99,52,32,99,111,108,111,114,59,10,9,118,101,99,50,32,102,97,99,116,111,114,115,59,10,10,9,118,101,99,52,32,112,97,114,97,109,101,116,101,114,115,49,59,10,9,118,101,99,52,32,112,97,114,97,109,101,116,101,114,115,50,59,10,9,118,101,99,50,32,112,97,114,97,109,101,116,101,114,115,51,59,10,9,98,111,111,108,32,115,104,97,100,111,119,77,97,112,112,105,110,103,59,10,125,59,10,10,47,47,32,76,117,109,105,195,168,114,101,115,10,117,110,105,102,111,114,109,32,76,105,103,104,116,32,76,105,103,104,116,115,91,51,93,59,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,67,117,98,101,32,80,111,105,110,116,76,105,103,104,116,83,104,97,100,111,119,77,97,112,91,51,93,59,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,68,105,114,101,99,116,105,111,110,97,108,83,112,111,116,76,105,103,104,116,83,104,97,100,111,119,77,97,112,91,51,93,59,10,10,47,47,32,77,97,116,195,169,114,105,97,117,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,77,97,116,101,114,105,97,108,65,108,112,104,97,77,97,112,59,10,117,110,105,102,111,114,109,32,102,108,111,97,116,32,77,97,116,101,114,105,97,108,65,108,112,104,97,84,104,114,101,115,104,111,108,100,59,10,117,110,105,102,111,114,109,32,118,101,99,52,32,77,97,116,101,114,105,97,108,65,109,98,105,101,110,116,59,10,117,110,105,102,111,114,109,32,118,101,99,52,32,77,97,116,101,114,105,97,108,68,105,102,102,117,115,101,59,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,77,97,116,101,114,105,97,108,68,105,102,102,117,115,101,77,97,112,59,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,77,97,116,101,114,105,97,108,69,109,105,115,115,105,118,101,77,97,112,59,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,77,97,116,101,114,105,97,108,72,101,105,103,104,116,77,97,112,59,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,77,97,116,101,114,105,97,108,78,111,114,109,97,108,77,97,112,59,10,117,110,105,102,111,114,109,32,102,108,111,97,116,32,77,97,116,101,114,105,97,108,83,104,105,110,105,110,101,115,115,59,10,117,110,105,102,111,114,109,32,118,101,99,52,32,77,97,116,101,114,105,97,108,83,112,101,99,117,108,97,114,59,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,77,97,116,101,114,105,97,108,83,112,101,99,117,108,97,114,77,97,112,59,10,10,47,47,32,65,117,116,114,101,115,10,117,110,105,102,111,114,109,32,102,108,111,97,116,32,80,97,114,97,108,108,97,120,66,105,97,115,32,61,32,45,48,46,48,51,59,10,117,110,105,102,111,114,109,32,102,108,111,97,116,32,80,97,114,97,108,108,97,120,83,99,97,108,101,32,61,32,48,46,48,50,59,10,117,110,105,102,111,114,109,32,118,101,99,50,32,73,110,118,84,97,114,103,101,116,83,105,122,101,59,10,117,110,105,102,111,114,109,32,118,101,99,51,32,69,121,101,80,111,115,105,116,105,111,110,59,10,117,110,105,102,111,114,109,32,118,101,99,52,32,83,99,101,110,101,65,109,98,105,101,110,116,59,10,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,84,101,120,116,117,114,101,79,118,101,114,108,97,121,59,10,10,47,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,70,111,110,99,116,105,111,110,115,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,47,10,118,101,99,51,32,70,108,111,97,116,84,111,67,111,108,111,114,40,102,108,111,97,116,32,102,41,10,123,10,9,118,101,99,51,32,99,111,108,111,114,59,10,10,9,102,32,42,61,32,50,53,54,46,48,59,10,9,99,111,108,111,114,46,120,32,61,32,102,108,111,111,114,40,102,41,59,10,10,9,102,32,61,32,40,102,32,45,32,99,111,108,111,114,46,120,41,32,42,32,50,53,54,46,48,59,10,9,99,111,108,111,114,46,121,32,61,32,102,108,111,111,114,40,102,41,59,10,10,9,99,111,108,111,114,46,122,32,61,32,102,32,45,32,99,111,108,111,114,46,121,59,10,9,99,111,108,111,114,46,120,121,32,42,61,32,48,46,48,48,51,57,48,54,50,53,59,32,47,47,32,42,61,32,49,46,48,47,50,53,54,10,10,9,114,101,116,117,114,110,32,99,111,108,111,114,59,10,125,10,10,35,100,101,102,105,110,101,32,107,80,73,32,51,46,49,52,49,53,57,50,54,53,51,54,10,10,118,101,99,52,32,69,110,99,111,100,101,78,111,114,109,97,108,40,105,110,32,118,101,99,51,32,110,111,114,109,97,108,41,10,123,10,9,47,47,114,101,116,117,114,110,32,118,101,99,52,40,110,111,114,109,97,108,42,48,46,53,32,43,32,48,46,53,44,32,48,46,48,41,59,10,9,114,101,116,117,114,110,32,118,101,99,52,40,118,101,99,50,40,97,116,97,110,40,110,111,114,109,97,108,46,121,44,32,110,111,114,109,97,108,46,120,41,47,107,80,73,44,32,110,111,114,109,97,108,46,122,41,44,32,48,46,48,44,32,48,46,48,41,59,10,125,10,10,102,108,111,97,116,32,86,101,99,116,111,114,84,111,68,101,112,116,104,86,97,108,117,101,40,118,101,99,51,32,118,101,99,44,32,102,108,111,97,116,32,122,78,101,97,114,44,32,102,108,111,97,116,32,122,70,97,114,41,10,123,10,9,118,101,99,51,32,97,98,115,86,101,99,32,61,32,97,98,115,40,118,101,99,41,59,10,9,102,108,111,97,116,32,108,111,99,97,108,90,32,61,32,109,97,120,40,97,98,115,86,101,99,46,120,44,32,109,97,120,40,97,98,115,86,101,99,46,121,44,32,97,98,115,86,101,99,46,122,41,41,59,10,10,9,102,108,111,97,116,32,110,111,114,109,90,32,61,32,40,40,122,70,97,114,32,43,32,122,78,101,97,114,41,32,42,32,108,111,99,97,108,90,32,45,32,40,50,46,48,42,122,70,97,114,42,122,78,101,97,114,41,41,32,47,32,40,40,122,70,97,114,32,45,32,122,78,101,97,114,41,42,108,111,99,97,108,90,41,59,10,9,114,101,116,117,114,110,32,40,110,111,114,109,90,32,43,32,49,46,48,41,32,42,32,48,46,53,59,10,125,10,10,102,108,111,97,116,32,67,97,108,99,117,108,97,116,101,68,105,114,101,99,116,105,111,110,97,108,83,104,97,100,111,119,70,97,99,116,111,114,40,105,110,116,32,108,105,103,104,116,73,110,100,101,120,41,10,123,10,9,118,101,99,52,32,108,105,103,104,116,83,112,97,99,101,80,111,115,32,61,32,118,76,105,103,104,116,83,112,97,99,101,80,111,115,91,108,105,103,104,116,73,110,100,101,120,93,59,10,9,114,101,116,117,114,110,32,40,116,101,120,116,117,114,101,40,68,105,114,101,99,116,105,111,110,97,108,83,112,111,116,76,105,103,104,116,83,104,97,100,111,119,77,97,112,91,108,105,103,104,116,73,110,100,101,120,93,44,32,108,105,103,104,116,83,112,97,99,101,80,111,115,46,120,121,41,46,120,32,62,61,32,40,108,105,103,104,116,83,112,97,99,101,80,111,115,46,122,32,45,32,48,46,48,48,48,53,41,41,32,63,32,49,46,48,32,58,32,48,46,48,59,10,125,10,10,102,108,111,97,116,32,67,97,108,99,117,108,97,116,101,80,111,105,110,116,83,104,97,100,111,119,70,97,99,116,111,114,40,105,110,116,32,108,105,103,104,116,73,110,100,101,120,44,32,118,101,99,51,32,108,105,103,104,116,84,111,87,111,114,108,100,44,32,102,108,111,97,116,32,122,78,101,97,114,44,32,102,108,111,97,116,32,122,70,97,114,41,10,123,10,9,114,101,116,117,114,110,32,40,116,101,120,116,117,114,101,40,80,111,105,110,116,76,105,103,104,116,83,104,97,100,111,119,77,97,112,91,108,105,103,104,116,73,110,100,101,120,93,44,32,118,101,99,51,40,108,105,103,104,116,84,111,87,111,114,108,100,46,120,44,32,45,108,105,103,104,116,84,111,87,111,114,108,100,46,121,44,32,45,108,105,103,104,116,84,111,87,111,114,108,100,46,122,41,41,46,120,32,62,61,32,86,101,99,116,111,114,84,111,68,101,112,116,104,86,97,108,117,101,40,108,105,103,104,116,84,111,87,111,114,108,100,44,32,122,78,101,97,114,44,32,122,70,97,114,41,41,32,63,32,49,46,48,32,58,32,48,46,48,59,10,125,10,10,102,108,111,97,116,32,67,97,108,99,117,108,97,116,101,83,112,111,116,83,104,97,100,111,119,70,97,99,116,111,114,40,105,110,116,32,108,105,103,104,116,73,110,100,101,120,41,10,123,10,9,118,101,99,52,32,108,105,103,104,116,83,112,97,99,101,80,111,115,32,61,32,118,76,105,103,104,116,83,112,97,99,101,80,111,115,91,108,105,103,104,116,73,110,100,101,120,93,59,10,10,9,102,108,111,97,116,32,118,105,115,105,98,105,108,105,116,121,32,61,32,49,46,48,59,10,9,102,108,111,97,116,32,120,44,121,59,10,9,102,111,114,32,40,121,32,61,32,45,51,46,53,59,32,121,32,60,61,32,51,46,53,59,32,121,43,61,32,49,46,48,41,10,9,9,102,111,114,32,40,120,32,61,32,45,51,46,53,59,32,120,32,60,61,32,51,46,53,59,32,120,43,61,32,49,46,48,41,10,9,9,9,118,105,115,105,98,105,108,105,116,121,32,43,61,32,40,116,101,120,116,117,114,101,80,114,111,106,40,68,105,114,101,99,116,105,111,110,97,108,83,112,111,116,76,105,103,104,116,83,104,97,100,111,119,77,97,112,91,108,105,103,104,116,73,110,100,101,120,93,44,32,108,105,103,104,116,83,112,97,99,101,80,111,115,46,120,121,119,32,43,32,118,101,99,51,40,120,47,49,48,50,52,46,48,32,42,32,108,105,103,104,116,83,112,97,99,101,80,111,115,46,119,44,32,121,47,49,48,50,52,46,48,32,42,32,108,105,103,104,116,83,112,97,99,101,80,111,115,46,119,44,32,48,46,48,41,41,46,120,32,62,61,32,40,108,105,103,104,116,83,112,97,99,101,80,111,115,46,122,32,45,32,48,46,48,48,48,53,41,47,108,105,103,104,116,83,112,97,99,101,80,111,115,46,119,41,32,63,32,49,46,48,32,58,32,48,46,48,59,10,10,9,118,105,115,105,98,105,108,105,116,121,32,47,61,32,54,52,46,48,59,10,9,10,9,114,101,116,117,114,110,32,118,105,115,105,98,105,108,105,116,121,59,10,125,10,10,118,111,105,100,32,109,97,105,110,40,41,10,123,10,9,118,101,99,52,32,100,105,102,102,117,115,101,67,111,108,111,114,32,61,32,77,97,116,101,114,105,97,108,68,105,102,102,117,115,101,32,42,32,118,67,111,108,111,114,59,10,10,35,105,102,32,65,85,84,79,95,84,69,88,67,79,79,82,68,83,10,9,118,101,99,50,32,116,101,120,67,111,111,114,100,32,61,32,103,108,95,70,114,97,103,67,111,111,114,100,46,120,121,32,42,32,73,110,118,84,97,114,103,101,116,83,105,122,101,59,10,35,101,108,115,101,10,9,118,101,99,50,32,116,101,120,67,111,111,114,100,32,61,32,118,84,101,120,67,111,111,114,100,59,10,35,101,110,100,105,102,10,10,35,105,102,32,76,73,71,72,84,73,78,71,32,38,38,32,80,65,82,65,76,76,65,88,95,77,65,80,80,73,78,71,10,9,102,108,111,97,116,32,104,101,105,103,104,116,32,61,32,116,101,120,116,117,114,101,40,77,97,116,101,114,105,97,108,72,101,105,103,104,116,77,97,112,44,32,116,101,120,67,111,111,114,100,41,46,114,59,10,9,102,108,111,97,116,32,118,32,61,32,104,101,105,103,104,116,42,80,97,114,97,108,108,97,120,83,99,97,108,101,32,43,32,80,97,114,97,108,108,97,120,66,105,97,115,59,10,10,9,118,101,99,51,32,118,105,101,119,68,105,114,32,61,32,110,111,114,109,97,108,105,122,101,40,118,86,105,101,119,68,105,114,41,59,10,9,116,101,120,67,111,111,114,100,32,43,61,32,118,32,42,32,118,105,101,119,68,105,114,46,120,121,59,10,35,101,110,100,105,102,10,10,35,105,102,32,68,73,70,70,85,83,69,95,77,65,80,80,73,78,71,10,9,100,105,102,102,117,115,101,67,111,108,111,114,32,42,61,32,116,101,120,116,117,114,101,40,77,97,116,101,114,105,97,108,68,105,102,102,117,115,101,77,97,112,44,32,116,101,120,67,111,111,114,100,41,59,10,35,101,110,100,105,102,10,10,35,105,102,32,70,76,65,71,95,84,69,88,84,85,82,69,79,86,69,82,76,65,89,10,9,100,105,102,102,117,115,101,67,111,108,111,114,32,42,61,32,116,101,120,116,117,114,101,40,84,101,120,116,117,114,101,79,118,101,114,108,97,121,44,32,116,101,120,67,111,111,114,100,41,59,10,35,101,110,100,105,102,10,10,35,105,102,32,70,76,65,71,95,68,69,70,69,82,82,69,68,10,9,35,105,102,32,65,76,80,72,65,95,84,69,83,84,10,9,9,47,47,32,73,110,117,116,105,108,101,32,100,101,32,102,97,105,114,101,32,100,101,32,108,39,97,108,112,104,97,45,109,97,112,112,105,110,103,32,115,97,110,115,32,97,108,112,104,97,45,116,101,115,116,32,101,110,32,68,101,102,101,114,114,101,100,32,40,108,39,97,108,112,104,97,32,110,39,101,115,116,32,112,97,115,32,115,97,117,118,101,103,97,114,100,195,169,32,100,97,110,115,32,108,101,32,71,45,66,117,102,102,101,114,41,10,9,9,35,105,102,32,65,76,80,72,65,95,77,65,80,80,73,78,71,10,9,100,105,102,102,117,115,101,67,111,108,111,114,46,97,32,42,61,32,116,101,120,116,117,114,101,40,77,97,116,101,114,105,97,108,65,108,112,104,97,77,97,112,44,32,116,101,120,67,111,111,114,100,41,46,114,59,10,9,9,35,101,110,100,105,102,10,9,9,10,9,105,102,32,40,100,105,102,102,117,115,101,67,111,108,111,114,46,97,32,60,32,77,97,116,101,114,105,97,108,65,108,112,104,97,84,104,114,101,115,104,111,108,100,41,10,9,9,100,105,115,99,97,114,100,59,10,9,35,101,110,100,105,102,32,47,47,32,65,76,80,72,65,95,84,69,83,84,10,10,9,35,105,102,32,76,73,71,72,84,73,78,71,10,9,9,35,105,102,32,78,79,82,77,65,76,95,77,65,80,80,73,78,71,10,9,118,101,99,51,32,110,111,114,109,97,108,32,61,32,110,111,114,109,97,108,105,122,101,40,118,76,105,103,104,116,84,111,87,111,114,108,100,32,42,32,40,50,46,48,32,42,32,118,101,99,51,40,116,101,120,116,117,114,101,40,77,97,116,101,114,105,97,108,78,111,114,109,97,108,77,97,112,44,32,116,101,120,67,111,111,114,100,41,41,32,45,32,49,46,48,41,41,59,10,9,9,35,101,108,115,101,10,9,118,101,99,51,32,110,111,114,109,97,108,32,61,32,110,111,114,109,97,108,105,122,101,40,118,78,111,114,109,97,108,41,59,10,9,9,35,101,110,100,105,102,32,47,47,32,78,79,82,77,65,76,95,77,65,80,80,73,78,71,10,10,9,118,101,99,51,32,115,112,101,99,117,108,97,114,67,111,108,111,114,32,61,32,77,97,116,101,114,105,97,108,83,112,101,99,117,108,97,114,46,114,103,98,59,10,9,9,35,105,102,32,83,80,69,67,85,76,65,82,95,77,65,80,80,73,78,71,10,9,115,112,101,99,117,108,97,114,67,111,108,111,114,32,42,61,32,116,101,120,116,117,114,101,40,77,97,116,101,114,105,97,108,83,112,101,99,117,108,97,114,77,97,112,44,32,116,101,120,67,111,111,114,100,41,46,114,103,98,59,10,9,9,35,101,110,100,105,102,10,10,9,47,42,10,9,84,101,120,116,117,114,101,48,58,32,68,105,102,102,117,115,101,32,67,111,108,111,114,32,43,32,83,112,101,99,117,108,97,114,10,9,84,101,120,116,117,114,101,49,58,32,78,111,114,109,97,108,32,43,32,83,112,101,99,117,108,97,114,10,9,84,101,120,116,117,114,101,50,58,32,69,110,99,111,100,101,100,32,100,101,112,116,104,32,43,32,83,104,105,110,105,110,101,115,115,10,9,42,47,10,9,82,101,110,100,101,114,84,97,114,103,101,116,48,32,61,32,118,101,99,52,40,100,105,102,102,117,115,101,67,111,108,111,114,46,114,103,98,44,32,100,111,116,40,115,112,101,99,117,108,97,114,67,111,108,111,114,44,32,118,101,99,51,40,48,46,51,44,32,48,46,53,57,44,32,48,46,49,49,41,41,41,59,10,9,82,101,110,100,101,114,84,97,114,103,101,116,49,32,61,32,118,101,99,52,40,69,110,99,111,100,101,78,111,114,109,97,108,40,110,111,114,109,97,108,41,41,59,10,9,82,101,110,100,101,114,84,97,114,103,101,116,50,32,61,32,118,101,99,52,40,70,108,111,97,116,84,111,67,111,108,111,114,40,103,108,95,70,114,97,103,67,111,111,114,100,46,122,41,44,32,40,77,97,116,101,114,105,97,108,83,104,105,110,105,110,101,115,115,32,61,61,32,48,46,48,41,32,63,32,48,46,48,32,58,32,109,97,120,40,108,111,103,50,40,77,97,116,101,114,105,97,108,83,104,105,110,105,110,101,115,115,41,44,32,48,46,49,41,47,49,48,46,53,41,59,32,47,47,32,104,116,116,112,58,47,47,119,119,119,46,103,117,101,114,114,105,108,108,97,45,103,97,109,101,115,46,99,111,109,47,112,117,98,108,105,99,97,116,105,111,110,115,47,100,114,95,107,122,50,95,114,115,120,95,100,101,118,48,55,46,112,100,102,10,9,35,101,108,115,101,32,47,47,32,76,73,71,72,84,73,78,71,10,9,82,101,110,100,101,114,84,97,114,103,101,116,48,32,61,32,118,101,99,52,40,100,105,102,102,117,115,101,67,111,108,111,114,46,114,103,98,44,32,48,46,48,41,59,10,9,35,101,110,100,105,102,10,35,101,108,115,101,32,47,47,32,70,76,65,71,95,68,69,70,69,82,82,69,68,10,9,35,105,102,32,65,76,80,72,65,95,77,65,80,80,73,78,71,10,9,100,105,102,102,117,115,101,67,111,108,111,114,46,97,32,42,61,32,116,101,120,116,117,114,101,40,77,97,116,101,114,105,97,108,65,108,112,104,97,77,97,112,44,32,116,101,120,67,111,111,114,100,41,46,114,59,10,9,35,101,110,100,105,102,10,10,9,35,105,102,32,65,76,80,72,65,95,84,69,83,84,10,9,105,102,32,40,100,105,102,102,117,115,101,67,111,108,111,114,46,97,32,60,32,77,97,116,101,114,105,97,108,65,108,112,104,97,84,104,114,101,115,104,111,108,100,41,10,9,9,100,105,115,99,97,114,100,59,10,9,35,101,110,100,105,102,10,10,9,35,105,102,32,76,73,71,72,84,73,78,71,10,9,118,101,99,51,32,108,105,103,104,116,65,109,98,105,101,110,116,32,61,32,118,101,99,51,40,48,46,48,41,59,10,9,118,101,99,51,32,108,105,103,104,116,68,105,102,102,117,115,101,32,61,32,118,101,99,51,40,48,46,48,41,59,10,9,118,101,99,51,32,108,105,103,104,116,83,112,101,99,117,108,97,114,32,61,32,118,101,99,51,40,48,46,48,41,59,10,10,9,9,35,105,102,32,78,79,82,77,65,76,95,77,65,80,80,73,78,71,10,9,118,101,99,51,32,110,111,114,109,97,108,32,61,32,110,111,114,109,97,108,105,122,101,40,118,76,105,103,104,116,84,111,87,111,114,108,100,32,42,32,40,50,46,48,32,42,32,118,101,99,51,40,116,101,120,116,117,114,101,40,77,97,116,101,114,105,97,108,78,111,114,109,97,108,77,97,112,44,32,116,101,120,67,111,111,114,100,41,41,32,45,32,49,46,48,41,41,59,10,9,9,35,101,108,115,101,10,9,118,101,99,51,32,110,111,114,109,97,108,32,61,32,110,111,114,109,97,108,105,122,101,40,118,78,111,114,109,97,108,41,59,10,9,9,35,101,110,100,105,102,10,10,9,105,102,32,40,77,97,116,101,114,105,97,108,83,104,105,110,105,110,101,115,115,32,62,32,48,46,48,41,10,9,123,10,9,9,118,101,99,51,32,101,121,101,86,101,99,32,61,32,110,111,114,109,97,108,105,122,101,40,69,121,101,80,111,115,105,116,105,111,110,32,45,32,118,87,111,114,108,100,80,111,115,41,59,10,10,9,9,102,111,114,32,40,105,110,116,32,105,32,61,32,48,59,32,105,32,60,32,51,59,32,43,43,105,41,10,9,9,123,10,9,9,9,118,101,99,52,32,108,105,103,104,116,67,111,108,111,114,32,61,32,76,105,103,104,116,115,91,105,93,46,99,111,108,111,114,59,10,9,9,9,102,108,111,97,116,32,108,105,103,104,116,65,109,98,105,101,110,116,70,97,99,116,111,114,32,61,32,76,105,103,104,116,115,91,105,93,46,102,97,99,116,111,114,115,46,120,59,10,9,9,9,102,108,111,97,116,32,108,105,103,104,116,68,105,102,102,117,115,101,70,97,99,116,111,114,32,61,32,76,105,103,104,116,115,91,105,93,46,102,97,99,116,111,114,115,46,121,59,10,10,9,9,9,115,119,105,116,99,104,32,40,76,105,103,104,116,115,91,105,93,46,116,121,112,101,41,10,9,9,9,123,10,9,9,9,9,99,97,115,101,32,76,73,71,72,84,95,68,73,82,69,67,84,73,79,78,65,76,58,10,9,9,9,9,123,10,9,9,9,9,9,118,101,99,51,32,108,105,103,104,116,68,105,114,32,61,32,45,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,49,46,120,121,122,59,10,10,9,9,9,9,9,47,47,32,65,109,98,105,101,110,116,10,9,9,9,9,9,108,105,103,104,116,65,109,98,105,101,110,116,32,43,61,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,32,42,32,108,105,103,104,116,65,109,98,105,101,110,116,70,97,99,116,111,114,32,42,32,40,77,97,116,101,114,105,97,108,65,109,98,105,101,110,116,46,114,103,98,32,43,32,83,99,101,110,101,65,109,98,105,101,110,116,46,114,103,98,41,59,10,10,9,9,9,9,9,102,108,111,97,116,32,97,116,116,32,61,32,49,46,48,59,10,10,9,9,9,9,9,35,105,102,32,83,72,65,68,79,87,95,77,65,80,80,73,78,71,10,9,9,9,9,9,105,102,32,40,76,105,103,104,116,115,91,105,93,46,115,104,97,100,111,119,77,97,112,112,105,110,103,41,10,9,9,9,9,9,123,10,9,9,9,9,9,9,102,108,111,97,116,32,115,104,97,100,111,119,70,97,99,116,111,114,32,61,32,67,97,108,99,117,108,97,116,101,68,105,114,101,99,116,105,111,110,97,108,83,104,97,100,111,119,70,97,99,116,111,114,40,105,41,59,10,9,9,9,9,9,9,105,102,32,40,115,104,97,100,111,119,70,97,99,116,111,114,32,61,61,32,48,46,48,41,10,9,9,9,9,9,9,9,98,114,101,97,107,59,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,97,116,116,32,42,61,32,115,104,97,100,111,119,70,97,99,116,111,114,59,10,9,9,9,9,9,125,10,9,9,9,9,9,35,101,110,100,105,102,10,10,9,9,9,9,9,47,47,32,68,105,102,102,117,115,101,10,9,9,9,9,9,102,108,111,97,116,32,108,97,109,98,101,114,116,32,61,32,109,97,120,40,100,111,116,40,110,111,114,109,97,108,44,32,108,105,103,104,116,68,105,114,41,44,32,48,46,48,41,59,10,10,9,9,9,9,9,108,105,103,104,116,68,105,102,102,117,115,101,32,43,61,32,97,116,116,32,42,32,108,97,109,98,101,114,116,32,42,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,32,42,32,108,105,103,104,116,68,105,102,102,117,115,101,70,97,99,116,111,114,59,10,10,9,9,9,9,9,47,47,32,83,112,101,99,117,108,97,114,10,9,9,9,9,9,118,101,99,51,32,114,101,102,108,101,99,116,105,111,110,32,61,32,114,101,102,108,101,99,116,40,45,108,105,103,104,116,68,105,114,44,32,110,111,114,109,97,108,41,59,10,9,9,9,9,9,102,108,111,97,116,32,115,112,101,99,117,108,97,114,70,97,99,116,111,114,32,61,32,109,97,120,40,100,111,116,40,114,101,102,108,101,99,116,105,111,110,44,32,101,121,101,86,101,99,41,44,32,48,46,48,41,59,10,9,9,9,9,9,115,112,101,99,117,108,97,114,70,97,99,116,111,114,32,61,32,112,111,119,40,115,112,101,99,117,108,97,114,70,97,99,116,111,114,44,32,77,97,116,101,114,105,97,108,83,104,105,110,105,110,101,115,115,41,59,10,10,9,9,9,9,9,108,105,103,104,116,83,112,101,99,117,108,97,114,32,43,61,32,97,116,116,32,42,32,115,112,101,99,117,108,97,114,70,97,99,116,111,114,32,42,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,59,10,9,9,9,9,9,98,114,101,97,107,59,10,9,9,9,9,125,10,10,9,9,9,9,99,97,115,101,32,76,73,71,72,84,95,80,79,73,78,84,58,10,9,9,9,9,123,10,9,9,9,9,9,118,101,99,51,32,108,105,103,104,116,80,111,115,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,49,46,120,121,122,59,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,65,116,116,101,110,117,97,116,105,111,110,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,49,46,119,59,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,73,110,118,82,97,100,105,117,115,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,50,46,119,59,10,9,9,9,9,9,10,9,9,9,9,9,118,101,99,51,32,119,111,114,108,100,84,111,76,105,103,104,116,32,61,32,108,105,103,104,116,80,111,115,32,45,32,118,87,111,114,108,100,80,111,115,59,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,68,105,114,76,101,110,103,116,104,32,61,32,108,101,110,103,116,104,40,119,111,114,108,100,84,111,76,105,103,104,116,41,59,10,9,9,9,9,9,118,101,99,51,32,108,105,103,104,116,68,105,114,32,61,32,119,111,114,108,100,84,111,76,105,103,104,116,32,47,32,108,105,103,104,116,68,105,114,76,101,110,103,116,104,59,32,47,47,32,78,111,114,109,97,108,105,115,97,116,105,111,110,10,9,9,9,9,9,10,9,9,9,9,9,102,108,111,97,116,32,97,116,116,32,61,32,109,97,120,40,108,105,103,104,116,65,116,116,101,110,117,97,116,105,111,110,32,45,32,108,105,103,104,116,73,110,118,82,97,100,105,117,115,32,42,32,108,105,103,104,116,68,105,114,76,101,110,103,116,104,44,32,48,46,48,41,59,10,10,9,9,9,9,9,47,47,32,65,109,98,105,101,110,116,10,9,9,9,9,9,108,105,103,104,116,65,109,98,105,101,110,116,32,43,61,32,97,116,116,32,42,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,32,42,32,108,105,103,104,116,65,109,98,105,101,110,116,70,97,99,116,111,114,32,42,32,40,77,97,116,101,114,105,97,108,65,109,98,105,101,110,116,46,114,103,98,32,43,32,83,99,101,110,101,65,109,98,105,101,110,116,46,114,103,98,41,59,10,10,9,9,9,9,9,35,105,102,32,83,72,65,68,79,87,95,77,65,80,80,73,78,71,10,9,9,9,9,9,105,102,32,40,76,105,103,104,116,115,91,105,93,46,115,104,97,100,111,119,77,97,112,112,105,110,103,41,10,9,9,9,9,9,123,10,9,9,9,9,9,9,102,108,111,97,116,32,115,104,97,100,111,119,70,97,99,116,111,114,32,61,32,67,97,108,99,117,108,97,116,101,80,111,105,110,116,83,104,97,100,111,119,70,97,99,116,111,114,40,105,44,32,118,87,111,114,108,100,80,111,115,32,45,32,108,105,103,104,116,80,111,115,44,32,48,46,49,44,32,53,48,46,48,41,59,10,9,9,9,9,9,9,105,102,32,40,115,104,97,100,111,119,70,97,99,116,111,114,32,61,61,32,48,46,48,41,10,9,9,9,9,9,9,9,98,114,101,97,107,59,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,97,116,116,32,42,61,32,115,104,97,100,111,119,70,97,99,116,111,114,59,10,9,9,9,9,9,125,10,9,9,9,9,9,35,101,110,100,105,102,10,10,9,9,9,9,9,47,47,32,68,105,102,102,117,115,101,10,9,9,9,9,9,102,108,111,97,116,32,108,97,109,98,101,114,116,32,61,32,109,97,120,40,100,111,116,40,110,111,114,109,97,108,44,32,108,105,103,104,116,68,105,114,41,44,32,48,46,48,41,59,10,9,9,9,9,9,10,9,9,9,9,9,108,105,103,104,116,68,105,102,102,117,115,101,32,43,61,32,97,116,116,32,42,32,108,97,109,98,101,114,116,32,42,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,32,42,32,108,105,103,104,116,68,105,102,102,117,115,101,70,97,99,116,111,114,59,10,10,9,9,9,9,9,47,47,32,83,112,101,99,117,108,97,114,10,9,9,9,9,9,118,101,99,51,32,114,101,102,108,101,99,116,105,111,110,32,61,32,114,101,102,108,101,99,116,40,45,108,105,103,104,116,68,105,114,44,32,110,111,114,109,97,108,41,59,10,9,9,9,9,9,102,108,111,97,116,32,115,112,101,99,117,108,97,114,70,97,99,116,111,114,32,61,32,109,97,120,40,100,111,116,40,114,101,102,108,101,99,116,105,111,110,44,32,101,121,101,86,101,99,41,44,32,48,46,48,41,59,10,9,9,9,9,9,115,112,101,99,117,108,97,114,70,97,99,116,111,114,32,61,32,112,111,119,40,115,112,101,99,117,108,97,114,70,97,99,116,111,114,44,32,77,97,116,101,114,105,97,108,83,104,105,110,105,110,101,115,115,41,59,10,10,9,9,9,9,9,108,105,103,104,116,83,112,101,99,117,108,97,114,32,43,61,32,97,116,116,32,42,32,115,112,101,99,117,108,97,114,70,97,99,116,111,114,32,42,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,59,10,9,9,9,9,9,98,114,101,97,107,59,10,9,9,9,9,125,10,10,9,9,9,9,99,97,115,101,32,76,73,71,72,84,95,83,80,79,84,58,10,9,9,9,9,123,10,9,9,9,9,9,118,101,99,51,32,108,105,103,104,116,80,111,115,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,49,46,120,121,122,59,10,9,9,9,9,9,118,101,99,51,32,108,105,103,104,116,68,105,114,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,50,46,120,121,122,59,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,65,116,116,101,110,117,97,116,105,111,110,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,49,46,119,59,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,73,110,118,82,97,100,105,117,115,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,50,46,119,59,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,73,110,110,101,114,65,110,103,108,101,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,51,46,120,59,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,79,117,116,101,114,65,110,103,108,101,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,51,46,121,59,10,10,9,9,9,9,9,118,101,99,51,32,119,111,114,108,100,84,111,76,105,103,104,116,32,61,32,108,105,103,104,116,80,111,115,32,45,32,118,87,111,114,108,100,80,111,115,59,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,68,105,115,116,97,110,99,101,32,61,32,108,101,110,103,116,104,40,119,111,114,108,100,84,111,76,105,103,104,116,41,59,10,9,9,9,9,9,119,111,114,108,100,84,111,76,105,103,104,116,32,47,61,32,108,105,103,104,116,68,105,115,116,97,110,99,101,59,32,47,47,32,78,111,114,109,97,108,105,115,97,116,105,111,110,10,9,9,9,9,9,10,9,9,9,9,9,102,108,111,97,116,32,97,116,116,32,61,32,109,97,120,40,108,105,103,104,116,65,116,116,101,110,117,97,116,105,111,110,32,45,32,108,105,103,104,116,73,110,118,82,97,100,105,117,115,32,42,32,108,105,103,104,116,68,105,115,116,97,110,99,101,44,32,48,46,48,41,59,10,10,9,9,9,9,9,47,47,32,65,109,98,105,101,110,116,10,9,9,9,9,9,108,105,103,104,116,65,109,98,105,101,110,116,32,43,61,32,97,116,116,32,42,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,32,42,32,108,105,103,104,116,65,109,98,105,101,110,116,70,97,99,116,111,114,32,42,32,40,77,97,116,101,114,105,97,108,65,109,98,105,101,110,116,46,114,103,98,32,43,32,83,99,101,110,101,65,109,98,105,101,110,116,46,114,103,98,41,59,10,10,9,9,9,9,9,35,105,102,32,83,72,65,68,79,87,95,77,65,80,80,73,78,71,10,9,9,9,9,9,105,102,32,40,76,105,103,104,116,115,91,105,93,46,115,104,97,100,111,119,77,97,112,112,105,110,103,41,10,9,9,9,9,9,123,10,9,9,9,9,9,9,102,108,111,97,116,32,115,104,97,100,111,119,70,97,99,116,111,114,32,61,32,67,97,108,99,117,108,97,116,101,83,112,111,116,83,104,97,100,111,119,70,97,99,116,111,114,40,105,41,59,10,9,9,9,9,9,9,105,102,32,40,115,104,97,100,111,119,70,97,99,116,111,114,32,61,61,32,48,46,48,41,10,9,9,9,9,9,9,9,98,114,101,97,107,59,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,97,116,116,32,42,61,32,115,104,97,100,111,119,70,97,99,116,111,114,59,10,9,9,9,9,9,125,10,9,9,9,9,9,35,101,110,100,105,102,10,10,9,9,9,9,9,47,47,32,77,111,100,105,102,105,99,97,116,105,111,110,32,100,101,32,108,39,97,116,116,195,169,110,117,97,116,105,111,110,32,112,111,117,114,32,103,195,169,114,101,114,32,108,101,32,115,112,111,116,10,9,9,9,9,9,102,108,111,97,116,32,99,117,114,65,110,103,108,101,32,61,32,100,111,116,40,108,105,103,104,116,68,105,114,44,32,45,119,111,114,108,100,84,111,76,105,103,104,116,41,59,10,9,9,9,9,9,102,108,111,97,116,32,105,110,110,101,114,77,105,110,117,115,79,117,116,101,114,65,110,103,108,101,32,61,32,108,105,103,104,116,73,110,110,101,114,65,110,103,108,101,32,45,32,108,105,103,104,116,79,117,116,101,114,65,110,103,108,101,59,10,9,9,9,9,9,97,116,116,32,42,61,32,109,97,120,40,40,99,117,114,65,110,103,108,101,32,45,32,108,105,103,104,116,79,117,116,101,114,65,110,103,108,101,41,32,47,32,105,110,110,101,114,77,105,110,117,115,79,117,116,101,114,65,110,103,108,101,44,32,48,46,48,41,59,10,10,9,9,9,9,9,47,47,32,68,105,102,102,117,115,101,10,9,9,9,9,9,102,108,111,97,116,32,108,97,109,98,101,114,116,32,61,32,109,97,120,40,100,111,116,40,110,111,114,109,97,108,44,32,119,111,114,108,100,84,111,76,105,103,104,116,41,44,32,48,46,48,41,59,10,10,9,9,9,9,9,108,105,103,104,116,68,105,102,102,117,115,101,32,43,61,32,97,116,116,32,42,32,108,97,109,98,101,114,116,32,42,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,32,42,32,108,105,103,104,116,68,105,102,102,117,115,101,70,97,99,116,111,114,59,10,10,9,9,9,9,9,47,47,32,83,112,101,99,117,108,97,114,10,9,9,9,9,9,118,101,99,51,32,114,101,102,108,101,99,116,105,111,110,32,61,32,114,101,102,108,101,99,116,40,45,119,111,114,108,100,84,111,76,105,103,104,116,44,32,110,111,114,109,97,108,41,59,10,9,9,9,9,9,102,108,111,97,116,32,115,112,101,99,117,108,97,114,70,97,99,116,111,114,32,61,32,109,97,120,40,100,111,116,40,114,101,102,108,101,99,116,105,111,110,44,32,101,121,101,86,101,99,41,44,32,48,46,48,41,59,10,9,9,9,9,9,115,112,101,99,117,108,97,114,70,97,99,116,111,114,32,61,32,112,111,119,40,115,112,101,99,117,108,97,114,70,97,99,116,111,114,44,32,77,97,116,101,114,105,97,108,83,104,105,110,105,110,101,115,115,41,59,10,10,9,9,9,9,9,108,105,103,104,116,83,112,101,99,117,108,97,114,32,43,61,32,97,116,116,32,42,32,115,112,101,99,117,108,97,114,70,97,99,116,111,114,32,42,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,59,10,9,9,9,9,9,98,114,101,97,107,59,10,9,9,9,9,125,10,9,9,9,9,10,9,9,9,9,100,101,102,97,117,108,116,58,10,9,9,9,9,9,98,114,101,97,107,59,10,9,9,9,125,10,9,9,125,10,9,125,10,9,101,108,115,101,10,9,123,10,9,9,102,111,114,32,40,105,110,116,32,105,32,61,32,48,59,32,105,32,60,32,51,59,32,43,43,105,41,10,9,9,123,10,9,9,9,118,101,99,52,32,108,105,103,104,116,67,111,108,111,114,32,61,32,76,105,103,104,116,115,91,105,93,46,99,111,108,111,114,59,10,9,9,9,102,108,111,97,116,32,108,105,103,104,116,65,109,98,105,101,110,116,70,97,99,116,111,114,32,61,32,76,105,103,104,116,115,91,105,93,46,102,97,99,116,111,114,115,46,120,59,10,9,9,9,102,108,111,97,116,32,108,105,103,104,116,68,105,102,102,117,115,101,70,97,99,116,111,114,32,61,32,76,105,103,104,116,115,91,105,93,46,102,97,99,116,111,114,115,46,121,59,10,10,9,9,9,115,119,105,116,99,104,32,40,76,105,103,104,116,115,91,105,93,46,116,121,112,101,41,10,9,9,9,123,10,9,9,9,9,99,97,115,101,32,76,73,71,72,84,95,68,73,82,69,67,84,73,79,78,65,76,58,10,9,9,9,9,123,10,9,9,9,9,9,118,101,99,51,32,108,105,103,104,116,68,105,114,32,61,32,45,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,49,46,120,121,122,59,10,10,9,9,9,9,9,47,47,32,65,109,98,105,101,110,116,10,9,9,9,9,9,108,105,103,104,116,65,109,98,105,101,110,116,32,43,61,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,32,42,32,108,105,103,104,116,65,109,98,105,101,110,116,70,97,99,116,111,114,32,42,32,40,77,97,116,101,114,105,97,108,65,109,98,105,101,110,116,46,114,103,98,32,43,32,83,99,101,110,101,65,109,98,105,101,110,116,46,114,103,98,41,59,10,10,9,9,9,9,9,102,108,111,97,116,32,97,116,116,32,61,32,49,46,48,59,10,10,9,9,9,9,9,35,105,102,32,83,72,65,68,79,87,95,77,65,80,80,73,78,71,10,9,9,9,9,9,105,102,32,40,76,105,103,104,116,115,91,105,93,46,115,104,97,100,111,119,77,97,112,112,105,110,103,41,10,9,9,9,9,9,123,10,9,9,9,9,9,9,102,108,111,97,116,32,115,104,97,100,111,119,70,97,99,116,111,114,32,61,32,67,97,108,99,117,108,97,116,101,68,105,114,101,99,116,105,111,110,97,108,83,104,97,100,111,119,70,97,99,116,111,114,40,105,41,59,10,9,9,9,9,9,9,105,102,32,40,115,104,97,100,111,119,70,97,99,116,111,114,32,61,61,32,48,46,48,41,10,9,9,9,9,9,9,9,98,114,101,97,107,59,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,97,116,116,32,42,61,32,115,104,97,100,111,119,70,97,99,116,111,114,59,10,9,9,9,9,9,125,10,9,9,9,9,9,35,101,110,100,105,102,10,10,9,9,9,9,9,47,47,32,68,105,102,102,117,115,101,10,9,9,9,9,9,102,108,111,97,116,32,108,97,109,98,101,114,116,32,61,32,109,97,120,40,100,111,116,40,110,111,114,109,97,108,44,32,108,105,103,104,116,68,105,114,41,44,32,48,46,48,41,59,10,10,9,9,9,9,9,108,105,103,104,116,68,105,102,102,117,115,101,32,43,61,32,97,116,116,32,42,32,108,97,109,98,101,114,116,32,42,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,32,42,32,108,105,103,104,116,68,105,102,102,117,115,101,70,97,99,116,111,114,59,10,9,9,9,9,9,98,114,101,97,107,59,10,9,9,9,9,125,10,10,9,9,9,9,99,97,115,101,32,76,73,71,72,84,95,80,79,73,78,84,58,10,9,9,9,9,123,10,9,9,9,9,9,118,101,99,51,32,108,105,103,104,116,80,111,115,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,49,46,120,121,122,59,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,65,116,116,101,110,117,97,116,105,111,110,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,49,46,119,59,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,73,110,118,82,97,100,105,117,115,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,50,46,119,59,10,9,9,9,9,9,10,9,9,9,9,9,118,101,99,51,32,119,111,114,108,100,84,111,76,105,103,104,116,32,61,32,108,105,103,104,116,80,111,115,32,45,32,118,87,111,114,108,100,80,111,115,59,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,68,105,114,76,101,110,103,116,104,32,61,32,108,101,110,103,116,104,40,119,111,114,108,100,84,111,76,105,103,104,116,41,59,10,9,9,9,9,9,118,101,99,51,32,108,105,103,104,116,68,105,114,32,61,32,119,111,114,108,100,84,111,76,105,103,104,116,32,47,32,108,105,103,104,116,68,105,114,76,101,110,103,116,104,59,32,47,47,32,78,111,114,109,97,108,105,115,97,116,105,111,110,10,9,9,9,9,9,10,9,9,9,9,9,102,108,111,97,116,32,97,116,116,32,61,32,109,97,120,40,108,105,103,104,116,65,116,116,101,110,117,97,116,105,111,110,32,45,32,108,105,103,104,116,73,110,118,82,97,100,105,117,115,32,42,32,108,105,103,104,116,68,105,114,76,101,110,103,116,104,44,32,48,46,48,41,59,10,10,9,9,9,9,9,47,47,32,65,109,98,105,101,110,116,10,9,9,9,9,9,108,105,103,104,116,65,109,98,105,101,110,116,32,43,61,32,97,116,116,32,42,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,32,42,32,108,105,103,104,116,65,109,98,105,101,110,116,70,97,99,116,111,114,32,42,32,40,77,97,116,101,114,105,97,108,65,109,98,105,101,110,116,46,114,103,98,32,43,32,83,99,101,110,101,65,109,98,105,101,110,116,46,114,103,98,41,59,10,10,9,9,9,9,9,35,105,102,32,83,72,65,68,79,87,95,77,65,80,80,73,78,71,10,9,9,9,9,9,105,102,32,40,76,105,103,104,116,115,91,105,93,46,115,104,97,100,111,119,77,97,112,112,105,110,103,41,10,9,9,9,9,9,123,10,9,9,9,9,9,9,102,108,111,97,116,32,115,104,97,100,111,119,70,97,99,116,111,114,32,61,32,67,97,108,99,117,108,97,116,101,80,111,105,110,116,83,104,97,100,111,119,70,97,99,116,111,114,40,105,44,32,118,87,111,114,108,100,80,111,115,32,45,32,108,105,103,104,116,80,111,115,44,32,48,46,49,44,32,53,48,46,48,41,59,10,9,9,9,9,9,9,105,102,32,40,115,104,97,100,111,119,70,97,99,116,111,114,32,61,61,32,48,46,48,41,10,9,9,9,9,9,9,9,98,114,101,97,107,59,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,97,116,116,32,42,61,32,115,104,97,100,111,119,70,97,99,116,111,114,59,10,9,9,9,9,9,125,10,9,9,9,9,9,35,101,110,100,105,102,10,10,9,9,9,9,9,47,47,32,68,105,102,102,117,115,101,10,9,9,9,9,9,102,108,111,97,116,32,108,97,109,98,101,114,116,32,61,32,109,97,120,40,100,111,116,40,110,111,114,109,97,108,44,32,108,105,103,104,116,68,105,114,41,44,32,48,46,48,41,59,10,9,9,9,9,9,10,9,9,9,9,9,108,105,103,104,116,68,105,102,102,117,115,101,32,43,61,32,97,116,116,32,42,32,108,97,109,98,101,114,116,32,42,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,32,42,32,108,105,103,104,116,68,105,102,102,117,115,101,70,97,99,116,111,114,59,10,9,9,9,9,9,98,114,101,97,107,59,10,9,9,9,9,125,10,10,9,9,9,9,99,97,115,101,32,76,73,71,72,84,95,83,80,79,84,58,10,9,9,9,9,123,10,9,9,9,9,9,118,101,99,51,32,108,105,103,104,116,80,111,115,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,49,46,120,121,122,59,10,9,9,9,9,9,118,101,99,51,32,108,105,103,104,116,68,105,114,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,50,46,120,121,122,59,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,65,116,116,101,110,117,97,116,105,111,110,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,49,46,119,59,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,73,110,118,82,97,100,105,117,115,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,50,46,119,59,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,73,110,110,101,114,65,110,103,108,101,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,51,46,120,59,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,79,117,116,101,114,65,110,103,108,101,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,51,46,121,59,10,10,9,9,9,9,9,118,101,99,51,32,119,111,114,108,100,84,111,76,105,103,104,116,32,61,32,108,105,103,104,116,80,111,115,32,45,32,118,87,111,114,108,100,80,111,115,59,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,68,105,115,116,97,110,99,101,32,61,32,108,101,110,103,116,104,40,119,111,114,108,100,84,111,76,105,103,104,116,41,59,10,9,9,9,9,9,119,111,114,108,100,84,111,76,105,103,104,116,32,47,61,32,108,105,103,104,116,68,105,115,116,97,110,99,101,59,32,47,47,32,78,111,114,109,97,108,105,115,97,116,105,111,110,10,9,9,9,9,9,10,9,9,9,9,9,102,108,111,97,116,32,97,116,116,32,61,32,109,97,120,40,108,105,103,104,116,65,116,116,101,110,117,97,116,105,111,110,32,45,32,108,105,103,104,116,73,110,118,82,97,100,105,117,115,32,42,32,108,105,103,104,116,68,105,115,116,97,110,99,101,44,32,48,46,48,41,59,10,10,9,9,9,9,9,47,47,32,65,109,98,105,101,110,116,10,9,9,9,9,9,108,105,103,104,116,65,109,98,105,101,110,116,32,43,61,32,97,116,116,32,42,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,32,42,32,108,105,103,104,116,65,109,98,105,101,110,116,70,97,99,116,111,114,32,42,32,40,77,97,116,101,114,105,97,108,65,109,98,105,101,110,116,46,114,103,98,32,43,32,83,99,101,110,101,65,109,98,105,101,110,116,46,114,103,98,41,59,10,10,9,9,9,9,9,35,105,102,32,83,72,65,68,79,87,95,77,65,80,80,73,78,71,10,9,9,9,9,9,105,102,32,40,76,105,103,104,116,115,91,105,93,46,115,104,97,100,111,119,77,97,112,112,105,110,103,41,10,9,9,9,9,9,123,10,9,9,9,9,9,9,102,108,111,97,116,32,115,104,97,100,111,119,70,97,99,116,111,114,32,61,32,67,97,108,99,117,108,97,116,101,83,112,111,116,83,104,97,100,111,119,70,97,99,116,111,114,40,105,41,59,10,9,9,9,9,9,9,105,102,32,40,115,104,97,100,111,119,70,97,99,116,111,114,32,61,61,32,48,46,48,41,10,9,9,9,9,9,9,9,98,114,101,97,107,59,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,97,116,116,32,42,61,32,115,104,97,100,111,119,70,97,99,116,111,114,59,10,9,9,9,9,9,125,10,9,9,9,9,9,35,101,110,100,105,102,10,10,9,9,9,9,9,47,47,32,77,111,100,105,102,105,99,97,116,105,111,110,32,100,101,32,108,39,97,116,116,195,169,110,117,97,116,105,111,110,32,112,111,117,114,32,103,195,169,114,101,114,32,108,101,32,115,112,111,116,10,9,9,9,9,9,102,108,111,97,116,32,99,117,114,65,110,103,108,101,32,61,32,100,111,116,40,108,105,103,104,116,68,105,114,44,32,45,119,111,114,108,100,84,111,76,105,103,104,116,41,59,10,9,9,9,9,9,102,108,111,97,116,32,105,110,110,101,114,77,105,110,117,115,79,117,116,101,114,65,110,103,108,101,32,61,32,108,105,103,104,116,73,110,110,101,114,65,110,103,108,101,32,45,32,108,105,103,104,116,79,117,116,101,114,65,110,103,108,101,59,10,9,9,9,9,9,97,116,116,32,42,61,32,109,97,120,40,40,99,117,114,65,110,103,108,101,32,45,32,108,105,103,104,116,79,117,116,101,114,65,110,103,108,101,41,32,47,32,105,110,110,101,114,77,105,110,117,115,79,117,116,101,114,65,110,103,108,101,44,32,48,46,48,41,59,10,10,9,9,9,9,9,47,47,32,68,105,102,102,117,115,101,10,9,9,9,9,9,102,108,111,97,116,32,108,97,109,98,101,114,116,32,61,32,109,97,120,40,100,111,116,40,110,111,114,109,97,108,44,32,119,111,114,108,100,84,111,76,105,103,104,116,41,44,32,48,46,48,41,59,10,10,9,9,9,9,9,108,105,103,104,116,68,105,102,102,117,115,101,32,43,61,32,97,116,116,32,42,32,108,97,109,98,101,114,116,32,42,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,32,42,32,108,105,103,104,116,68,105,102,102,117,115,101,70,97,99,116,111,114,59,10,9,9,9,9,125,10,9,9,9,9,10,9,9,9,9,100,101,102,97,117,108,116,58,10,9,9,9,9,9,98,114,101,97,107,59,10,9,9,9,125,10,9,9,125,10,9,125,10,9,10,9,108,105,103,104,116,83,112,101,99,117,108,97,114,32,42,61,32,77,97,116,101,114,105,97,108,83,112,101,99,117,108,97,114,46,114,103,98,59,10,9,9,35,105,102,32,83,80,69,67,85,76,65,82,95,77,65,80,80,73,78,71,10,9,108,105,103,104,116,83,112,101,99,117,108,97,114,32,42,61,32,116,101,120,116,117,114,101,40,77,97,116,101,114,105,97,108,83,112,101,99,117,108,97,114,77,97,112,44,32,116,101,120,67,111,111,114,100,41,46,114,103,98,59,32,47,47,32,85,116,105,108,105,115,101,114,32,108,39,97,108,112,104,97,32,100,101,32,77,97,116,101,114,105,97,108,83,112,101,99,117,108,97,114,32,110,39,97,117,114,97,105,116,32,97,117,99,117,110,32,115,101,110,115,10,9,9,35,101,110,100,105,102,10,9,9,10,9,118,101,99,51,32,108,105,103,104,116,67,111,108,111,114,32,61,32,40,108,105,103,104,116,65,109,98,105,101,110,116,32,43,32,108,105,103,104,116,68,105,102,102,117,115,101,32,43,32,108,105,103,104,116,83,112,101,99,117,108,97,114,41,59,10,9,118,101,99,52,32,102,114,97,103,109,101,110,116,67,111,108,111,114,32,61,32,118,101,99,52,40,108,105,103,104,116,67,111,108,111,114,44,32,49,46,48,41,32,42,32,100,105,102,102,117,115,101,67,111,108,111,114,59,10,10,9,9,35,105,102,32,69,77,73,83,83,73,86,69,95,77,65,80,80,73,78,71,10,9,102,108,111,97,116,32,108,105,103,104,116,73,110,116,101,110,115,105,116,121,32,61,32,100,111,116,40,108,105,103,104,116,67,111,108,111,114,44,32,118,101,99,51,40,48,46,51,44,32,48,46,53,57,44,32,48,46,49,49,41,41,59,10,10,9,118,101,99,51,32,101,109,105,115,115,105,111,110,67,111,108,111,114,32,61,32,77,97,116,101,114,105,97,108,68,105,102,102,117,115,101,46,114,103,98,32,42,32,116,101,120,116,117,114,101,40,77,97,116,101,114,105,97,108,69,109,105,115,115,105,118,101,77,97,112,44,32,116,101,120,67,111,111,114,100,41,46,114,103,98,59,10,9,82,101,110,100,101,114,84,97,114,103,101,116,48,32,61,32,118,101,99,52,40,109,105,120,40,102,114,97,103,109,101,110,116,67,111,108,111,114,46,114,103,98,44,32,101,109,105,115,115,105,111,110,67,111,108,111,114,44,32,99,108,97,109,112,40,49,46,48,32,45,32,51,46,48,42,108,105,103,104,116,73,110,116,101,110,115,105,116,121,44,32,48,46,48,44,32,49,46,48,41,41,44,32,102,114,97,103,109,101,110,116,67,111,108,111,114,46,97,41,59,10,9,9,35,101,108,115,101,10,9,82,101,110,100,101,114,84,97,114,103,101,116,48,32,61,32,102,114,97,103,109,101,110,116,67,111,108,111,114,59,10,9,9,35,101,110,100,105,102,32,47,47,32,69,77,73,83,83,73,86,69,95,77,65,80,80,73,78,71,10,9,35,101,108,115,101,10,9,82,101,110,100,101,114,84,97,114,103,101,116,48,32,61,32,100,105,102,102,117,115,101,67,111,108,111,114,59,10,9,35,101,110,100,105,102,32,47,47,32,76,73,71,72,84,73,78,71,10,35,101,110,100,105,102,32,47,47,32,70,76,65,71,95,68,69,70,69,82,82,69,68,10,125,10,10, \ No newline at end of file From 831b9358ef8ba6af6e5053e04e5cbaaf9eb3c8e1 Mon Sep 17 00:00:00 2001 From: Lynix Date: Wed, 19 Aug 2015 23:23:19 +0200 Subject: [PATCH 33/37] Utility/SimpleTextDrawer: Fix movement Former-commit-id: f5086d1ca281f31a3b89d5cd535f9aeaa9b2a929 --- include/Nazara/Utility/SimpleTextDrawer.hpp | 7 ++- src/Nazara/Utility/SimpleTextDrawer.cpp | 56 ++++++++++++++++----- 2 files changed, 50 insertions(+), 13 deletions(-) diff --git a/include/Nazara/Utility/SimpleTextDrawer.hpp b/include/Nazara/Utility/SimpleTextDrawer.hpp index c69cc1a25..200031c7c 100644 --- a/include/Nazara/Utility/SimpleTextDrawer.hpp +++ b/include/Nazara/Utility/SimpleTextDrawer.hpp @@ -19,7 +19,7 @@ class NAZARA_UTILITY_API NzSimpleTextDrawer : public NzAbstractTextDrawer public: NzSimpleTextDrawer(); NzSimpleTextDrawer(const NzSimpleTextDrawer& drawer); - NzSimpleTextDrawer(NzSimpleTextDrawer&&) = default; + NzSimpleTextDrawer(NzSimpleTextDrawer&& drawer); virtual ~NzSimpleTextDrawer(); const NzRectui& GetBounds() const; @@ -39,10 +39,15 @@ class NAZARA_UTILITY_API NzSimpleTextDrawer : public NzAbstractTextDrawer void SetStyle(nzUInt32 style); void SetText(const NzString& str); + NzSimpleTextDrawer& operator=(const NzSimpleTextDrawer& drawer) = default; + NzSimpleTextDrawer& operator=(NzSimpleTextDrawer&& drawer); + static NzSimpleTextDrawer Draw(const NzString& str, unsigned int characterSize, nzUInt32 style = nzTextStyle_Regular, const NzColor& color = NzColor::White); static NzSimpleTextDrawer Draw(NzFont* font, const NzString& str, unsigned int characterSize, nzUInt32 style = nzTextStyle_Regular, const NzColor& color = NzColor::White); private: + void ConnectFontSlots(); + void DisconnectFontSlots(); void OnFontAtlasLayerChanged(const NzFont* font, NzAbstractImage* oldLayer, NzAbstractImage* newLayer); void OnFontInvalidated(const NzFont* font); void OnFontRelease(const NzFont* object); diff --git a/src/Nazara/Utility/SimpleTextDrawer.cpp b/src/Nazara/Utility/SimpleTextDrawer.cpp index 2373f722a..45cd8a5b5 100644 --- a/src/Nazara/Utility/SimpleTextDrawer.cpp +++ b/src/Nazara/Utility/SimpleTextDrawer.cpp @@ -24,6 +24,12 @@ m_characterSize(drawer.m_characterSize) SetFont(drawer.m_font); } +NzSimpleTextDrawer::NzSimpleTextDrawer(NzSimpleTextDrawer&& drawer) +{ + operator=(std::move(drawer)); +} + + NzSimpleTextDrawer::~NzSimpleTextDrawer() = default; const NzRectui& NzSimpleTextDrawer::GetBounds() const @@ -112,20 +118,11 @@ void NzSimpleTextDrawer::SetFont(NzFont* font) if (m_font != font) { m_font = font; + if (m_font) - { - m_atlasChangedSlot.Connect(m_font->OnFontAtlasChanged, this, &NzSimpleTextDrawer::OnFontInvalidated); - m_atlasLayerChangedSlot.Connect(m_font->OnFontAtlasLayerChanged, this, &NzSimpleTextDrawer::OnFontAtlasLayerChanged); - m_fontReleaseSlot.Connect(m_font->OnFontRelease, this, &NzSimpleTextDrawer::OnFontRelease); - m_glyphCacheClearedSlot.Connect(m_font->OnFontGlyphCacheCleared, this, &NzSimpleTextDrawer::OnFontInvalidated); - } + ConnectFontSlots(); else - { - m_atlasChangedSlot.Disconnect(); - m_atlasLayerChangedSlot.Disconnect(); - m_fontReleaseSlot.Disconnect(); - m_glyphCacheClearedSlot.Disconnect(); - } + DisconnectFontSlots(); m_glyphUpdated = false; } @@ -145,6 +142,25 @@ void NzSimpleTextDrawer::SetText(const NzString& str) m_glyphUpdated = false; } +NzSimpleTextDrawer& NzSimpleTextDrawer::operator=(NzSimpleTextDrawer&& drawer) +{ + DisconnectFontSlots(); + + m_bounds = std::move(drawer.m_bounds); + m_characterSize = std::move(drawer.m_characterSize); + m_color = std::move(drawer.m_color); + m_glyphs = std::move(drawer.m_glyphs); + m_glyphUpdated = std::move(drawer.m_glyphUpdated); + m_font = std::move(drawer.m_font); + m_style = std::move(drawer.m_style); + m_text = std::move(drawer.m_text); + + // Update slot pointers (TODO: Improve the way of doing this) + ConnectFontSlots(); + + return *this; +} + NzSimpleTextDrawer NzSimpleTextDrawer::Draw(const NzString& str, unsigned int characterSize, nzUInt32 style, const NzColor& color) { NzSimpleTextDrawer drawer; @@ -168,6 +184,22 @@ NzSimpleTextDrawer NzSimpleTextDrawer::Draw(NzFont* font, const NzString& str, u return drawer; } +void NzSimpleTextDrawer::ConnectFontSlots() +{ + m_atlasChangedSlot.Connect(m_font->OnFontAtlasChanged, this, &NzSimpleTextDrawer::OnFontInvalidated); + m_atlasLayerChangedSlot.Connect(m_font->OnFontAtlasLayerChanged, this, &NzSimpleTextDrawer::OnFontAtlasLayerChanged); + m_fontReleaseSlot.Connect(m_font->OnFontRelease, this, &NzSimpleTextDrawer::OnFontRelease); + m_glyphCacheClearedSlot.Connect(m_font->OnFontGlyphCacheCleared, this, &NzSimpleTextDrawer::OnFontInvalidated); +} + +void NzSimpleTextDrawer::DisconnectFontSlots() +{ + m_atlasChangedSlot.Disconnect(); + m_atlasLayerChangedSlot.Disconnect(); + m_fontReleaseSlot.Disconnect(); + m_glyphCacheClearedSlot.Disconnect(); +} + void NzSimpleTextDrawer::OnFontAtlasLayerChanged(const NzFont* font, NzAbstractImage* oldLayer, NzAbstractImage* newLayer) { NazaraUnused(font); From 6ed8abafc6da77fdeb5ba042981c829fd3b5c20b Mon Sep 17 00:00:00 2001 From: Lynix Date: Sat, 19 Sep 2015 15:31:39 +0200 Subject: [PATCH 34/37] Ndk/RenderSystem: Fix compilation Former-commit-id: 25907facf61c77d64c1206ce4abe3e8018931ba7 --- SDK/src/NDK/Systems/RenderSystem.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SDK/src/NDK/Systems/RenderSystem.cpp b/SDK/src/NDK/Systems/RenderSystem.cpp index 7face4a5a..d242e6ce2 100644 --- a/SDK/src/NDK/Systems/RenderSystem.cpp +++ b/SDK/src/NDK/Systems/RenderSystem.cpp @@ -113,7 +113,7 @@ namespace Ndk NodeComponent& lightNode = light->GetComponent(); ///TODO: Cache somehow? - lightComponent.AddToRenderQueue(renderQueue, NzMatrix4f::ConcatenateAffine(m_coordinateSystemMatrix, drawableNode.GetTransformMatrix())); + lightComponent.AddToRenderQueue(renderQueue, NzMatrix4f::ConcatenateAffine(m_coordinateSystemMatrix, lightNode.GetTransformMatrix())); } camComponent.ApplyView(); From 9e7452ab68860b53c29e0cd28267897adaf99cc2 Mon Sep 17 00:00:00 2001 From: Lynix Date: Wed, 9 Dec 2015 01:11:27 +0100 Subject: [PATCH 35/37] Graphics/DepthRender: Fix compilation Former-commit-id: 749e3b67038cba20c46bd5570e616608200733f5 --- include/Nazara/Graphics/DepthRenderQueue.hpp | 49 +- .../Nazara/Graphics/DepthRenderTechnique.hpp | 91 +- src/Nazara/Graphics/DepthRenderQueue.cpp | 402 ++++----- src/Nazara/Graphics/DepthRenderTechnique.cpp | 834 ++++++++++-------- 4 files changed, 720 insertions(+), 656 deletions(-) diff --git a/include/Nazara/Graphics/DepthRenderQueue.hpp b/include/Nazara/Graphics/DepthRenderQueue.hpp index ed96b7d6b..0b8a1fc5d 100644 --- a/include/Nazara/Graphics/DepthRenderQueue.hpp +++ b/include/Nazara/Graphics/DepthRenderQueue.hpp @@ -18,31 +18,36 @@ #include #include -class NAZARA_GRAPHICS_API NzDepthRenderQueue : public NzForwardRenderQueue +namespace Nz { - public: - NzDepthRenderQueue(); - ~NzDepthRenderQueue() = default; + class NAZARA_GRAPHICS_API DepthRenderQueue : public ForwardRenderQueue + { + public: + DepthRenderQueue(); + ~DepthRenderQueue() = default; - void AddBillboard(const NzMaterial* material, const NzVector3f& position, const NzVector2f& size, const NzVector2f& sinCos = NzVector2f(0.f, 1.f), const NzColor& color = NzColor::White) override; - void AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr sinCosPtr = nullptr, NzSparsePtr colorPtr = nullptr) override; - void AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr sinCosPtr, NzSparsePtr alphaPtr) override; - void AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr anglePtr, NzSparsePtr colorPtr = nullptr) override; - void AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr anglePtr, NzSparsePtr alphaPtr) override; - void AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr sinCosPtr = nullptr, NzSparsePtr colorPtr = nullptr) override; - void AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr sinCosPtr, NzSparsePtr alphaPtr) override; - void AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr anglePtr, NzSparsePtr colorPtr = nullptr) override; - void AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr anglePtr, NzSparsePtr alphaPtr) override; - void AddDirectionalLight(const DirectionalLight& light) override; - void AddMesh(const NzMaterial* material, const NzMeshData& meshData, const NzBoxf& meshAABB, const NzMatrix4f& transformMatrix) override; - void AddPointLight(const PointLight& light) override; - void AddSpotLight(const SpotLight& light) override; - void AddSprites(const NzMaterial* material, const NzVertexStruct_XYZ_Color_UV* vertices, unsigned int spriteCount, const NzTexture* overlay = nullptr) override; + void AddBillboard(int renderOrder, const Material* material, const Vector3f& position, const Vector2f& size, const Vector2f& sinCos = Vector2f(0.f, 1.f), const Color& color = Color::White) override; + void AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr sinCosPtr = nullptr, SparsePtr colorPtr = nullptr) override; + void AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr sinCosPtr, SparsePtr alphaPtr) override; + void AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr anglePtr, SparsePtr colorPtr = nullptr) override; + void AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr anglePtr, SparsePtr alphaPtr) override; + void AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr sinCosPtr = nullptr, SparsePtr colorPtr = nullptr) override; + void AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr sinCosPtr, SparsePtr alphaPtr) override; + void AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr anglePtr, SparsePtr colorPtr = nullptr) override; + void AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr anglePtr, SparsePtr alphaPtr) override; + void AddDirectionalLight(const DirectionalLight& light) override; + void AddMesh(int renderOrder, const Material* material, const MeshData& meshData, const Boxf& meshAABB, const Matrix4f& transformMatrix) override; + void AddPointLight(const PointLight& light) override; + void AddSpotLight(const SpotLight& light) override; + void AddSprites(int renderOrder, const Material* material, const VertexStruct_XYZ_Color_UV* vertices, unsigned int spriteCount, const Texture* overlay = nullptr) override; - private: - bool IsMaterialSuitable(const NzMaterial* material) const; + private: + inline bool IsMaterialSuitable(const Material* material) const; - NzMaterialRef m_baseMaterial; -}; + MaterialRef m_baseMaterial; + }; +} + +#include #endif // NAZARA_DEPTHRENDERQUEUE_HPP diff --git a/include/Nazara/Graphics/DepthRenderTechnique.hpp b/include/Nazara/Graphics/DepthRenderTechnique.hpp index 9da641c3b..0b265ccc3 100644 --- a/include/Nazara/Graphics/DepthRenderTechnique.hpp +++ b/include/Nazara/Graphics/DepthRenderTechnique.hpp @@ -16,65 +16,62 @@ #include #include -class NAZARA_GRAPHICS_API NzDepthRenderTechnique : public NzAbstractRenderTechnique +namespace Nz { - public: - NzDepthRenderTechnique(); - ~NzDepthRenderTechnique() = default; + class NAZARA_GRAPHICS_API DepthRenderTechnique : public AbstractRenderTechnique + { + public: + DepthRenderTechnique(); + ~DepthRenderTechnique() = default; - bool Draw(const NzSceneData& sceneData) const override; + bool Draw(const SceneData& sceneData) const override; - NzAbstractRenderQueue* GetRenderQueue() override; - nzRenderTechniqueType GetType() const override; + AbstractRenderQueue* GetRenderQueue() override; + RenderTechniqueType GetType() const override; - static bool Initialize(); - static void Uninitialize(); + static bool Initialize(); + static void Uninitialize(); - private: - struct ShaderUniforms; + private: + struct ShaderUniforms; - void DrawBasicSprites(const NzSceneData& sceneData) const; - void DrawBillboards(const NzSceneData& sceneData) const; - void DrawOpaqueModels(const NzSceneData& sceneData) const; - const ShaderUniforms* GetShaderUniforms(const NzShader* shader) const; - void OnShaderInvalidated(const NzShader* shader) const; + void DrawBasicSprites(const SceneData& sceneData, ForwardRenderQueue::Layer& layer) const; + void DrawBillboards(const SceneData& sceneData, ForwardRenderQueue::Layer& layer) const; + void DrawOpaqueModels(const SceneData& sceneData, ForwardRenderQueue::Layer& layer) const; + const ShaderUniforms* GetShaderUniforms(const Shader* shader) const; + void OnShaderInvalidated(const Shader* shader) const; - struct LightIndex - { - nzLightType type; - float score; - unsigned int index; - }; + struct LightIndex + { + LightType type; + float score; + unsigned int index; + }; - struct ShaderUniforms - { - NazaraSlot(NzShader, OnShaderUniformInvalidated, shaderUniformInvalidatedSlot); - NazaraSlot(NzShader, OnShaderRelease, shaderReleaseSlot); + struct ShaderUniforms + { + NazaraSlot(Shader, OnShaderUniformInvalidated, shaderUniformInvalidatedSlot); + NazaraSlot(Shader, OnShaderRelease, shaderReleaseSlot); - NzLightUniforms lightUniforms; - bool hasLightUniforms; + // Autre uniformes + int eyePosition; + int sceneAmbient; + int textureOverlay; + }; - /// Moins coûteux en mémoire que de stocker un NzLightUniforms par index de lumière, - /// à voir si ça fonctionne chez tout le monde - int lightOffset; // "Distance" entre Lights[0].type et Lights[1].type + mutable std::unordered_map m_shaderUniforms; + Buffer m_vertexBuffer; + mutable DepthRenderQueue m_renderQueue; + VertexBuffer m_billboardPointBuffer; + VertexBuffer m_spriteBuffer; - // Autre uniformes - int eyePosition; - int sceneAmbient; - int textureOverlay; - }; + static IndexBuffer s_quadIndexBuffer; + static VertexBuffer s_quadVertexBuffer; + static VertexDeclaration s_billboardInstanceDeclaration; + static VertexDeclaration s_billboardVertexDeclaration; + }; +} - mutable std::unordered_map m_shaderUniforms; - NzBuffer m_vertexBuffer; - mutable NzDepthRenderQueue m_renderQueue; - NzVertexBuffer m_billboardPointBuffer; - NzVertexBuffer m_spriteBuffer; - - static NzIndexBuffer s_quadIndexBuffer; - static NzVertexBuffer s_quadVertexBuffer; - static NzVertexDeclaration s_billboardInstanceDeclaration; - static NzVertexDeclaration s_billboardVertexDeclaration; -}; #include diff --git a/src/Nazara/Graphics/DepthRenderQueue.cpp b/src/Nazara/Graphics/DepthRenderQueue.cpp index 9ff02dcbd..e6fc71ae0 100644 --- a/src/Nazara/Graphics/DepthRenderQueue.cpp +++ b/src/Nazara/Graphics/DepthRenderQueue.cpp @@ -7,203 +7,211 @@ #include #include -NzDepthRenderQueue::NzDepthRenderQueue() +namespace Nz { - // Material - m_baseMaterial = NzMaterial::New(); - m_baseMaterial->Enable(nzRendererParameter_ColorWrite, false); - m_baseMaterial->Enable(nzRendererParameter_FaceCulling, false); - //m_baseMaterial->SetFaceCulling(nzFaceSide_Front); + DepthRenderQueue::DepthRenderQueue() + { + // Material + m_baseMaterial = Material::New(); + m_baseMaterial->Enable(RendererParameter_ColorWrite, false); + m_baseMaterial->Enable(RendererParameter_FaceCulling, false); + //m_baseMaterial->SetFaceCulling(FaceSide_Front); + } + + void DepthRenderQueue::AddBillboard(int renderOrder, const Material* material, const Vector3f& position, const Vector2f& size, const Vector2f& sinCos, const Color& color) + { + NazaraAssert(material, "Invalid material"); + NazaraUnused(renderOrder); + + if (!IsMaterialSuitable(material)) + return; + + if (material->HasDepthMaterial()) + material = material->GetDepthMaterial(); + else + material = m_baseMaterial; + + ForwardRenderQueue::AddBillboard(0, material, position, size, sinCos, color); + } + + void DepthRenderQueue::AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr sinCosPtr, SparsePtr colorPtr) + { + NazaraAssert(material, "Invalid material"); + NazaraUnused(renderOrder); + + if (!IsMaterialSuitable(material)) + return; + + if (material->HasDepthMaterial()) + material = material->GetDepthMaterial(); + else + material = m_baseMaterial; + + ForwardRenderQueue::AddBillboards(0, material, count, positionPtr, sizePtr, sinCosPtr, colorPtr); + } + + void DepthRenderQueue::AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr sinCosPtr, SparsePtr alphaPtr) + { + NazaraAssert(material, "Invalid material"); + NazaraUnused(renderOrder); + + if (!IsMaterialSuitable(material)) + return; + + if (material->HasDepthMaterial()) + material = material->GetDepthMaterial(); + else + material = m_baseMaterial; + + ForwardRenderQueue::AddBillboards(0, material, count, positionPtr, sizePtr, sinCosPtr, alphaPtr); + } + + void DepthRenderQueue::AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr anglePtr, SparsePtr colorPtr) + { + NazaraAssert(material, "Invalid material"); + NazaraUnused(renderOrder); + + if (!IsMaterialSuitable(material)) + return; + + if (material->HasDepthMaterial()) + material = material->GetDepthMaterial(); + else + material = m_baseMaterial; + + ForwardRenderQueue::AddBillboards(0, material, count, positionPtr, sizePtr, anglePtr, colorPtr); + } + + void DepthRenderQueue::AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr anglePtr, SparsePtr alphaPtr) + { + NazaraAssert(material, "Invalid material"); + NazaraUnused(renderOrder); + + if (!IsMaterialSuitable(material)) + return; + + if (material->HasDepthMaterial()) + material = material->GetDepthMaterial(); + else + material = m_baseMaterial; + + ForwardRenderQueue::AddBillboards(0, material, count, positionPtr, sizePtr, anglePtr, alphaPtr); + } + + void DepthRenderQueue::AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr sinCosPtr, SparsePtr colorPtr) + { + NazaraAssert(material, "Invalid material"); + NazaraUnused(renderOrder); + + if (!IsMaterialSuitable(material)) + return; + + if (material->HasDepthMaterial()) + material = material->GetDepthMaterial(); + else + material = m_baseMaterial; + + ForwardRenderQueue::AddBillboards(0, material, count, positionPtr, sizePtr, sinCosPtr, colorPtr); + } + + void DepthRenderQueue::AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr sinCosPtr, SparsePtr alphaPtr) + { + NazaraAssert(material, "Invalid material"); + NazaraUnused(renderOrder); + + if (!IsMaterialSuitable(material)) + return; + + if (material->HasDepthMaterial()) + material = material->GetDepthMaterial(); + else + material = m_baseMaterial; + + ForwardRenderQueue::AddBillboards(0, material, count, positionPtr, sizePtr, sinCosPtr, alphaPtr); + } + + void DepthRenderQueue::AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr anglePtr, SparsePtr colorPtr) + { + NazaraAssert(material, "Invalid material"); + NazaraUnused(renderOrder); + + if (!IsMaterialSuitable(material)) + return; + + if (material->HasDepthMaterial()) + material = material->GetDepthMaterial(); + else + material = m_baseMaterial; + + ForwardRenderQueue::AddBillboards(0, material, count, positionPtr, sizePtr, anglePtr, colorPtr); + } + + void DepthRenderQueue::AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr anglePtr, SparsePtr alphaPtr) + { + NazaraAssert(material, "Invalid material"); + NazaraUnused(renderOrder); + + if (!IsMaterialSuitable(material)) + return; + + if (material->HasDepthMaterial()) + material = material->GetDepthMaterial(); + else + material = m_baseMaterial; + + ForwardRenderQueue::AddBillboards(0, material, count, positionPtr, sizePtr, anglePtr, alphaPtr); + } + + void DepthRenderQueue::AddDirectionalLight(const DirectionalLight& light) + { + NazaraAssert(false, "Depth render queue doesn't handle lights"); + NazaraUnused(light); + } + + void DepthRenderQueue::AddMesh(int renderOrder, const Material* material, const MeshData& meshData, const Boxf& meshAABB, const Matrix4f& transformMatrix) + { + NazaraAssert(material, "Invalid material"); + NazaraUnused(renderOrder); + NazaraUnused(meshAABB); + + if (!IsMaterialSuitable(material)) + return; + + if (material->HasDepthMaterial()) + material = material->GetDepthMaterial(); + else + material = m_baseMaterial; + + ForwardRenderQueue::AddMesh(0, material, meshData, meshAABB, transformMatrix); + } + + void DepthRenderQueue::AddPointLight(const PointLight& light) + { + NazaraAssert(false, "Depth render queue doesn't handle lights"); + NazaraUnused(light); + } + + void DepthRenderQueue::AddSpotLight(const SpotLight& light) + { + NazaraAssert(false, "Depth render queue doesn't handle lights"); + NazaraUnused(light); + } + + void DepthRenderQueue::AddSprites(int renderOrder, const Material* material, const VertexStruct_XYZ_Color_UV* vertices, unsigned int spriteCount, const Texture* overlay) + { + NazaraAssert(material, "Invalid material"); + NazaraUnused(renderOrder); + NazaraUnused(overlay); + + if (!IsMaterialSuitable(material)) + return; + + if (material->HasDepthMaterial()) + material = material->GetDepthMaterial(); + else + material = m_baseMaterial; + + ForwardRenderQueue::AddSprites(0, material, vertices, spriteCount, overlay); + } } -void NzDepthRenderQueue::AddBillboard(const NzMaterial* material, const NzVector3f& position, const NzVector2f& size, const NzVector2f& sinCos, const NzColor& color) -{ - NazaraAssert(material, "Invalid material"); - - if (!IsMaterialSuitable(material)) - return; - - if (material->HasDepthMaterial()) - material = material->GetDepthMaterial(); - else - material = m_baseMaterial; - - NzForwardRenderQueue::AddBillboard(material, position, size, sinCos, color); -} - -void NzDepthRenderQueue::AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr sinCosPtr, NzSparsePtr colorPtr) -{ - NazaraAssert(material, "Invalid material"); - - if (!IsMaterialSuitable(material)) - return; - - if (material->HasDepthMaterial()) - material = material->GetDepthMaterial(); - else - material = m_baseMaterial; - - NzForwardRenderQueue::AddBillboards(material, count, positionPtr, sizePtr, sinCosPtr, colorPtr); -} - -void NzDepthRenderQueue::AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr sinCosPtr, NzSparsePtr alphaPtr) -{ - NazaraAssert(material, "Invalid material"); - - if (!IsMaterialSuitable(material)) - return; - - if (material->HasDepthMaterial()) - material = material->GetDepthMaterial(); - else - material = m_baseMaterial; - - NzForwardRenderQueue::AddBillboards(material, count, positionPtr, sizePtr, sinCosPtr, alphaPtr); -} - -void NzDepthRenderQueue::AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr anglePtr, NzSparsePtr colorPtr) -{ - NazaraAssert(material, "Invalid material"); - - if (!IsMaterialSuitable(material)) - return; - - if (material->HasDepthMaterial()) - material = material->GetDepthMaterial(); - else - material = m_baseMaterial; - - NzForwardRenderQueue::AddBillboards(material, count, positionPtr, sizePtr, anglePtr, colorPtr); -} - -void NzDepthRenderQueue::AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr anglePtr, NzSparsePtr alphaPtr) -{ - NazaraAssert(material, "Invalid material"); - - if (!IsMaterialSuitable(material)) - return; - - if (material->HasDepthMaterial()) - material = material->GetDepthMaterial(); - else - material = m_baseMaterial; - - NzForwardRenderQueue::AddBillboards(material, count, positionPtr, sizePtr, anglePtr, alphaPtr); -} - -void NzDepthRenderQueue::AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr sinCosPtr, NzSparsePtr colorPtr) -{ - NazaraAssert(material, "Invalid material"); - - if (!IsMaterialSuitable(material)) - return; - - if (material->HasDepthMaterial()) - material = material->GetDepthMaterial(); - else - material = m_baseMaterial; - - NzForwardRenderQueue::AddBillboards(material, count, positionPtr, sizePtr, sinCosPtr, colorPtr); -} - -void NzDepthRenderQueue::AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr sinCosPtr, NzSparsePtr alphaPtr) -{ - NazaraAssert(material, "Invalid material"); - - if (!IsMaterialSuitable(material)) - return; - - if (material->HasDepthMaterial()) - material = material->GetDepthMaterial(); - else - material = m_baseMaterial; - - NzForwardRenderQueue::AddBillboards(material, count, positionPtr, sizePtr, sinCosPtr, alphaPtr); -} - -void NzDepthRenderQueue::AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr anglePtr, NzSparsePtr colorPtr) -{ - NazaraAssert(material, "Invalid material"); - - if (!IsMaterialSuitable(material)) - return; - - if (material->HasDepthMaterial()) - material = material->GetDepthMaterial(); - else - material = m_baseMaterial; - - NzForwardRenderQueue::AddBillboards(material, count, positionPtr, sizePtr, anglePtr, colorPtr); -} - -void NzDepthRenderQueue::AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr anglePtr, NzSparsePtr alphaPtr) -{ - NazaraAssert(material, "Invalid material"); - - if (!IsMaterialSuitable(material)) - return; - - if (material->HasDepthMaterial()) - material = material->GetDepthMaterial(); - else - material = m_baseMaterial; - - NzForwardRenderQueue::AddBillboards(material, count, positionPtr, sizePtr, anglePtr, alphaPtr); -} - -void NzDepthRenderQueue::AddDirectionalLight(const DirectionalLight& light) -{ - NazaraAssert(false, "Depth render queue doesn't handle lights"); - NazaraUnused(light); -} - -void NzDepthRenderQueue::AddMesh(const NzMaterial* material, const NzMeshData& meshData, const NzBoxf& meshAABB, const NzMatrix4f& transformMatrix) -{ - NazaraAssert(material, "Invalid material"); - NazaraUnused(meshAABB); - - if (!IsMaterialSuitable(material)) - return; - - if (material->HasDepthMaterial()) - material = material->GetDepthMaterial(); - else - material = m_baseMaterial; - - NzForwardRenderQueue::AddMesh(material, meshData, meshAABB, transformMatrix); -} - -void NzDepthRenderQueue::AddPointLight(const PointLight& light) -{ - NazaraAssert(false, "Depth render queue doesn't handle lights"); - NazaraUnused(light); -} - -void NzDepthRenderQueue::AddSpotLight(const SpotLight& light) -{ - NazaraAssert(false, "Depth render queue doesn't handle lights"); - NazaraUnused(light); -} - -void NzDepthRenderQueue::AddSprites(const NzMaterial* material, const NzVertexStruct_XYZ_Color_UV* vertices, unsigned int spriteCount, const NzTexture* overlay) -{ - NazaraAssert(material, "Invalid material"); - NazaraUnused(overlay); - - if (!IsMaterialSuitable(material)) - return; - - if (material->HasDepthMaterial()) - material = material->GetDepthMaterial(); - else - material = m_baseMaterial; - - NzForwardRenderQueue::AddSprites(material, vertices, spriteCount, overlay); -} - -bool NzDepthRenderQueue::IsMaterialSuitable(const NzMaterial* material) const -{ - NazaraAssert(material, "Invalid material"); - - return material->HasDepthMaterial() || (material->IsEnabled(nzRendererParameter_DepthBuffer) && material->IsEnabled(nzRendererParameter_DepthWrite) && material->IsShadowCastingEnabled()); -} diff --git a/src/Nazara/Graphics/DepthRenderTechnique.cpp b/src/Nazara/Graphics/DepthRenderTechnique.cpp index 31d63d56a..107043bce 100644 --- a/src/Nazara/Graphics/DepthRenderTechnique.cpp +++ b/src/Nazara/Graphics/DepthRenderTechnique.cpp @@ -20,173 +20,269 @@ #include #include -namespace +namespace Nz { - struct BillboardPoint + namespace { - NzColor color; - NzVector3f position; - NzVector2f size; - NzVector2f sinCos; // must follow `size` (both will be sent as a Vector4f) - NzVector2f uv; - }; - - unsigned int s_maxQuads = std::numeric_limits::max()/6; - unsigned int s_vertexBufferSize = 4*1024*1024; // 4 MiB -} - -NzDepthRenderTechnique::NzDepthRenderTechnique() : -m_vertexBuffer(nzBufferType_Vertex) -{ - NzErrorFlags flags(nzErrorFlag_ThrowException, true); - - m_vertexBuffer.Create(s_vertexBufferSize, nzDataStorage_Hardware, nzBufferUsage_Dynamic); - - m_billboardPointBuffer.Reset(&s_billboardVertexDeclaration, &m_vertexBuffer); - m_spriteBuffer.Reset(NzVertexDeclaration::Get(nzVertexLayout_XYZ_Color_UV), &m_vertexBuffer); -} - -bool NzDepthRenderTechnique::Draw(const NzSceneData& sceneData) const -{ - NzRenderer::Enable(nzRendererParameter_DepthBuffer, true); - NzRenderer::Enable(nzRendererParameter_DepthWrite, true); - NzRenderer::Clear(nzRendererBuffer_Depth); - - // Just in case the background does render depth - if (sceneData.background) - sceneData.background->Draw(sceneData.viewer); - - if (!m_renderQueue.opaqueModels.empty()) - DrawOpaqueModels(sceneData); - - if (!m_renderQueue.basicSprites.empty()) - DrawBasicSprites(sceneData); - - if (!m_renderQueue.billboards.empty()) - DrawBillboards(sceneData); - - // Other custom drawables - for (const NzDrawable* drawable : m_renderQueue.otherDrawables) - drawable->Draw(); - - return true; -} - -NzAbstractRenderQueue* NzDepthRenderTechnique::GetRenderQueue() -{ - return &m_renderQueue; -} - -nzRenderTechniqueType NzDepthRenderTechnique::GetType() const -{ - return nzRenderTechniqueType_Depth; -} - -bool NzDepthRenderTechnique::Initialize() -{ - try - { - NzErrorFlags flags(nzErrorFlag_ThrowException, true); - - s_quadIndexBuffer.Reset(false, s_maxQuads*6, nzDataStorage_Hardware, nzBufferUsage_Static); - - NzBufferMapper mapper(s_quadIndexBuffer, nzBufferAccess_WriteOnly); - nzUInt16* indices = static_cast(mapper.GetPointer()); - - for (unsigned int i = 0; i < s_maxQuads; ++i) + struct BillboardPoint { - *indices++ = i*4 + 0; - *indices++ = i*4 + 2; - *indices++ = i*4 + 1; - - *indices++ = i*4 + 2; - *indices++ = i*4 + 3; - *indices++ = i*4 + 1; - } - - mapper.Unmap(); // Inutile de garder le buffer ouvert plus longtemps - - // Quad buffer (utilisé pour l'instancing de billboard et de sprites) - //Note: Les UV sont calculés dans le shader - s_quadVertexBuffer.Reset(NzVertexDeclaration::Get(nzVertexLayout_XY), 4, nzDataStorage_Hardware, nzBufferUsage_Static); - - float vertices[2*4] = { - -0.5f, -0.5f, - 0.5f, -0.5f, - -0.5f, 0.5f, - 0.5f, 0.5f, + Color color; + Vector3f position; + Vector2f size; + Vector2f sinCos; // must follow `size` (both will be sent as a Vector4f) + Vector2f uv; }; - s_quadVertexBuffer.FillRaw(vertices, 0, sizeof(vertices)); - - // Déclaration lors du rendu des billboards par sommet - s_billboardVertexDeclaration.EnableComponent(nzVertexComponent_Color, nzComponentType_Color, NzOffsetOf(BillboardPoint, color)); - s_billboardVertexDeclaration.EnableComponent(nzVertexComponent_Position, nzComponentType_Float3, NzOffsetOf(BillboardPoint, position)); - s_billboardVertexDeclaration.EnableComponent(nzVertexComponent_TexCoord, nzComponentType_Float2, NzOffsetOf(BillboardPoint, uv)); - s_billboardVertexDeclaration.EnableComponent(nzVertexComponent_Userdata0, nzComponentType_Float4, NzOffsetOf(BillboardPoint, size)); // Englobe sincos - - // Declaration utilisée lors du rendu des billboards par instancing - // L'avantage ici est la copie directe (std::memcpy) des données de la RenderQueue vers le buffer GPU - s_billboardInstanceDeclaration.EnableComponent(nzVertexComponent_InstanceData0, nzComponentType_Float3, NzOffsetOf(NzForwardRenderQueue::BillboardData, center)); - s_billboardInstanceDeclaration.EnableComponent(nzVertexComponent_InstanceData1, nzComponentType_Float4, NzOffsetOf(NzForwardRenderQueue::BillboardData, size)); // Englobe sincos - s_billboardInstanceDeclaration.EnableComponent(nzVertexComponent_InstanceData2, nzComponentType_Color, NzOffsetOf(NzForwardRenderQueue::BillboardData, color)); - } - catch (const std::exception& e) - { - NazaraError("Failed to initialise: " + NzString(e.what())); - return false; + unsigned int s_maxQuads = std::numeric_limits::max() / 6; + unsigned int s_vertexBufferSize = 4 * 1024 * 1024; // 4 MiB } - return true; -} - -void NzDepthRenderTechnique::Uninitialize() -{ - s_quadIndexBuffer.Reset(); - s_quadVertexBuffer.Reset(); -} - -void NzDepthRenderTechnique::DrawBasicSprites(const NzSceneData& sceneData) const -{ - NazaraUnused(sceneData); - - const NzShader* lastShader = nullptr; - const ShaderUniforms* shaderUniforms = nullptr; - - NzRenderer::SetIndexBuffer(&s_quadIndexBuffer); - NzRenderer::SetMatrix(nzMatrixType_World, NzMatrix4f::Identity()); - NzRenderer::SetVertexBuffer(&m_spriteBuffer); - - for (auto& matIt : m_renderQueue.basicSprites) + DepthRenderTechnique::DepthRenderTechnique() : + m_vertexBuffer(BufferType_Vertex) { - const NzMaterial* material = matIt.first; - auto& matEntry = matIt.second; + ErrorFlags flags(ErrorFlag_ThrowException, true); - if (matEntry.enabled) + m_vertexBuffer.Create(s_vertexBufferSize, DataStorage_Hardware, BufferUsage_Dynamic); + + m_billboardPointBuffer.Reset(&s_billboardVertexDeclaration, &m_vertexBuffer); + m_spriteBuffer.Reset(VertexDeclaration::Get(VertexLayout_XYZ_Color_UV), &m_vertexBuffer); + } + + bool DepthRenderTechnique::Draw(const SceneData& sceneData) const + { + Renderer::Enable(RendererParameter_DepthBuffer, true); + Renderer::Enable(RendererParameter_DepthWrite, true); + Renderer::Clear(RendererBuffer_Depth); + + // Just in case the background does render depth + if (sceneData.background) + sceneData.background->Draw(sceneData.viewer); + + for (auto& pair : m_renderQueue.layers) { - auto& overlayMap = matEntry.overlayMap; - for (auto& overlayIt : overlayMap) - { - const NzTexture* overlay = overlayIt.first; - auto& spriteChainVector = overlayIt.second.spriteChains; + ForwardRenderQueue::Layer& layer = pair.second; - unsigned int spriteChainCount = spriteChainVector.size(); - if (spriteChainCount > 0) + if (!layer.opaqueModels.empty()) + DrawOpaqueModels(sceneData, layer); + + if (!layer.basicSprites.empty()) + DrawBasicSprites(sceneData, layer); + + if (!layer.billboards.empty()) + DrawBillboards(sceneData, layer); + + for (const Drawable* drawable : layer.otherDrawables) + drawable->Draw(); + } + + return true; + } + + AbstractRenderQueue* DepthRenderTechnique::GetRenderQueue() + { + return &m_renderQueue; + } + + RenderTechniqueType DepthRenderTechnique::GetType() const + { + return RenderTechniqueType_Depth; + } + + bool DepthRenderTechnique::Initialize() + { + try + { + ErrorFlags flags(ErrorFlag_ThrowException, true); + + s_quadIndexBuffer.Reset(false, s_maxQuads * 6, DataStorage_Hardware, BufferUsage_Static); + + BufferMapper mapper(s_quadIndexBuffer, BufferAccess_WriteOnly); + UInt16* indices = static_cast(mapper.GetPointer()); + + for (unsigned int i = 0; i < s_maxQuads; ++i) + { + *indices++ = i * 4 + 0; + *indices++ = i * 4 + 2; + *indices++ = i * 4 + 1; + + *indices++ = i * 4 + 2; + *indices++ = i * 4 + 3; + *indices++ = i * 4 + 1; + } + + mapper.Unmap(); // Inutile de garder le buffer ouvert plus longtemps + + // Quad buffer (utilisé pour l'instancing de billboard et de sprites) + //Note: Les UV sont calculés dans le shader + s_quadVertexBuffer.Reset(VertexDeclaration::Get(VertexLayout_XY), 4, DataStorage_Hardware, BufferUsage_Static); + + float vertices[2 * 4] = { + -0.5f, -0.5f, + 0.5f, -0.5f, + -0.5f, 0.5f, + 0.5f, 0.5f, + }; + + s_quadVertexBuffer.FillRaw(vertices, 0, sizeof(vertices)); + + // Déclaration lors du rendu des billboards par sommet + s_billboardVertexDeclaration.EnableComponent(VertexComponent_Color, ComponentType_Color, NazaraOffsetOf(BillboardPoint, color)); + s_billboardVertexDeclaration.EnableComponent(VertexComponent_Position, ComponentType_Float3, NazaraOffsetOf(BillboardPoint, position)); + s_billboardVertexDeclaration.EnableComponent(VertexComponent_TexCoord, ComponentType_Float2, NazaraOffsetOf(BillboardPoint, uv)); + s_billboardVertexDeclaration.EnableComponent(VertexComponent_Userdata0, ComponentType_Float4, NazaraOffsetOf(BillboardPoint, size)); // Englobe sincos + + // Declaration utilisée lors du rendu des billboards par instancing + // L'avantage ici est la copie directe (std::memcpy) des données de la RenderQueue vers le buffer GPU + s_billboardInstanceDeclaration.EnableComponent(VertexComponent_InstanceData0, ComponentType_Float3, NazaraOffsetOf(ForwardRenderQueue::BillboardData, center)); + s_billboardInstanceDeclaration.EnableComponent(VertexComponent_InstanceData1, ComponentType_Float4, NazaraOffsetOf(ForwardRenderQueue::BillboardData, size)); // Englobe sincos + s_billboardInstanceDeclaration.EnableComponent(VertexComponent_InstanceData2, ComponentType_Color, NazaraOffsetOf(ForwardRenderQueue::BillboardData, color)); + } + catch (const std::exception& e) + { + NazaraError("Failed to initialise: " + String(e.what())); + return false; + } + + return true; + } + + void DepthRenderTechnique::Uninitialize() + { + s_quadIndexBuffer.Reset(); + s_quadVertexBuffer.Reset(); + } + + void DepthRenderTechnique::DrawBasicSprites(const SceneData& sceneData, ForwardRenderQueue::Layer& layer) const + { + NazaraAssert(sceneData.viewer, "Invalid viewer"); + + const Shader* lastShader = nullptr; + const ShaderUniforms* shaderUniforms = nullptr; + + Renderer::SetIndexBuffer(&s_quadIndexBuffer); + Renderer::SetMatrix(MatrixType_World, Matrix4f::Identity()); + Renderer::SetVertexBuffer(&m_spriteBuffer); + + for (auto& matIt : layer.basicSprites) + { + const Material* material = matIt.first; + auto& matEntry = matIt.second; + + if (matEntry.enabled) + { + auto& overlayMap = matEntry.overlayMap; + for (auto& overlayIt : overlayMap) + { + const Texture* overlay = overlayIt.first; + auto& spriteChainVector = overlayIt.second.spriteChains; + + unsigned int spriteChainCount = spriteChainVector.size(); + if (spriteChainCount > 0) + { + // On commence par appliquer du matériau (et récupérer le shader ainsi activé) + UInt32 flags = ShaderFlags_VertexColor; + if (overlay) + flags |= ShaderFlags_TextureOverlay; + + UInt8 overlayUnit; + const Shader* shader = material->Apply(flags, 0, &overlayUnit); + + if (overlay) + { + overlayUnit++; + Renderer::SetTexture(overlayUnit, overlay); + Renderer::SetTextureSampler(overlayUnit, material->GetDiffuseSampler()); + } + + // Les uniformes sont conservées au sein d'un programme, inutile de les renvoyer tant qu'il ne change pas + if (shader != lastShader) + { + // Index des uniformes dans le shader + shaderUniforms = GetShaderUniforms(shader); + + // Couleur ambiante de la scène + shader->SendColor(shaderUniforms->sceneAmbient, sceneData.ambientColor); + // Overlay + shader->SendInteger(shaderUniforms->textureOverlay, overlayUnit); + // Position de la caméra + shader->SendVector(shaderUniforms->eyePosition, sceneData.viewer->GetEyePosition()); + + lastShader = shader; + } + + unsigned int spriteChain = 0; // Quelle chaîne de sprite traitons-nous + unsigned int spriteChainOffset = 0; // À quel offset dans la dernière chaîne nous sommes-nous arrêtés + + do + { + // On ouvre le buffer en écriture + BufferMapper vertexMapper(m_spriteBuffer, BufferAccess_DiscardAndWrite); + VertexStruct_XYZ_Color_UV* vertices = reinterpret_cast(vertexMapper.GetPointer()); + + unsigned int spriteCount = 0; + unsigned int maxSpriteCount = std::min(s_maxQuads, m_spriteBuffer.GetVertexCount()/4); + + do + { + ForwardRenderQueue::SpriteChain_XYZ_Color_UV& currentChain = spriteChainVector[spriteChain]; + unsigned int count = std::min(maxSpriteCount - spriteCount, currentChain.spriteCount - spriteChainOffset); + + std::memcpy(vertices, currentChain.vertices + spriteChainOffset*4, 4*count*sizeof(VertexStruct_XYZ_Color_UV)); + vertices += count*4; + + spriteCount += count; + spriteChainOffset += count; + + // Avons-nous traité la chaîne entière ? + if (spriteChainOffset == currentChain.spriteCount) + { + spriteChain++; + spriteChainOffset = 0; + } + } + while (spriteCount < maxSpriteCount && spriteChain < spriteChainCount); + + vertexMapper.Unmap(); + + Renderer::DrawIndexedPrimitives(PrimitiveMode_TriangleList, 0, spriteCount*6); + } + while (spriteChain < spriteChainCount); + + spriteChainVector.clear(); + } + } + + // On remet à zéro + matEntry.enabled = false; + } + } + } + + void DepthRenderTechnique::DrawBillboards(const SceneData& sceneData, ForwardRenderQueue::Layer& layer) const + { + NazaraAssert(sceneData.viewer, "Invalid viewer"); + + const Shader* lastShader = nullptr; + const ShaderUniforms* shaderUniforms = nullptr; + + if (Renderer::HasCapability(RendererCap_Instancing)) + { + VertexBuffer* instanceBuffer = Renderer::GetInstanceBuffer(); + instanceBuffer->SetVertexDeclaration(&s_billboardInstanceDeclaration); + + Renderer::SetVertexBuffer(&s_quadVertexBuffer); + + for (auto& matIt : layer.billboards) + { + const Material* material = matIt.first; + auto& entry = matIt.second; + auto& billboardVector = entry.billboards; + + unsigned int billboardCount = billboardVector.size(); + if (billboardCount > 0) { // On commence par appliquer du matériau (et récupérer le shader ainsi activé) - nzUInt32 flags = nzShaderFlags_VertexColor; - if (overlay) - flags |= nzShaderFlags_TextureOverlay; - - nzUInt8 overlayUnit; - const NzShader* shader = material->Apply(flags, 0, &overlayUnit); - - if (overlay) - { - overlayUnit++; - NzRenderer::SetTexture(overlayUnit, overlay); - NzRenderer::SetTextureSampler(overlayUnit, material->GetDiffuseSampler()); - } + const Shader* shader = material->Apply(ShaderFlags_Billboard | ShaderFlags_Instancing | ShaderFlags_VertexColor); // Les uniformes sont conservées au sein d'un programme, inutile de les renvoyer tant qu'il ne change pas if (shader != lastShader) @@ -194,302 +290,260 @@ void NzDepthRenderTechnique::DrawBasicSprites(const NzSceneData& sceneData) cons // Index des uniformes dans le shader shaderUniforms = GetShaderUniforms(shader); - // Overlay - shader->SendInteger(shaderUniforms->textureOverlay, overlayUnit); + // Couleur ambiante de la scène + shader->SendColor(shaderUniforms->sceneAmbient, sceneData.ambientColor); + // Position de la caméra + shader->SendVector(shaderUniforms->eyePosition, sceneData.viewer->GetEyePosition()); lastShader = shader; } - unsigned int spriteChain = 0; // Quelle chaîne de sprite traitons-nous - unsigned int spriteChainOffset = 0; // À quel offset dans la dernière chaîne nous sommes-nous arrêtés + const ForwardRenderQueue::BillboardData* data = &billboardVector[0]; + unsigned int maxBillboardPerDraw = instanceBuffer->GetVertexCount(); + do + { + unsigned int renderedBillboardCount = std::min(billboardCount, maxBillboardPerDraw); + billboardCount -= renderedBillboardCount; + + instanceBuffer->Fill(data, 0, renderedBillboardCount, true); + data += renderedBillboardCount; + + Renderer::DrawPrimitivesInstanced(renderedBillboardCount, PrimitiveMode_TriangleStrip, 0, 4); + } + while (billboardCount > 0); + + billboardVector.clear(); + } + } + } + else + { + Renderer::SetIndexBuffer(&s_quadIndexBuffer); + Renderer::SetVertexBuffer(&m_billboardPointBuffer); + + for (auto& matIt : layer.billboards) + { + const Material* material = matIt.first; + auto& entry = matIt.second; + auto& billboardVector = entry.billboards; + + unsigned int billboardCount = billboardVector.size(); + if (billboardCount > 0) + { + // On commence par appliquer du matériau (et récupérer le shader ainsi activé) + const Shader* shader = material->Apply(ShaderFlags_Billboard | ShaderFlags_VertexColor); + + // Les uniformes sont conservées au sein d'un programme, inutile de les renvoyer tant qu'il ne change pas + if (shader != lastShader) + { + // Index des uniformes dans le shader + shaderUniforms = GetShaderUniforms(shader); + + // Couleur ambiante de la scène + shader->SendColor(shaderUniforms->sceneAmbient, sceneData.ambientColor); + // Position de la caméra + shader->SendVector(shaderUniforms->eyePosition, sceneData.viewer->GetEyePosition()); + + lastShader = shader; + } + + const ForwardRenderQueue::BillboardData* data = &billboardVector[0]; + unsigned int maxBillboardPerDraw = std::min(s_maxQuads, m_billboardPointBuffer.GetVertexCount()/4); do { - // On ouvre le buffer en écriture - NzBufferMapper vertexMapper(m_spriteBuffer, nzBufferAccess_DiscardAndWrite); - NzVertexStruct_XYZ_Color_UV* vertices = reinterpret_cast(vertexMapper.GetPointer()); + unsigned int renderedBillboardCount = std::min(billboardCount, maxBillboardPerDraw); + billboardCount -= renderedBillboardCount; - unsigned int spriteCount = 0; - unsigned int maxSpriteCount = std::min(s_maxQuads, m_spriteBuffer.GetVertexCount()/4); + BufferMapper vertexMapper(m_billboardPointBuffer, BufferAccess_DiscardAndWrite, 0, renderedBillboardCount*4); + BillboardPoint* vertices = reinterpret_cast(vertexMapper.GetPointer()); - do + for (unsigned int i = 0; i < renderedBillboardCount; ++i) { - NzForwardRenderQueue::SpriteChain_XYZ_Color_UV& currentChain = spriteChainVector[spriteChain]; - unsigned int count = std::min(maxSpriteCount - spriteCount, currentChain.spriteCount - spriteChainOffset); + const ForwardRenderQueue::BillboardData& billboard = *data++; - std::memcpy(vertices, currentChain.vertices + spriteChainOffset*4, 4*count*sizeof(NzVertexStruct_XYZ_Color_UV)); - vertices += count*4; + vertices->color = billboard.color; + vertices->position = billboard.center; + vertices->sinCos = billboard.sinCos; + vertices->size = billboard.size; + vertices->uv.Set(0.f, 1.f); + vertices++; - spriteCount += count; - spriteChainOffset += count; + vertices->color = billboard.color; + vertices->position = billboard.center; + vertices->sinCos = billboard.sinCos; + vertices->size = billboard.size; + vertices->uv.Set(1.f, 1.f); + vertices++; - // Avons-nous traité la chaîne entière ? - if (spriteChainOffset == currentChain.spriteCount) - { - spriteChain++; - spriteChainOffset = 0; - } + vertices->color = billboard.color; + vertices->position = billboard.center; + vertices->sinCos = billboard.sinCos; + vertices->size = billboard.size; + vertices->uv.Set(0.f, 0.f); + vertices++; + + vertices->color = billboard.color; + vertices->position = billboard.center; + vertices->sinCos = billboard.sinCos; + vertices->size = billboard.size; + vertices->uv.Set(1.f, 0.f); + vertices++; } - while (spriteCount < maxSpriteCount && spriteChain < spriteChainCount); vertexMapper.Unmap(); - NzRenderer::DrawIndexedPrimitives(nzPrimitiveMode_TriangleList, 0, spriteCount*6); + Renderer::DrawIndexedPrimitives(PrimitiveMode_TriangleList, 0, renderedBillboardCount*6); } - while (spriteChain < spriteChainCount); + while (billboardCount > 0); - spriteChainVector.clear(); + billboardVector.clear(); } } - - // On remet à zéro - matEntry.enabled = false; - } - } -} - -void NzDepthRenderTechnique::DrawBillboards(const NzSceneData& sceneData) const -{ - NazaraUnused(sceneData); - - if (NzRenderer::HasCapability(nzRendererCap_Instancing)) - { - NzVertexBuffer* instanceBuffer = NzRenderer::GetInstanceBuffer(); - instanceBuffer->SetVertexDeclaration(&s_billboardInstanceDeclaration); - - NzRenderer::SetVertexBuffer(&s_quadVertexBuffer); - - for (auto& matIt : m_renderQueue.billboards) - { - const NzMaterial* material = matIt.first; - auto& entry = matIt.second; - auto& billboardVector = entry.billboards; - - unsigned int billboardCount = billboardVector.size(); - if (billboardCount > 0) - { - // On commence par appliquer du matériau - material->Apply(nzShaderFlags_Billboard | nzShaderFlags_Instancing | nzShaderFlags_VertexColor); - - const NzForwardRenderQueue::BillboardData* data = &billboardVector[0]; - unsigned int maxBillboardPerDraw = instanceBuffer->GetVertexCount(); - do - { - unsigned int renderedBillboardCount = std::min(billboardCount, maxBillboardPerDraw); - billboardCount -= renderedBillboardCount; - - instanceBuffer->Fill(data, 0, renderedBillboardCount, true); - data += renderedBillboardCount; - - NzRenderer::DrawPrimitivesInstanced(renderedBillboardCount, nzPrimitiveMode_TriangleStrip, 0, 4); - } - while (billboardCount > 0); - - billboardVector.clear(); - } } } - else + + void DepthRenderTechnique::DrawOpaqueModels(const SceneData& sceneData, ForwardRenderQueue::Layer& layer) const { - NzRenderer::SetIndexBuffer(&s_quadIndexBuffer); - NzRenderer::SetVertexBuffer(&m_billboardPointBuffer); + NazaraAssert(sceneData.viewer, "Invalid viewer"); - for (auto& matIt : m_renderQueue.billboards) + const Shader* lastShader = nullptr; + const ShaderUniforms* shaderUniforms = nullptr; + + for (auto& matIt : layer.opaqueModels) { - const NzMaterial* material = matIt.first; - auto& entry = matIt.second; - auto& billboardVector = entry.billboards; + auto& matEntry = matIt.second; - unsigned int billboardCount = billboardVector.size(); - if (billboardCount > 0) + if (matEntry.enabled) { - // On commence par appliquer du matériau - material->Apply(nzShaderFlags_Billboard | nzShaderFlags_VertexColor); + ForwardRenderQueue::MeshInstanceContainer& meshInstances = matEntry.meshMap; - const NzForwardRenderQueue::BillboardData* data = &billboardVector[0]; - unsigned int maxBillboardPerDraw = std::min(s_maxQuads, m_billboardPointBuffer.GetVertexCount()/4); - - do + if (!meshInstances.empty()) { - unsigned int renderedBillboardCount = std::min(billboardCount, maxBillboardPerDraw); - billboardCount -= renderedBillboardCount; + const Material* material = matIt.first; - NzBufferMapper vertexMapper(m_billboardPointBuffer, nzBufferAccess_DiscardAndWrite, 0, renderedBillboardCount*4); - BillboardPoint* vertices = reinterpret_cast(vertexMapper.GetPointer()); + bool instancing = m_instancingEnabled && matEntry.instancingEnabled; - for (unsigned int i = 0; i < renderedBillboardCount; ++i) + // On commence par appliquer du matériau (et récupérer le shader ainsi activé) + UInt8 freeTextureUnit; + const Shader* shader = material->Apply((instancing) ? ShaderFlags_Instancing : 0, 0, &freeTextureUnit); + + // Les uniformes sont conservées au sein d'un programme, inutile de les renvoyer tant qu'il ne change pas + if (shader != lastShader) { - const NzForwardRenderQueue::BillboardData& billboard = *data++; - - vertices->color = billboard.color; - vertices->position = billboard.center; - vertices->sinCos = billboard.sinCos; - vertices->size = billboard.size; - vertices->uv.Set(0.f, 1.f); - vertices++; - - vertices->color = billboard.color; - vertices->position = billboard.center; - vertices->sinCos = billboard.sinCos; - vertices->size = billboard.size; - vertices->uv.Set(1.f, 1.f); - vertices++; - - vertices->color = billboard.color; - vertices->position = billboard.center; - vertices->sinCos = billboard.sinCos; - vertices->size = billboard.size; - vertices->uv.Set(0.f, 0.f); - vertices++; - - vertices->color = billboard.color; - vertices->position = billboard.center; - vertices->sinCos = billboard.sinCos; - vertices->size = billboard.size; - vertices->uv.Set(1.f, 0.f); - vertices++; + // Index des uniformes dans le shader + shaderUniforms = GetShaderUniforms(shader); + lastShader = shader; } - vertexMapper.Unmap(); - - NzRenderer::DrawIndexedPrimitives(nzPrimitiveMode_TriangleList, 0, renderedBillboardCount*6); - } - while (billboardCount > 0); - - billboardVector.clear(); - } - } - } -} - -void NzDepthRenderTechnique::DrawOpaqueModels(const NzSceneData& sceneData) const -{ - NazaraUnused(sceneData); - - for (auto& matIt : m_renderQueue.opaqueModels) - { - auto& matEntry = matIt.second; - - if (matEntry.enabled) - { - NzForwardRenderQueue::MeshInstanceContainer& meshInstances = matEntry.meshMap; - - if (!meshInstances.empty()) - { - const NzMaterial* material = matIt.first; - - // Nous utilisons de l'instancing que lorsqu'aucune lumière (autre que directionnelle) n'est active - // Ceci car l'instancing n'est pas compatible avec la recherche des lumières les plus proches - // (Le deferred shading n'a pas ce problème) - bool noPointSpotLight = m_renderQueue.pointLights.empty() && m_renderQueue.spotLights.empty(); - bool instancing = m_instancingEnabled && (!material->IsLightingEnabled() || noPointSpotLight) && matEntry.instancingEnabled; - - // On commence par appliquer du matériau (et récupérer le shader ainsi activé) - material->Apply((instancing) ? nzShaderFlags_Instancing : 0); - - // Meshes - for (auto& meshIt : meshInstances) - { - const NzMeshData& meshData = meshIt.first; - auto& meshEntry = meshIt.second; - - std::vector& instances = meshEntry.instances; - if (!instances.empty()) + // Meshes + for (auto& meshIt : meshInstances) { - const NzIndexBuffer* indexBuffer = meshData.indexBuffer; - const NzVertexBuffer* vertexBuffer = meshData.vertexBuffer; + const MeshData& meshData = meshIt.first; + auto& meshEntry = meshIt.second; - // Gestion du draw call avant la boucle de rendu - NzRenderer::DrawCall drawFunc; - NzRenderer::DrawCallInstanced instancedDrawFunc; - unsigned int indexCount; + const Spheref& squaredBoundingSphere = meshEntry.squaredBoundingSphere; + std::vector& instances = meshEntry.instances; - if (indexBuffer) + if (!instances.empty()) { - drawFunc = NzRenderer::DrawIndexedPrimitives; - instancedDrawFunc = NzRenderer::DrawIndexedPrimitivesInstanced; - indexCount = indexBuffer->GetIndexCount(); - } - else - { - drawFunc = NzRenderer::DrawPrimitives; - instancedDrawFunc = NzRenderer::DrawPrimitivesInstanced; - indexCount = vertexBuffer->GetVertexCount(); - } + const IndexBuffer* indexBuffer = meshData.indexBuffer; + const VertexBuffer* vertexBuffer = meshData.vertexBuffer; - NzRenderer::SetIndexBuffer(indexBuffer); - NzRenderer::SetVertexBuffer(vertexBuffer); + // Gestion du draw call avant la boucle de rendu + Renderer::DrawCall drawFunc; + Renderer::DrawCallInstanced instancedDrawFunc; + unsigned int indexCount; - if (instancing) - { - // On calcule le nombre d'instances que l'on pourra afficher cette fois-ci (Selon la taille du buffer d'instancing) - NzVertexBuffer* instanceBuffer = NzRenderer::GetInstanceBuffer(); - instanceBuffer->SetVertexDeclaration(NzVertexDeclaration::Get(nzVertexLayout_Matrix4)); + if (indexBuffer) + { + drawFunc = Renderer::DrawIndexedPrimitives; + instancedDrawFunc = Renderer::DrawIndexedPrimitivesInstanced; + indexCount = indexBuffer->GetIndexCount(); + } + else + { + drawFunc = Renderer::DrawPrimitives; + instancedDrawFunc = Renderer::DrawPrimitivesInstanced; + indexCount = vertexBuffer->GetVertexCount(); + } - const NzMatrix4f* instanceMatrices = &instances[0]; - unsigned int instanceCount = instances.size(); - unsigned int maxInstanceCount = instanceBuffer->GetVertexCount(); // Le nombre maximum d'instances en une fois + Renderer::SetIndexBuffer(indexBuffer); + Renderer::SetVertexBuffer(vertexBuffer); - while (instanceCount > 0) + if (instancing) { // On calcule le nombre d'instances que l'on pourra afficher cette fois-ci (Selon la taille du buffer d'instancing) - unsigned int renderedInstanceCount = std::min(instanceCount, maxInstanceCount); - instanceCount -= renderedInstanceCount; + VertexBuffer* instanceBuffer = Renderer::GetInstanceBuffer(); + instanceBuffer->SetVertexDeclaration(VertexDeclaration::Get(VertexLayout_Matrix4)); - // On remplit l'instancing buffer avec nos matrices world - instanceBuffer->Fill(instanceMatrices, 0, renderedInstanceCount, true); - instanceMatrices += renderedInstanceCount; + const Matrix4f* instanceMatrices = &instances[0]; + unsigned int instanceCount = instances.size(); + unsigned int maxInstanceCount = instanceBuffer->GetVertexCount(); // Le nombre maximum d'instances en une fois - // Et on affiche - instancedDrawFunc(renderedInstanceCount, meshData.primitiveMode, 0, indexCount); + while (instanceCount > 0) + { + // On calcule le nombre d'instances que l'on pourra afficher cette fois-ci (Selon la taille du buffer d'instancing) + unsigned int renderedInstanceCount = std::min(instanceCount, maxInstanceCount); + instanceCount -= renderedInstanceCount; + + // On remplit l'instancing buffer avec nos matrices world + instanceBuffer->Fill(instanceMatrices, 0, renderedInstanceCount, true); + instanceMatrices += renderedInstanceCount; + + // Et on affiche + instancedDrawFunc(renderedInstanceCount, meshData.primitiveMode, 0, indexCount); + } } - } - else - { - // Sans instancing, on doit effectuer un draw call pour chaque instance - // Cela reste néanmoins plus rapide que l'instancing en dessous d'un certain nombre d'instances - // À cause du temps de modification du buffer d'instancing - for (const NzMatrix4f& matrix : instances) + else { - NzRenderer::SetMatrix(nzMatrixType_World, matrix); - drawFunc(meshData.primitiveMode, 0, indexCount); + // Sans instancing, on doit effectuer un draw call pour chaque instance + // Cela reste néanmoins plus rapide que l'instancing en dessous d'un certain nombre d'instances + // À cause du temps de modification du buffer d'instancing + for (const Matrix4f& matrix : instances) + { + Renderer::SetMatrix(MatrixType_World, matrix); + drawFunc(meshData.primitiveMode, 0, indexCount); + } } + instances.clear(); } - instances.clear(); } } - } - // Et on remet à zéro les données - matEntry.enabled = false; - matEntry.instancingEnabled = false; + // Et on remet à zéro les données + matEntry.enabled = false; + matEntry.instancingEnabled = false; + } } } -} -const NzDepthRenderTechnique::ShaderUniforms* NzDepthRenderTechnique::GetShaderUniforms(const NzShader* shader) const -{ - auto it = m_shaderUniforms.find(shader); - if (it == m_shaderUniforms.end()) + const DepthRenderTechnique::ShaderUniforms* DepthRenderTechnique::GetShaderUniforms(const Shader* shader) const { - ShaderUniforms uniforms; - uniforms.shaderReleaseSlot.Connect(shader->OnShaderRelease, this, &NzDepthRenderTechnique::OnShaderInvalidated); - uniforms.shaderUniformInvalidatedSlot.Connect(shader->OnShaderUniformInvalidated, this, &NzDepthRenderTechnique::OnShaderInvalidated); + auto it = m_shaderUniforms.find(shader); + if (it == m_shaderUniforms.end()) + { + ShaderUniforms uniforms; + uniforms.shaderReleaseSlot.Connect(shader->OnShaderRelease, this, &DepthRenderTechnique::OnShaderInvalidated); + uniforms.shaderUniformInvalidatedSlot.Connect(shader->OnShaderUniformInvalidated, this, &DepthRenderTechnique::OnShaderInvalidated); - uniforms.textureOverlay = shader->GetUniformLocation("TextureOverlay"); + uniforms.eyePosition = shader->GetUniformLocation("EyePosition"); + uniforms.sceneAmbient = shader->GetUniformLocation("SceneAmbient"); + uniforms.textureOverlay = shader->GetUniformLocation("TextureOverlay"); - it = m_shaderUniforms.emplace(shader, std::move(uniforms)).first; + it = m_shaderUniforms.emplace(shader, std::move(uniforms)).first; + } + + return &it->second; } - return &it->second; -} + void DepthRenderTechnique::OnShaderInvalidated(const Shader* shader) const + { + m_shaderUniforms.erase(shader); + } -void NzDepthRenderTechnique::OnShaderInvalidated(const NzShader* shader) const -{ - m_shaderUniforms.erase(shader); -} - -NzIndexBuffer NzDepthRenderTechnique::s_quadIndexBuffer; -NzVertexBuffer NzDepthRenderTechnique::s_quadVertexBuffer; -NzVertexDeclaration NzDepthRenderTechnique::s_billboardInstanceDeclaration; -NzVertexDeclaration NzDepthRenderTechnique::s_billboardVertexDeclaration; + IndexBuffer DepthRenderTechnique::s_quadIndexBuffer; + VertexBuffer DepthRenderTechnique::s_quadVertexBuffer; + VertexDeclaration DepthRenderTechnique::s_billboardInstanceDeclaration; + VertexDeclaration DepthRenderTechnique::s_billboardVertexDeclaration; +} \ No newline at end of file From b3455e88ca18e8f16ac163b50c1c41b71a15e513 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 17 Apr 2016 19:58:15 +0200 Subject: [PATCH 36/37] Graphics/DepthRenderTechnique: Add Clear method Former-commit-id: 70e7cb5b59f0407c73766687b6a95e09b7eca589 --- SDK/src/NDK/Systems/RenderSystem.cpp | 4 ++++ include/Nazara/Graphics/DepthRenderTechnique.hpp | 1 + src/Nazara/Graphics/DepthRenderTechnique.cpp | 5 ++++- 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/SDK/src/NDK/Systems/RenderSystem.cpp b/SDK/src/NDK/Systems/RenderSystem.cpp index 829d2b398..7b90761b6 100644 --- a/SDK/src/NDK/Systems/RenderSystem.cpp +++ b/SDK/src/NDK/Systems/RenderSystem.cpp @@ -4,6 +4,7 @@ #include #include +#include #include #include #include @@ -169,6 +170,7 @@ namespace Ndk Nz::Renderer::SetMatrix(Nz::MatrixType_Projection, Nz::Matrix4f::Ortho(0.f, 100.f, 100.f, 0.f, 1.f, 100.f)); Nz::Renderer::SetMatrix(Nz::MatrixType_View, Nz::Matrix4f::ViewMatrix(lightNode.GetRotation() * Nz::Vector3f::Forward() * 100.f, lightNode.GetRotation())); + m_shadowTechnique.Clear(dummySceneData); m_shadowTechnique.Draw(dummySceneData); } } @@ -233,6 +235,7 @@ namespace Ndk graphicsComponent.AddToRenderQueue(renderQueue); } + m_shadowTechnique.Clear(dummySceneData); m_shadowTechnique.Draw(dummySceneData); } break; @@ -260,6 +263,7 @@ namespace Ndk graphicsComponent.AddToRenderQueue(renderQueue); } + m_shadowTechnique.Clear(dummySceneData); m_shadowTechnique.Draw(dummySceneData); break; } diff --git a/include/Nazara/Graphics/DepthRenderTechnique.hpp b/include/Nazara/Graphics/DepthRenderTechnique.hpp index 0b265ccc3..ac75f7e52 100644 --- a/include/Nazara/Graphics/DepthRenderTechnique.hpp +++ b/include/Nazara/Graphics/DepthRenderTechnique.hpp @@ -24,6 +24,7 @@ namespace Nz DepthRenderTechnique(); ~DepthRenderTechnique() = default; + void Clear(const SceneData& sceneData) const override; bool Draw(const SceneData& sceneData) const override; AbstractRenderQueue* GetRenderQueue() override; diff --git a/src/Nazara/Graphics/DepthRenderTechnique.cpp b/src/Nazara/Graphics/DepthRenderTechnique.cpp index 107043bce..1b2dc03f1 100644 --- a/src/Nazara/Graphics/DepthRenderTechnique.cpp +++ b/src/Nazara/Graphics/DepthRenderTechnique.cpp @@ -48,7 +48,7 @@ namespace Nz m_spriteBuffer.Reset(VertexDeclaration::Get(VertexLayout_XYZ_Color_UV), &m_vertexBuffer); } - bool DepthRenderTechnique::Draw(const SceneData& sceneData) const + void DepthRenderTechnique::Clear(const SceneData& sceneData) const { Renderer::Enable(RendererParameter_DepthBuffer, true); Renderer::Enable(RendererParameter_DepthWrite, true); @@ -57,7 +57,10 @@ namespace Nz // Just in case the background does render depth if (sceneData.background) sceneData.background->Draw(sceneData.viewer); + } + bool DepthRenderTechnique::Draw(const SceneData& sceneData) const + { for (auto& pair : m_renderQueue.layers) { ForwardRenderQueue::Layer& layer = pair.second; From 43c1243b750a50877b631c4c78a78640b5ea48a1 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 17 Apr 2016 20:22:29 +0200 Subject: [PATCH 37/37] Fix merge problems Former-commit-id: 899b541adea1719f558c52abfab51458249b6aaf --- include/Nazara/Math/Sphere.inl | 17 ++++---- include/Nazara/Math/Vector2.hpp | 10 ++--- include/Nazara/Math/Vector3.hpp | 10 ++--- include/Nazara/Math/Vector3.inl | 45 +++++++++++++++++--- include/Nazara/Math/Vector4.hpp | 10 ++--- include/Nazara/Math/Vector4.inl | 2 + src/Nazara/Graphics/DepthRenderTechnique.cpp | 29 ++++--------- 7 files changed, 72 insertions(+), 51 deletions(-) diff --git a/include/Nazara/Math/Sphere.inl b/include/Nazara/Math/Sphere.inl index 3438b5080..b87bd51a7 100644 --- a/include/Nazara/Math/Sphere.inl +++ b/include/Nazara/Math/Sphere.inl @@ -124,6 +124,7 @@ namespace Nz * * \param point Position of the point */ + template bool Sphere::Contains(const Vector3& point) const { @@ -131,7 +132,7 @@ namespace Nz } /*! - * \brief Returns the distance from the center of the sphere to the point + * \brief Returns the distance from the sphere to the point (is negative when the point is inside the sphere) * \return Distance to the point * * \param X X position of the point @@ -148,7 +149,7 @@ namespace Nz } /*! - * \brief Returns the distance from the center of the sphere to the point + * \brief Returns the distance from the sphere to the point (is negative when the point is inside the sphere) * \return Distance to the point * * \param point Position of the point @@ -303,7 +304,7 @@ namespace Nz template bool Sphere::Intersect(const Sphere& sphere) const { - return SquaredDistance(sphere.x, sphere.y, sphere.z) - radius * radius <= sphere.radius * sphere.radius; + return SquaredDistance(sphere.x, sphere.y, sphere.z) <= sphere.radius * sphere.radius; } /*! @@ -392,7 +393,6 @@ namespace Nz return *this; } - /* template Sphere& Sphere::Set(const Circle& circle) @@ -407,11 +407,12 @@ namespace Nz */ /*! - * \brief Sets the components of the sphere with center and radius from another sphere + * \brief Sets the components of the sphere with center and radius from another * \return A reference to this sphere * * \param sphere The other sphere */ + template Sphere& Sphere::Set(const Sphere& sphere) { @@ -458,7 +459,7 @@ namespace Nz } /*! - * \brief Returns the squared distance from the center of the sphere to the point + * \brief Returns the squared distance from the sphere to the point (can be negative if the point is inside the sphere) * \return Squared distance to the point * * \param X X position of the point @@ -467,7 +468,6 @@ namespace Nz * * \see Distance */ - template T Sphere::SquaredDistance(T X, T Y, T Z) const { @@ -475,14 +475,13 @@ namespace Nz } /*! - * \brief Returns the squared distance from the center of the sphere to the point + * \brief Returns the squared distance from the sphere to the point (can be negative if the point is inside the sphere) * \return Squared distance to the point * * \param point Position of the point * * \see Distance */ - template T Sphere::SquaredDistance(const Vector3& point) const { diff --git a/include/Nazara/Math/Vector2.hpp b/include/Nazara/Math/Vector2.hpp index 4a6a83c16..b275d0544 100644 --- a/include/Nazara/Math/Vector2.hpp +++ b/include/Nazara/Math/Vector2.hpp @@ -102,11 +102,6 @@ namespace Nz T x, y; }; - template std::ostream& operator<<(std::ostream& out, const Vector2& vec); - - template Vector2 operator*(T scale, const Vector2& vec); - template Vector2 operator/(T scale, const Vector2& vec); - typedef Vector2 Vector2d; typedef Vector2 Vector2f; typedef Vector2 Vector2i; @@ -118,6 +113,11 @@ namespace Nz template bool Unserialize(SerializationContext& context, Vector2* vector); } +template std::ostream& operator<<(std::ostream& out, const Nz::Vector2& vec); + +template Nz::Vector2 operator*(T scale, const Nz::Vector2& vec); +template Nz::Vector2 operator/(T scale, const Nz::Vector2& vec); + #include #endif // NAZARA_VECTOR2_HPP diff --git a/include/Nazara/Math/Vector3.hpp b/include/Nazara/Math/Vector3.hpp index a5fbad035..7743e7a35 100644 --- a/include/Nazara/Math/Vector3.hpp +++ b/include/Nazara/Math/Vector3.hpp @@ -124,11 +124,6 @@ namespace Nz T x, y, z; }; - template std::ostream& operator<<(std::ostream& out, const Vector3& vec); - - template Vector3 operator*(T scale, const Vector3& vec); - template Vector3 operator/(T scale, const Vector3& vec); - typedef Vector3 Vector3d; typedef Vector3 Vector3f; typedef Vector3 Vector3i; @@ -140,6 +135,11 @@ namespace Nz template bool Unserialize(SerializationContext& context, Vector3* vector); } +template std::ostream& operator<<(std::ostream& out, const Nz::Vector3& vec); + +template Nz::Vector3 operator*(T scale, const Nz::Vector3& vec); +template Nz::Vector3 operator/(T scale, const Nz::Vector3& vec); + #include #endif // NAZARA_VECTOR3_HPP diff --git a/include/Nazara/Math/Vector3.inl b/include/Nazara/Math/Vector3.inl index 96f70f9b1..c5a0155c7 100644 --- a/include/Nazara/Math/Vector3.inl +++ b/include/Nazara/Math/Vector3.inl @@ -1012,10 +1012,15 @@ namespace Nz } /*! - * \brief Shorthand for the vector (0, -1, 0) - * \return A vector with components (0, -1, 0) + * \brief Measure the distance between two points + * Shorthand for vec1.Distance(vec2) * - * \see MakeDown + * param vec1 the first point + * param vec2 the second point + * + * \return The distance between the two vectors + * + * \see SquaredDistance */ template T Vector3::Distance(const Vector3& vec1, const Vector3& vec2) @@ -1023,12 +1028,29 @@ namespace Nz return vec1.Distance(vec2); } + /*! + * \brief Measure the distance between two points as a float + * Shorthand for vec1.Distancef(vec2) + * + * param vec1 the first point + * param vec2 the second point + * + * \return The distance between the two vectors as a float + * + * \see SquaredDistancef + */ template float Vector3::Distancef(const Vector3& vec1, const Vector3& vec2) { return vec1.Distancef(vec2); } + /*! + * \brief Shorthand for the vector (0, -1, 0) + * \return A vector with components (0, -1, 0) + * + * \see MakeDown + */ template Vector3 Vector3::Down() { @@ -1123,10 +1145,13 @@ namespace Nz } /*! - * \brief Shorthand for the vector (1, 1, 1) - * \return A vector with components (1, 1, 1) + * \brief Calculates the squared distance between two vectors + * \return The metric distance between two vectors with the squared euclidean norm * - * \see MakeUnit + * \param vec1 The first point to measure the distance with + * \param vec2 The second point to measure the distance with + * + * \see Distance */ template T Vector3::SquaredDistance(const Vector3& vec1, const Vector3& vec2) @@ -1134,6 +1159,12 @@ namespace Nz return vec1.SquaredDistance(vec2); } + /*! + * \brief Shorthand for the vector (1, 1, 1) + * \return A vector with components (1, 1, 1) + * + * \see MakeUnit + */ template Vector3 Vector3::Unit() { @@ -1312,6 +1343,8 @@ Nz::Vector3 operator/(T scale, const Nz::Vector3& vec) throw std::domain_error(error); } #endif + + return Nz::Vector3(scale / vec.x, scale / vec.y, scale / vec.z); } #undef F diff --git a/include/Nazara/Math/Vector4.hpp b/include/Nazara/Math/Vector4.hpp index daedcad0b..d1e51433a 100644 --- a/include/Nazara/Math/Vector4.hpp +++ b/include/Nazara/Math/Vector4.hpp @@ -100,11 +100,6 @@ namespace Nz T x, y, z, w; }; - template std::ostream& operator<<(std::ostream& out, const Vector4& vec); - - template Vector4 operator*(T scale, const Vector4& vec); - template Vector4 operator/(T scale, const Vector4& vec); - typedef Vector4 Vector4d; typedef Vector4 Vector4f; typedef Vector4 Vector4i; @@ -116,6 +111,11 @@ namespace Nz template bool Unserialize(SerializationContext& context, Vector4* vector); } +template std::ostream& operator<<(std::ostream& out, const Nz::Vector4& vec); + +template Nz::Vector4 operator*(T scale, const Nz::Vector4& vec); +template Nz::Vector4 operator/(T scale, const Nz::Vector4& vec); + #include #endif // NAZARA_VECTOR4_HPP diff --git a/include/Nazara/Math/Vector4.inl b/include/Nazara/Math/Vector4.inl index f0220ec4e..73a9a0802 100644 --- a/include/Nazara/Math/Vector4.inl +++ b/include/Nazara/Math/Vector4.inl @@ -1116,6 +1116,8 @@ Nz::Vector4 operator/(T scale, const Nz::Vector4& vec) throw std::domain_error(error); } #endif + + return Nz::Vector4(scale / vec.x, scale / vec.y, scale / vec.z, scale / vec.w); } #undef F diff --git a/src/Nazara/Graphics/DepthRenderTechnique.cpp b/src/Nazara/Graphics/DepthRenderTechnique.cpp index 1b2dc03f1..46e7fb043 100644 --- a/src/Nazara/Graphics/DepthRenderTechnique.cpp +++ b/src/Nazara/Graphics/DepthRenderTechnique.cpp @@ -55,8 +55,8 @@ namespace Nz Renderer::Clear(RendererBuffer_Depth); // Just in case the background does render depth - if (sceneData.background) - sceneData.background->Draw(sceneData.viewer); + //if (sceneData.background) + // sceneData.background->Draw(sceneData.viewer); } bool DepthRenderTechnique::Draw(const SceneData& sceneData) const @@ -121,9 +121,9 @@ namespace Nz float vertices[2 * 4] = { -0.5f, -0.5f, - 0.5f, -0.5f, + 0.5f, -0.5f, -0.5f, 0.5f, - 0.5f, 0.5f, + 0.5f, 0.5f, }; s_quadVertexBuffer.FillRaw(vertices, 0, sizeof(vertices)); @@ -157,8 +157,6 @@ namespace Nz void DepthRenderTechnique::DrawBasicSprites(const SceneData& sceneData, ForwardRenderQueue::Layer& layer) const { - NazaraAssert(sceneData.viewer, "Invalid viewer"); - const Shader* lastShader = nullptr; const ShaderUniforms* shaderUniforms = nullptr; @@ -183,7 +181,7 @@ namespace Nz if (spriteChainCount > 0) { // On commence par appliquer du matériau (et récupérer le shader ainsi activé) - UInt32 flags = ShaderFlags_VertexColor; + UInt32 flags = 0; if (overlay) flags |= ShaderFlags_TextureOverlay; @@ -203,12 +201,10 @@ namespace Nz // Index des uniformes dans le shader shaderUniforms = GetShaderUniforms(shader); - // Couleur ambiante de la scène - shader->SendColor(shaderUniforms->sceneAmbient, sceneData.ambientColor); // Overlay shader->SendInteger(shaderUniforms->textureOverlay, overlayUnit); // Position de la caméra - shader->SendVector(shaderUniforms->eyePosition, sceneData.viewer->GetEyePosition()); + shader->SendVector(shaderUniforms->eyePosition, Renderer::GetMatrix(MatrixType_ViewProj).GetTranslation()); lastShader = shader; } @@ -263,8 +259,6 @@ namespace Nz void DepthRenderTechnique::DrawBillboards(const SceneData& sceneData, ForwardRenderQueue::Layer& layer) const { - NazaraAssert(sceneData.viewer, "Invalid viewer"); - const Shader* lastShader = nullptr; const ShaderUniforms* shaderUniforms = nullptr; @@ -293,10 +287,8 @@ namespace Nz // Index des uniformes dans le shader shaderUniforms = GetShaderUniforms(shader); - // Couleur ambiante de la scène - shader->SendColor(shaderUniforms->sceneAmbient, sceneData.ambientColor); // Position de la caméra - shader->SendVector(shaderUniforms->eyePosition, sceneData.viewer->GetEyePosition()); + shader->SendVector(shaderUniforms->eyePosition, Renderer::GetMatrix(MatrixType_ViewProj).GetTranslation()); lastShader = shader; } @@ -342,10 +334,8 @@ namespace Nz // Index des uniformes dans le shader shaderUniforms = GetShaderUniforms(shader); - // Couleur ambiante de la scène - shader->SendColor(shaderUniforms->sceneAmbient, sceneData.ambientColor); // Position de la caméra - shader->SendVector(shaderUniforms->eyePosition, sceneData.viewer->GetEyePosition()); + shader->SendVector(shaderUniforms->eyePosition, Renderer::GetMatrix(MatrixType_ViewProj).GetTranslation()); lastShader = shader; } @@ -408,8 +398,6 @@ namespace Nz void DepthRenderTechnique::DrawOpaqueModels(const SceneData& sceneData, ForwardRenderQueue::Layer& layer) const { - NazaraAssert(sceneData.viewer, "Invalid viewer"); - const Shader* lastShader = nullptr; const ShaderUniforms* shaderUniforms = nullptr; @@ -531,7 +519,6 @@ namespace Nz uniforms.shaderUniformInvalidatedSlot.Connect(shader->OnShaderUniformInvalidated, this, &DepthRenderTechnique::OnShaderInvalidated); uniforms.eyePosition = shader->GetUniformLocation("EyePosition"); - uniforms.sceneAmbient = shader->GetUniformLocation("SceneAmbient"); uniforms.textureOverlay = shader->GetUniformLocation("TextureOverlay"); it = m_shaderUniforms.emplace(shader, std::move(uniforms)).first;