From 974df4288f97cc9e83c7823f10f8234ab96516fe Mon Sep 17 00:00:00 2001 From: Lynix Date: Tue, 16 Jun 2015 14:21:20 +0200 Subject: [PATCH 01/60] 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/60] 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/60] 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/60] 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/60] 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/60] 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/60] 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/60] 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/60] 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/60] 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/60] 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/60] 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/60] 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/60] 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/60] 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/60] 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/60] 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/60] 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/60] 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/60] 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/60] 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/60] 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/60] 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/60] 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/60] 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/60] 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/60] 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/60] 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/60] 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/60] 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/60] 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/60] 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/60] 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/60] 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/60] 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/60] 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/60] 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; From 9aab369791ad04ca45cd5b8dabd071060da0d639 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sat, 30 Apr 2016 12:44:34 +0200 Subject: [PATCH 38/60] Core/ParameterList: Add support for color values and updated documentation Former-commit-id: 87478d0e90a39ec24779ee9174e9f4e1a1f6d32b --- include/Nazara/Core/Enums.hpp | 1 + include/Nazara/Core/ParameterList.hpp | 8 +- src/Nazara/Core/ParameterList.cpp | 320 ++++++++++++++++---------- 3 files changed, 209 insertions(+), 120 deletions(-) diff --git a/include/Nazara/Core/Enums.hpp b/include/Nazara/Core/Enums.hpp index 02039811b..7a5c161ab 100644 --- a/include/Nazara/Core/Enums.hpp +++ b/include/Nazara/Core/Enums.hpp @@ -93,6 +93,7 @@ namespace Nz enum ParameterType { ParameterType_Boolean, + ParameterType_Color, ParameterType_Float, ParameterType_Integer, ParameterType_None, diff --git a/include/Nazara/Core/ParameterList.hpp b/include/Nazara/Core/ParameterList.hpp index 2475185d7..119d05cca 100644 --- a/include/Nazara/Core/ParameterList.hpp +++ b/include/Nazara/Core/ParameterList.hpp @@ -8,6 +8,7 @@ #define NAZARA_PARAMETERLIST_HPP #include +#include #include #include #include @@ -27,6 +28,7 @@ namespace Nz void Clear(); bool GetBooleanParameter(const String& name, bool* value) const; + bool GetColorParameter(const String& name, Color* value) const; bool GetFloatParameter(const String& name, float* value) const; bool GetIntegerParameter(const String& name, int* value) const; bool GetParameterType(const String& name, ParameterType* type) const; @@ -39,13 +41,14 @@ namespace Nz void RemoveParameter(const String& name); void SetParameter(const String& name); + void SetParameter(const String& name, const Color& value); void SetParameter(const String& name, const String& value); void SetParameter(const String& name, const char* value); - void SetParameter(const String& name, void* value); - void SetParameter(const String& name, void* value, Destructor destructor); void SetParameter(const String& name, bool value); void SetParameter(const String& name, float value); void SetParameter(const String& name, int value); + void SetParameter(const String& name, void* value); + void SetParameter(const String& name, void* value, Destructor destructor); ParameterList& operator=(const ParameterList& list); ParameterList& operator=(ParameterList&&) = default; @@ -79,6 +82,7 @@ namespace Nz float floatVal; int intVal; void* ptrVal; + Color colorVal; String stringVal; UserdataValue* userdataVal; }; diff --git a/src/Nazara/Core/ParameterList.cpp b/src/Nazara/Core/ParameterList.cpp index f9a24d4cc..91426a0b7 100644 --- a/src/Nazara/Core/ParameterList.cpp +++ b/src/Nazara/Core/ParameterList.cpp @@ -22,7 +22,6 @@ namespace Nz /*! * \brief Constructs a ParameterList object by copy */ - ParameterList::ParameterList(const ParameterList& list) { operator=(list); @@ -31,16 +30,14 @@ namespace Nz /*! * \brief Destructs the object and clears */ - ParameterList::~ParameterList() { Clear(); } /*! - * \brief Clears the list of parameters + * \brief Clears all the parameters */ - void ParameterList::Clear() { for (auto it = m_parameters.begin(); it != m_parameters.end(); ++it) @@ -50,17 +47,18 @@ namespace Nz } /*! - * \brief Gets a boolean parameter by name - * \return true if success + * \brief Gets a parameter as a boolean + * \return true if the parameter could be represented as a boolean * - * \param name Name of the variable - * \param value Value to set + * \param name Name of the parameter + * \param value Pointer to a boolean to hold the retrieved value * - * \remark Produces a NazaraAssert if pointer is invalid - * \remark Produces a silent NazaraError if name is not a variable - * \remark Produces a silent NazaraError if value could not be convertible + * \remark value must be a valid pointer + * \remark In case of failure, the variable pointed by value keep its value + * \remark If the parameter is not a boolean, a conversion will be performed, compatibles types are: + Integer: 0 is interpreted as false, any other value is interpreted as true + String: Conversion obeys the rule as described by String::ToBool */ - bool ParameterList::GetBooleanParameter(const String& name, bool* value) const { NazaraAssert(value, "Invalid pointer"); @@ -85,17 +83,17 @@ namespace Nz return true; case ParameterType_String: + { + bool converted; + if (it->second.value.stringVal.ToBool(&converted, String::CaseInsensitive)) { - bool converted; - if (it->second.value.stringVal.ToBool(&converted, String::CaseInsensitive)) - { - *value = converted; - return true; - } - - break; + *value = converted; + return true; } + break; + } + case ParameterType_Float: case ParameterType_None: case ParameterType_Pointer: @@ -108,17 +106,62 @@ namespace Nz } /*! - * \brief Gets a float parameter by name - * \return true if success + * \brief Gets a parameter as a color + * \return true if the parameter could be represented as a color * - * \param name Name of the variable - * \param value Value to set + * \param name Name of the parameter + * \param value Pointer to a color to hold the retrieved value * - * \remark Produces a NazaraAssert if pointer is invalid - * \remark Produces a silent NazaraError if name is not a variable - * \remark Produces a silent NazaraError if value could not be convertible + * \remark value must be a valid pointer + * \remark In case of failure, the variable pointed by value keep its value + * \remark If the parameter is not a color, the function fails */ + bool ParameterList::GetColorParameter(const String& name, Color* value) const + { + NazaraAssert(value, "Invalid pointer"); + ErrorFlags flags(ErrorFlag_Silent | ErrorFlag_ThrowExceptionDisabled); + + auto it = m_parameters.find(name); + if (it == m_parameters.end()) + { + NazaraError("Parameter \"" + name + "\" is not present"); + return false; + } + + switch (it->second.type) + { + case ParameterType_Color: + *value = it->second.value.colorVal; + return true; + + case ParameterType_Boolean: + case ParameterType_Integer: + case ParameterType_String: + case ParameterType_Float: + case ParameterType_None: + case ParameterType_Pointer: + case ParameterType_Userdata: + break; + } + + NazaraError("Parameter value is not representable as a color"); + return false; + } + + /*! + * \brief Gets a parameter as a float + * \return true if the parameter could be represented as a float + * + * \param name Name of the parameter + * \param value Pointer to a float to hold the retrieved value + * + * \remark value must be a valid pointer + * \remark In case of failure, the variable pointed by value keep its value + * \remark If the parameter is not a float, a conversion will be performed, compatibles types are: + Integer: The integer value is converted to its float representation + String: Conversion obeys the rule as described by String::ToDouble + */ bool ParameterList::GetFloatParameter(const String& name, float* value) const { NazaraAssert(value, "Invalid pointer"); @@ -164,19 +207,21 @@ namespace Nz NazaraError("Parameter value is not representable as a float"); return false; } - + /*! - * \brief Gets a integer parameter by name - * \return true if success + * \brief Gets a parameter as an integer + * \return true if the parameter could be represented as an integer * - * \param name Name of the variable - * \param value Value to set + * \param name Name of the parameter + * \param value Pointer to an integer to hold the retrieved value * - * \remark Produces a NazaraAssert if pointer is invalid - * \remark Produces a silent NazaraError if name is not a variable - * \remark Produces a silent NazaraError if value could not be convertible + * \remark value must be a valid pointer + * \remark In case of failure, the variable pointed by value keep its value + * \remark If the parameter is not a float, a conversion will be performed, compatibles types are: + Boolean: The boolean is represented as 1 if true and 0 if false + Float: The floating-point value is truncated and converted to a integer + String: Conversion obeys the rule as described by String::ToInteger but fails if the value could not be represented as a int */ - bool ParameterList::GetIntegerParameter(const String& name, int* value) const { NazaraAssert(value, "Invalid pointer"); @@ -229,15 +274,14 @@ namespace Nz } /*! - * \brief Gets a parameter type by name - * \return true if the parameter is present + * \brief Gets a parameter type + * \return true if the parameter is present, its type being written to type * * \param name Name of the variable - * \param type Pointer to a variable to hold result + * \param type Pointer to a variable to hold the result * - * \remark Produces a NazaraAssert if type is invalid + * \remark type must be a valid pointer to a ParameterType variable */ - bool ParameterList::GetParameterType(const String& name, ParameterType* type) const { NazaraAssert(type, "Invalid pointer"); @@ -252,17 +296,17 @@ namespace Nz } /*! - * \brief Gets a pointer parameter by name - * \return true if success + * \brief Gets a parameter as a pointer + * \return true if the parameter could be represented as a pointer * - * \param name Name of the variable - * \param value Value to set + * \param name Name of the parameter + * \param value Pointer to a pointer to hold the retrieved value * - * \remark Produces a NazaraAssert if pointer is invalid - * \remark Produces a silent NazaraError if name is not a variable - * \remark Produces a silent NazaraError if value could not be convertible + * \remark value must be a valid pointer + * \remark In case of failure, the variable pointed by value keep its value + * \remark If the parameter is not a pointer, a conversion will be performed, compatibles types are: + Userdata: The pointer part of the userdata is returned */ - bool ParameterList::GetPointerParameter(const String& name, void** value) const { NazaraAssert(value, "Invalid pointer"); @@ -299,17 +343,23 @@ namespace Nz } /*! - * \brief Gets a string parameter by name - * \return true if success + * \brief Gets a parameter as a string + * \return true if the parameter could be represented as a string * - * \param name Name of the variable - * \param value Value to set + * \param name Name of the parameter + * \param value Pointer to a pointer to hold the retrieved value * - * \remark Produces a NazaraAssert if pointer is invalid - * \remark Produces a silent NazaraError if name is not a variable - * \remark Produces a silent NazaraError if value could not be convertible + * \remark value must be a valid pointer + * \remark In case of failure, the variable pointed by value keep its value + * \remark If the parameter is not a string, a conversion will be performed, all types are compatibles: + Boolean: Conversion obeys the rules of String::Boolean + Color: Conversion obeys the rules of Color::ToString + Float: Conversion obeys the rules of String::Number + Integer: Conversion obeys the rules of String::Number + None: An empty string is returned + Pointer: Conversion obeys the rules of String::Pointer + Userdata: Conversion obeys the rules of String::Pointer */ - bool ParameterList::GetStringParameter(const String& name, String* value) const { NazaraAssert(value, "Invalid pointer"); @@ -329,6 +379,10 @@ namespace Nz *value = String::Boolean(it->second.value.boolVal); return true; + case ParameterType_Color: + *value = it->second.value.colorVal.ToString(); + return true; + case ParameterType_Float: *value = String::Number(it->second.value.floatVal); return true; @@ -357,19 +411,20 @@ namespace Nz NazaraInternalError("Parameter value is not valid"); return false; } - + /*! - * \brief Gets a user parameter by name - * \return true if success + * \brief Gets a parameter as an userdata + * \return true if the parameter could be represented as a userdata * - * \param name Name of the variable - * \param value Value to set + * \param name Name of the parameter + * \param value Pointer to a pointer to hold the retrieved value * - * \remark Produces a NazaraAssert if pointer is invalid - * \remark Produces a silent NazaraError if name is not a variable - * \remark Produces a silent NazaraError if value could not be convertible + * \remark value must be a valid pointer + * \remark In case of failure, the variable pointed by value keep its value + * \remark If the parameter is not an userdata, the function fails + * + * \see GetPointerParameter */ - bool ParameterList::GetUserdataParameter(const String& name, void** value) const { NazaraAssert(value, "Invalid pointer"); @@ -396,25 +451,24 @@ namespace Nz } /*! - * \brief Checks whether the parameter list has a parameter with that name + * \brief Checks whether the parameter list contains a parameter named `name` * \return true if found * * \param name Name of the parameter */ - bool ParameterList::HasParameter(const String& name) const { return m_parameters.find(name) != m_parameters.end(); } /*! - * \brief Removes the parameter with that name + * \brief Removes the parameter named `name` * - * Removes the parameter with that name, if not found, nothing is done + * Search for a parameter named `name` and remove it from the parameter list, freeing up its memory + * Nothing is done if the parameter is not present in the parameter list * * \param name Name of the parameter */ - void ParameterList::RemoveParameter(const String& name) { auto it = m_parameters.find(name); @@ -426,11 +480,12 @@ namespace Nz } /*! - * \brief Sets the parameter with the name to ParameterType_None + * \brief Sets a null parameter named `name` + * + * If a parameter already exists with that name, it is destroyed and replaced by this call * * \param name Name of the parameter */ - void ParameterList::SetParameter(const String& name) { Parameter& parameter = CreateValue(name); @@ -438,12 +493,29 @@ namespace Nz } /*! - * \brief Sets the parameter with the name to the value + * \brief Sets a color parameter named `name` + * + * If a parameter already exists with that name, it is destroyed and replaced by this call * * \param name Name of the parameter - * \param value Value of the parameter + * \param value The color value */ + void ParameterList::SetParameter(const String& name, const Color& value) + { + Parameter& parameter = CreateValue(name); + parameter.type = ParameterType_Color; + PlacementNew(¶meter.value.colorVal, value); + } + + /*! + * \brief Sets a string parameter named `name` + * + * If a parameter already exists with that name, it is destroyed and replaced by this call + * + * \param name Name of the parameter + * \param value The string value + */ void ParameterList::SetParameter(const String& name, const String& value) { Parameter& parameter = CreateValue(name); @@ -453,12 +525,13 @@ namespace Nz } /*! - * \brief Sets the parameter with the name to the value + * \brief Sets a string parameter named `name` + * + * If a parameter already exists with that name, it is destroyed and replaced by this call * * \param name Name of the parameter - * \param value Value of the parameter + * \param value The string value */ - void ParameterList::SetParameter(const String& name, const char* value) { Parameter& parameter = CreateValue(name); @@ -468,41 +541,13 @@ namespace Nz } /*! - * \brief Sets the parameter with the name to the value + * \brief Sets a boolean parameter named `name` + * + * If a parameter already exists with that name, it is destroyed and replaced by this call * * \param name Name of the parameter - * \param value Value of the parameter + * \param value The boolean value */ - - void ParameterList::SetParameter(const String& name, void* value) - { - Parameter& parameter = CreateValue(name); - parameter.type = ParameterType_Pointer; - parameter.value.ptrVal = value; - } - - /*! - * \brief Sets the parameter with the name to the value - * - * \param name Name of the parameter - * \param value Value of the parameter - * \param destructor Destructor for dynamic variable - */ - - void ParameterList::SetParameter(const String& name, void* value, Destructor destructor) - { - Parameter& parameter = CreateValue(name); - parameter.type = ParameterType_Userdata; - parameter.value.userdataVal = new Parameter::UserdataValue(destructor, value); - } - - /*! - * \brief Sets the parameter with the name to the value - * - * \param name Name of the parameter - * \param value Value of the parameter - */ - void ParameterList::SetParameter(const String& name, bool value) { Parameter& parameter = CreateValue(name); @@ -511,12 +556,13 @@ namespace Nz } /*! - * \brief Sets the parameter with the name to the value + * \brief Sets a float parameter named `name` + * + * If a parameter already exists with that name, it is destroyed and replaced by this call * * \param name Name of the parameter - * \param value Value of the parameter + * \param value The float value */ - void ParameterList::SetParameter(const String& name, float value) { Parameter& parameter = CreateValue(name); @@ -525,26 +571,63 @@ namespace Nz } /*! - * \brief Sets the parameter with the name to the value + * \brief Sets an integer parameter named `name` + * + * If a parameter already exists with that name, it is destroyed and replaced by this call * * \param name Name of the parameter - * \param value Value of the parameter + * \param value The integer value */ - void ParameterList::SetParameter(const String& name, int value) { Parameter& parameter = CreateValue(name); parameter.type = ParameterType_Integer; parameter.value.intVal = value; } + + /*! + * \brief Sets a pointer parameter named `name` + * + * If a parameter already exists with that name, it is destroyed and replaced by this call + * + * \param name Name of the parameter + * \param value The pointer value + * + * \remark This sets a raw pointer, this class takes no responsibility toward it, + if you wish to destroy the pointed variable along with the parameter list, you should set a userdata + */ + void ParameterList::SetParameter(const String& name, void* value) + { + Parameter& parameter = CreateValue(name); + parameter.type = ParameterType_Pointer; + parameter.value.ptrVal = value; + } /*! - * \brief Assigns the content of the other parameter list to this + * \brief Sets a userdata parameter named `name` + * + * If a parameter already exists with that name, it is destroyed and replaced by this call + * + * \param name Name of the parameter + * \param value The pointer value + * \param destructor The destructor function to be called upon parameter suppression + * + * \remark The destructor is called once when all copies of the userdata are destroyed, which means + you can safely copy the parameter list around. + */ + void ParameterList::SetParameter(const String& name, void* value, Destructor destructor) + { + Parameter& parameter = CreateValue(name); + parameter.type = ParameterType_Userdata; + parameter.value.userdataVal = new Parameter::UserdataValue(destructor, value); + } + + /*! + * \brief Copies the content of the other parameter list to this * \return A reference to this * * \param list List to assign */ - ParameterList& ParameterList::operator=(const ParameterList& list) { Clear(); @@ -627,6 +710,7 @@ namespace Nz } case ParameterType_Boolean: + case ParameterType_Color: case ParameterType_Float: case ParameterType_Integer: case ParameterType_None: From 3b5d6e9cde24f75c1daabf5541558d2f0bfa50dd Mon Sep 17 00:00:00 2001 From: Lynix Date: Sat, 30 Apr 2016 18:44:33 +0200 Subject: [PATCH 39/60] Make mesh able to carry material informations - Move OBJ Loader to Utility module, where it belongs - Change Mesh material informations from a path to a parameterlist - Improve Mesh code Former-commit-id: f16f48f8b6399188a09797cec3707ab6726bdbca --- include/Nazara/Graphics/Material.hpp | 3 + include/Nazara/Renderer/Enums.hpp | 101 ---- include/Nazara/Renderer/RenderStates.hpp | 2 +- include/Nazara/Renderer/TextureSampler.hpp | 2 +- include/Nazara/Utility/Enums.hpp | 101 ++++ include/Nazara/Utility/MaterialData.hpp | 65 +++ include/Nazara/Utility/Mesh.hpp | 5 +- src/Nazara/Graphics/Formats/MeshLoader.cpp | 63 ++- src/Nazara/Graphics/Graphics.cpp | 5 - src/Nazara/Graphics/Material.cpp | 161 ++++++ src/Nazara/Utility/Formats/MD2Loader.cpp | 7 +- src/Nazara/Utility/Formats/MD5MeshLoader.cpp | 11 +- .../Formats/OBJLoader.cpp | 117 ++-- .../Formats/OBJLoader.hpp | 0 src/Nazara/Utility/Mesh.cpp | 510 +++--------------- src/Nazara/Utility/Utility.cpp | 7 +- 16 files changed, 523 insertions(+), 637 deletions(-) create mode 100644 include/Nazara/Utility/MaterialData.hpp rename src/Nazara/{Graphics => Utility}/Formats/OBJLoader.cpp (67%) rename src/Nazara/{Graphics => Utility}/Formats/OBJLoader.hpp (100%) diff --git a/include/Nazara/Graphics/Material.hpp b/include/Nazara/Graphics/Material.hpp index a2d30b643..397253022 100644 --- a/include/Nazara/Graphics/Material.hpp +++ b/include/Nazara/Graphics/Material.hpp @@ -24,6 +24,7 @@ #include #include #include +#include namespace Nz { @@ -62,6 +63,8 @@ namespace Nz const Shader* Apply(UInt32 shaderFlags = 0, UInt8 textureUnit = 0, UInt8* lastUsedUnit = nullptr) const; + void BuildFromParameters(const ParameterList& matData, const MaterialParams& matParams = MaterialParams()); + void Enable(RendererParameter renderParameter, bool enable); void EnableAlphaTest(bool alphaTest); void EnableDepthSorting(bool depthSorting); diff --git a/include/Nazara/Renderer/Enums.hpp b/include/Nazara/Renderer/Enums.hpp index 30e0b5616..2d0e6d3a7 100644 --- a/include/Nazara/Renderer/Enums.hpp +++ b/include/Nazara/Renderer/Enums.hpp @@ -19,40 +19,6 @@ namespace Nz AttachmentPoint_Max = AttachmentPoint_Stencil }; - enum BlendFunc - { - BlendFunc_DestAlpha, - BlendFunc_DestColor, - BlendFunc_SrcAlpha, - BlendFunc_SrcColor, - BlendFunc_InvDestAlpha, - BlendFunc_InvDestColor, - BlendFunc_InvSrcAlpha, - BlendFunc_InvSrcColor, - BlendFunc_One, - BlendFunc_Zero, - - BlendFunc_Max = BlendFunc_Zero - }; - - enum FaceFilling - { - FaceFilling_Fill, - FaceFilling_Line, - FaceFilling_Point, - - FaceFilling_Max = FaceFilling_Point - }; - - enum FaceSide - { - FaceSide_Back, - FaceSide_Front, - FaceSide_FrontAndBack, - - FaceSide_Max = FaceSide_FrontAndBack - }; - enum GpuQueryCondition { GpuQueryCondition_Region_NoWait, @@ -124,59 +90,6 @@ namespace Nz RendererBuffer_Max = RendererBuffer_Stencil*2-1 }; - enum RendererComparison - { - RendererComparison_Always, - RendererComparison_Equal, - RendererComparison_Greater, - RendererComparison_GreaterOrEqual, - RendererComparison_Less, - RendererComparison_LessOrEqual, - RendererComparison_Never, - RendererComparison_NotEqual, - - RendererComparison_Max = RendererComparison_NotEqual - }; - - enum RendererParameter - { - RendererParameter_Blend, - RendererParameter_ColorWrite, - RendererParameter_DepthBuffer, - RendererParameter_DepthWrite, - RendererParameter_FaceCulling, - RendererParameter_ScissorTest, - RendererParameter_StencilTest, - - RendererParameter_Max = RendererParameter_StencilTest - }; - - enum SamplerFilter - { - SamplerFilter_Unknown = -1, - - SamplerFilter_Bilinear, - SamplerFilter_Nearest, - SamplerFilter_Trilinear, - - SamplerFilter_Default, - - SamplerFilter_Max = SamplerFilter_Default - }; - - enum SamplerWrap - { - SamplerWrap_Unknown = -1, - - SamplerWrap_Clamp, - SamplerWrap_MirroredRepeat, - SamplerWrap_Repeat, - - SamplerWrap_Default, - - SamplerWrap_Max = SamplerWrap_Repeat - }; - enum ShaderUniform { ShaderUniform_InvProjMatrix, @@ -205,20 +118,6 @@ namespace Nz ShaderStageType_Max = ShaderStageType_Vertex }; - - enum StencilOperation - { - StencilOperation_Decrement, - StencilOperation_DecrementNoClamp, - StencilOperation_Increment, - StencilOperation_IncrementNoClamp, - StencilOperation_Invert, - StencilOperation_Keep, - StencilOperation_Replace, - StencilOperation_Zero, - - StencilOperation_Max = StencilOperation_Zero - }; } #endif // NAZARA_ENUMS_RENDERER_HPP diff --git a/include/Nazara/Renderer/RenderStates.hpp b/include/Nazara/Renderer/RenderStates.hpp index 9e9d455f4..4040bec55 100644 --- a/include/Nazara/Renderer/RenderStates.hpp +++ b/include/Nazara/Renderer/RenderStates.hpp @@ -7,7 +7,7 @@ #ifndef NAZARA_RENDERSTATES_HPP #define NAZARA_RENDERSTATES_HPP -#include +#include namespace Nz { diff --git a/include/Nazara/Renderer/TextureSampler.hpp b/include/Nazara/Renderer/TextureSampler.hpp index a461f57b2..21675e6c9 100644 --- a/include/Nazara/Renderer/TextureSampler.hpp +++ b/include/Nazara/Renderer/TextureSampler.hpp @@ -9,7 +9,7 @@ #include #include -#include +#include namespace Nz { diff --git a/include/Nazara/Utility/Enums.hpp b/include/Nazara/Utility/Enums.hpp index 096aa5fb6..143390906 100644 --- a/include/Nazara/Utility/Enums.hpp +++ b/include/Nazara/Utility/Enums.hpp @@ -17,6 +17,22 @@ namespace Nz AnimationType_Max = AnimationType_Static }; + enum BlendFunc + { + BlendFunc_DestAlpha, + BlendFunc_DestColor, + BlendFunc_SrcAlpha, + BlendFunc_SrcColor, + BlendFunc_InvDestAlpha, + BlendFunc_InvDestColor, + BlendFunc_InvSrcAlpha, + BlendFunc_InvSrcColor, + BlendFunc_One, + BlendFunc_Zero, + + BlendFunc_Max = BlendFunc_Zero + }; + enum BufferAccess { BufferAccess_DiscardAndWrite, @@ -87,6 +103,24 @@ namespace Nz DataStorage_Max = DataStorage_Software*2-1 }; + enum FaceFilling + { + FaceFilling_Fill, + FaceFilling_Line, + FaceFilling_Point, + + FaceFilling_Max = FaceFilling_Point + }; + + enum FaceSide + { + FaceSide_Back, + FaceSide_Front, + FaceSide_FrontAndBack, + + FaceSide_Max = FaceSide_FrontAndBack + }; + enum ImageType { ImageType_1D, @@ -211,6 +245,73 @@ namespace Nz PrimitiveMode_Max = PrimitiveMode_TriangleFan }; + enum RendererComparison + { + RendererComparison_Always, + RendererComparison_Equal, + RendererComparison_Greater, + RendererComparison_GreaterOrEqual, + RendererComparison_Less, + RendererComparison_LessOrEqual, + RendererComparison_Never, + RendererComparison_NotEqual, + + RendererComparison_Max = RendererComparison_NotEqual + }; + + enum RendererParameter + { + RendererParameter_Blend, + RendererParameter_ColorWrite, + RendererParameter_DepthBuffer, + RendererParameter_DepthWrite, + RendererParameter_FaceCulling, + RendererParameter_ScissorTest, + RendererParameter_StencilTest, + + RendererParameter_Max = RendererParameter_StencilTest + }; + + enum SamplerFilter + { + SamplerFilter_Unknown = -1, + + SamplerFilter_Bilinear, + SamplerFilter_Nearest, + SamplerFilter_Trilinear, + + SamplerFilter_Default, + + SamplerFilter_Max = SamplerFilter_Default + }; + + enum SamplerWrap + { + SamplerWrap_Unknown = -1, + + SamplerWrap_Clamp, + SamplerWrap_MirroredRepeat, + SamplerWrap_Repeat, + + SamplerWrap_Default, + + SamplerWrap_Max = SamplerWrap_Repeat + }; + + enum StencilOperation + { + StencilOperation_Decrement, + StencilOperation_DecrementNoClamp, + StencilOperation_Increment, + StencilOperation_IncrementNoClamp, + StencilOperation_Invert, + StencilOperation_Keep, + StencilOperation_Replace, + StencilOperation_Zero, + + StencilOperation_Max = StencilOperation_Zero + }; + enum TextAlign { TextAlign_Left, diff --git a/include/Nazara/Utility/MaterialData.hpp b/include/Nazara/Utility/MaterialData.hpp new file mode 100644 index 000000000..0f69c9846 --- /dev/null +++ b/include/Nazara/Utility/MaterialData.hpp @@ -0,0 +1,65 @@ +// Copyright (C) 2015 Jérôme Leclercq +// This file is part of the "Nazara Engine - Utility module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#pragma once + +#ifndef NAZARA_MATERIALDATA_HPP +#define NAZARA_MATERIALDATA_HPP + +namespace Nz +{ + struct MaterialData + { + static constexpr const char* AlphaTest = "MatAlphaTest"; + static constexpr const char* AlphaTexturePath = "MatAlphaTexturePath"; + static constexpr const char* AlphaThreshold = "MatAlphaThreshold"; + static constexpr const char* AmbientColor = "MatAmbientColor"; + static constexpr const char* BackFaceStencilCompare = "MatBackFaceStencilCompare"; + static constexpr const char* BackFaceStencilFail = "MatBackFaceStencilFail"; + static constexpr const char* BackFaceStencilMask = "MatBackFaceStencilMask"; + static constexpr const char* BackFaceStencilPass = "MatBackFaceStencilPass"; + static constexpr const char* BackFaceStencilReference = "MatBackFaceStencilReference"; + static constexpr const char* BackFaceStencilZFail = "MatBackFaceStencilZFail"; + static constexpr const char* Blending = "MatBlending"; + static constexpr const char* CustomDefined = "MatCustomDefined"; + static constexpr const char* ColorWrite = "MatColorWrite"; + static constexpr const char* DepthBuffer = "MatDepthBuffer"; + static constexpr const char* DepthFunc = "MatDepthfunc"; + static constexpr const char* DepthSorting = "MatDepthSorting"; + static constexpr const char* DepthWrite = "MatDepthWrite"; + static constexpr const char* DiffuseAnisotropyLevel = "MatDiffuseAnisotropyLevel"; + static constexpr const char* DiffuseColor = "MatDiffuseColor"; + static constexpr const char* DiffuseFilter = "MatDiffuseFilter"; + static constexpr const char* DiffuseTexturePath = "MatDiffuseTexturePath"; + static constexpr const char* DiffuseWrap = "MatDiffuseWrap"; + static constexpr const char* DstBlend = "MatDstBlend"; + static constexpr const char* EmissiveTexturePath = "MatEmissiveTexturePath"; + static constexpr const char* FaceCulling = "MatFaceCulling"; + static constexpr const char* FaceFilling = "MatFaceFilling"; + static constexpr const char* FilePath = "MatFilePath"; + static constexpr const char* HeightTexturePath = "MatHeightTexturePath"; + static constexpr const char* Lighting = "MatLighting"; + static constexpr const char* LineWidth = "MatLineWidth"; + static constexpr const char* NormalTexturePath = "MatNormalTexturePath"; + static constexpr const char* PointSize = "MatPointSize"; + static constexpr const char* ScissorTest = "MatScissorTest"; + static constexpr const char* Shininess = "MatShininess"; + static constexpr const char* SpecularAnisotropyLevel = "MatSpecularAnisotropyLevel"; + static constexpr const char* SpecularColor = "MatSpecularColor"; + static constexpr const char* SpecularFilter = "MatSpecularFilter"; + static constexpr const char* SpecularTexturePath = "MatSpecularTexturePath"; + static constexpr const char* SpecularWrap = "MatSpecularWrap"; + static constexpr const char* SrcBlend = "MatSrcBlend"; + static constexpr const char* StencilCompare = "MatStencilCompare"; + static constexpr const char* StencilFail = "MatStencilFail"; + static constexpr const char* StencilMask = "MatStencilMask"; + static constexpr const char* StencilPass = "MatStencilPass"; + static constexpr const char* StencilReference = "MatStencilReference"; + static constexpr const char* StencilTest = "MatStencilTest"; + static constexpr const char* StencilZFail = "MatStencilZFail"; + static constexpr const char* Transform = "MatTransform"; + }; +} + +#endif // NAZARA_MATERIALDATA_HPP diff --git a/include/Nazara/Utility/Mesh.hpp b/include/Nazara/Utility/Mesh.hpp index 433f50ab5..ff11b5d4d 100644 --- a/include/Nazara/Utility/Mesh.hpp +++ b/include/Nazara/Utility/Mesh.hpp @@ -93,7 +93,8 @@ namespace Nz String GetAnimation() const; AnimationType GetAnimationType() const; unsigned int GetJointCount() const; - String GetMaterial(unsigned int index) const; + ParameterList& GetMaterialData(unsigned int index); + const ParameterList& GetMaterialData(unsigned int index) const; unsigned int GetMaterialCount() const; Skeleton* GetSkeleton(); const Skeleton* GetSkeleton() const; @@ -124,8 +125,8 @@ namespace Nz void RemoveSubMesh(unsigned int index); void SetAnimation(const String& animationPath); - void SetMaterial(unsigned int matIndex, const String& materialPath); void SetMaterialCount(unsigned int matCount); + void SetMaterialData(unsigned int matIndex, ParameterList data); void Transform(const Matrix4f& matrix); diff --git a/src/Nazara/Graphics/Formats/MeshLoader.cpp b/src/Nazara/Graphics/Formats/MeshLoader.cpp index b915c6f2e..ffd2b423e 100644 --- a/src/Nazara/Graphics/Formats/MeshLoader.cpp +++ b/src/Nazara/Graphics/Formats/MeshLoader.cpp @@ -3,9 +3,11 @@ // For conditions of distribution and use, see copyright notice in Config.hpp #include +#include #include #include #include +#include #include #include #include @@ -14,6 +16,33 @@ namespace Nz { namespace { + void LoadMaterials(Model* model, const ModelParameters& parameters) + { + unsigned int matCount = model->GetMaterialCount(); + + for (unsigned int i = 0; i < matCount; ++i) + { + const ParameterList& matData = model->GetMesh()->GetMaterialData(i); + + String filePath; + if (matData.GetStringParameter(MaterialData::FilePath, &filePath)) + { + MaterialRef material = Material::New(); + if (material->LoadFromFile(filePath, parameters.material)) + model->SetMaterial(i, std::move(material)); + else + NazaraWarning("Failed to load material from file " + String::Number(i)); + } + else if (matData.HasParameter(MaterialData::CustomDefined)) + { + MaterialRef material = Material::New(); + material->BuildFromParameters(matData, parameters.material); + + model->SetMaterial(i, std::move(material)); + } + } + } + Ternary CheckStatic(Stream& stream, const ModelParameters& parameters) { NazaraUnused(stream); @@ -46,22 +75,7 @@ namespace Nz model->SetMesh(mesh); if (parameters.loadMaterials) - { - unsigned int matCount = model->GetMaterialCount(); - - for (unsigned int i = 0; i < matCount; ++i) - { - String mat = mesh->GetMaterial(i); - if (!mat.IsEmpty()) - { - MaterialRef material = Material::New(); - if (material->LoadFromFile(mat, parameters.material)) - model->SetMaterial(i, material); - else - NazaraWarning("Failed to load material #" + String::Number(i)); - } - } - } + LoadMaterials(model, parameters); return true; } @@ -98,22 +112,7 @@ namespace Nz model->SetMesh(mesh); if (parameters.loadMaterials) - { - unsigned int matCount = model->GetMaterialCount(); - - for (unsigned int i = 0; i < matCount; ++i) - { - String mat = mesh->GetMaterial(i); - if (!mat.IsEmpty()) - { - MaterialRef material = Material::New(); - if (material->LoadFromFile(mat, parameters.material)) - model->SetMaterial(i, material); - else - NazaraWarning("Failed to load material #" + String::Number(i)); - } - } - } + LoadMaterials(model, parameters); return true; } diff --git a/src/Nazara/Graphics/Graphics.cpp b/src/Nazara/Graphics/Graphics.cpp index a96f2f4e7..03c343ed3 100644 --- a/src/Nazara/Graphics/Graphics.cpp +++ b/src/Nazara/Graphics/Graphics.cpp @@ -20,7 +20,6 @@ #include #include #include -#include #include #include #include @@ -96,9 +95,6 @@ namespace Nz return false; } - // Loaders - Loaders::RegisterOBJ(); - // Loaders génériques Loaders::RegisterMesh(); Loaders::RegisterTexture(); @@ -176,7 +172,6 @@ namespace Nz // Loaders Loaders::UnregisterMesh(); - Loaders::UnregisterOBJ(); Loaders::UnregisterTexture(); DeferredRenderTechnique::Uninitialize(); diff --git a/src/Nazara/Graphics/Material.cpp b/src/Nazara/Graphics/Material.cpp index 0a4755c03..c646d940b 100644 --- a/src/Nazara/Graphics/Material.cpp +++ b/src/Nazara/Graphics/Material.cpp @@ -7,6 +7,7 @@ #endif #include +#include #include #include #include @@ -139,6 +140,166 @@ namespace Nz return instance.shader; } + void Material::BuildFromParameters(const ParameterList& matData, const MaterialParams& matParams) + { + Color color; + bool isEnabled; + float fValue; + int iValue; + String path; + + ErrorFlags errFlags(ErrorFlag_Silent | ErrorFlag_ThrowExceptionDisabled, true); + + + if (matData.GetFloatParameter(MaterialData::AlphaThreshold, &fValue)) + SetAlphaThreshold(fValue); + + if (matData.GetBooleanParameter(MaterialData::AlphaTest, &isEnabled)) + EnableAlphaTest(isEnabled); + + if (matData.GetColorParameter(MaterialData::AmbientColor, &color)) + SetAmbientColor(color); + + if (matData.GetIntegerParameter(MaterialData::DepthFunc, &iValue)) + SetDepthFunc(static_cast(iValue)); + + if (matData.GetBooleanParameter(MaterialData::DepthSorting, &isEnabled)) + EnableDepthSorting(isEnabled); + + if (matData.GetColorParameter(MaterialData::DiffuseColor, &color)) + SetDiffuseColor(color); + + if (matData.GetIntegerParameter(MaterialData::DstBlend, &iValue)) + SetDstBlend(static_cast(iValue)); + + if (matData.GetIntegerParameter(MaterialData::FaceCulling, &iValue)) + SetFaceCulling(static_cast(iValue)); + + if (matData.GetIntegerParameter(MaterialData::FaceFilling, &iValue)) + SetFaceFilling(static_cast(iValue)); + + if (matData.GetBooleanParameter(MaterialData::Lighting, &isEnabled)) + EnableLighting(isEnabled); + + if (matData.GetFloatParameter(MaterialData::LineWidth, &fValue)) + m_states.lineWidth = fValue; + + if (matData.GetFloatParameter(MaterialData::PointSize, &fValue)) + m_states.pointSize = fValue; + + if (matData.GetColorParameter(MaterialData::SpecularColor, &color)) + SetSpecularColor(color); + + if (matData.GetFloatParameter(MaterialData::Shininess, &fValue)) + SetShininess(fValue); + + if (matData.GetIntegerParameter(MaterialData::SrcBlend, &iValue)) + SetSrcBlend(static_cast(iValue)); + + if (matData.GetBooleanParameter(MaterialData::Transform, &isEnabled)) + EnableTransform(isEnabled); + + // RendererParameter + if (matData.GetBooleanParameter(MaterialData::Blending, &isEnabled)) + Enable(RendererParameter_Blend, isEnabled); + + if (matData.GetBooleanParameter(MaterialData::ColorWrite, &isEnabled)) + Enable(RendererParameter_ColorWrite, isEnabled); + + if (matData.GetBooleanParameter(MaterialData::DepthBuffer, &isEnabled)) + Enable(RendererParameter_DepthBuffer, isEnabled); + + if (matData.GetBooleanParameter(MaterialData::DepthWrite, &isEnabled)) + Enable(RendererParameter_DepthWrite, isEnabled); + + if (matData.GetBooleanParameter(MaterialData::FaceCulling, &isEnabled)) + Enable(RendererParameter_FaceCulling, isEnabled); + + if (matData.GetBooleanParameter(MaterialData::ScissorTest, &isEnabled)) + Enable(RendererParameter_ScissorTest, isEnabled); + + if (matData.GetBooleanParameter(MaterialData::StencilTest, &isEnabled)) + Enable(RendererParameter_StencilTest, isEnabled); + + // Samplers + if (matData.GetIntegerParameter(MaterialData::DiffuseAnisotropyLevel, &iValue)) + m_diffuseSampler.SetAnisotropyLevel(static_cast(iValue)); + + if (matData.GetIntegerParameter(MaterialData::DiffuseFilter, &iValue)) + m_diffuseSampler.SetFilterMode(static_cast(iValue)); + + if (matData.GetIntegerParameter(MaterialData::DiffuseWrap, &iValue)) + m_diffuseSampler.SetWrapMode(static_cast(iValue)); + + if (matData.GetIntegerParameter(MaterialData::SpecularAnisotropyLevel, &iValue)) + m_specularSampler.SetAnisotropyLevel(static_cast(iValue)); + + if (matData.GetIntegerParameter(MaterialData::SpecularFilter, &iValue)) + m_specularSampler.SetFilterMode(static_cast(iValue)); + + if (matData.GetIntegerParameter(MaterialData::SpecularWrap, &iValue)) + m_specularSampler.SetWrapMode(static_cast(iValue)); + + // Stencil + if (matData.GetIntegerParameter(MaterialData::StencilCompare, &iValue)) + m_states.frontFace.stencilCompare = static_cast(iValue); + + if (matData.GetIntegerParameter(MaterialData::StencilFail, &iValue)) + m_states.frontFace.stencilFail = static_cast(iValue); + + if (matData.GetIntegerParameter(MaterialData::StencilPass, &iValue)) + m_states.frontFace.stencilPass = static_cast(iValue); + + if (matData.GetIntegerParameter(MaterialData::StencilZFail, &iValue)) + m_states.frontFace.stencilZFail = static_cast(iValue); + + if (matData.GetIntegerParameter(MaterialData::StencilMask, &iValue)) + m_states.frontFace.stencilMask = static_cast(iValue); + + if (matData.GetIntegerParameter(MaterialData::StencilReference, &iValue)) + m_states.frontFace.stencilReference = static_cast(iValue); + + // Stencil (back) + if (matData.GetIntegerParameter(MaterialData::BackFaceStencilCompare, &iValue)) + m_states.backFace.stencilCompare = static_cast(iValue); + + if (matData.GetIntegerParameter(MaterialData::BackFaceStencilFail, &iValue)) + m_states.backFace.stencilFail = static_cast(iValue); + + if (matData.GetIntegerParameter(MaterialData::BackFaceStencilPass, &iValue)) + m_states.backFace.stencilPass = static_cast(iValue); + + if (matData.GetIntegerParameter(MaterialData::BackFaceStencilZFail, &iValue)) + m_states.backFace.stencilZFail = static_cast(iValue); + + if (matData.GetIntegerParameter(MaterialData::BackFaceStencilMask, &iValue)) + m_states.backFace.stencilMask = static_cast(iValue); + + if (matData.GetIntegerParameter(MaterialData::BackFaceStencilReference, &iValue)) + m_states.backFace.stencilReference = static_cast(iValue); + + // Textures + if (matParams.loadAlphaMap && matData.GetStringParameter(MaterialData::AlphaTexturePath, &path)) + SetAlphaMap(path); + + if (matParams.loadDiffuseMap && matData.GetStringParameter(MaterialData::DiffuseTexturePath, &path)) + SetDiffuseMap(path); + + if (matParams.loadEmissiveMap && matData.GetStringParameter(MaterialData::EmissiveTexturePath, &path)) + SetEmissiveMap(path); + + if (matParams.loadHeightMap && matData.GetStringParameter(MaterialData::HeightTexturePath, &path)) + SetHeightMap(path); + + if (matParams.loadNormalMap && matData.GetStringParameter(MaterialData::NormalTexturePath, &path)) + SetNormalMap(path); + + if (matParams.loadSpecularMap && matData.GetStringParameter(MaterialData::SpecularTexturePath, &path)) + SetSpecularMap(path); + + SetShader(matParams.shaderName); + } + void Material::Enable(RendererParameter renderParameter, bool enable) { #ifdef NAZARA_DEBUG diff --git a/src/Nazara/Utility/Formats/MD2Loader.cpp b/src/Nazara/Utility/Formats/MD2Loader.cpp index 184adfe17..eef4ac63d 100644 --- a/src/Nazara/Utility/Formats/MD2Loader.cpp +++ b/src/Nazara/Utility/Formats/MD2Loader.cpp @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -99,7 +100,11 @@ namespace Nz for (unsigned int i = 0; i < header.num_skins; ++i) { stream.Read(skin, 68*sizeof(char)); - mesh->SetMaterial(i, baseDir + skin); + + ParameterList matData; + matData.SetParameter(MaterialData::FilePath, baseDir + skin); + + mesh->SetMaterialData(i, std::move(matData)); } } } diff --git a/src/Nazara/Utility/Formats/MD5MeshLoader.cpp b/src/Nazara/Utility/Formats/MD5MeshLoader.cpp index 629452161..9f7b6151c 100644 --- a/src/Nazara/Utility/Formats/MD5MeshLoader.cpp +++ b/src/Nazara/Utility/Formats/MD5MeshLoader.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include @@ -189,7 +190,10 @@ namespace Nz vertexMapper.Unmap(); // Material - mesh->SetMaterial(i, baseDir + md5Mesh.shader); + ParameterList matData; + matData.SetParameter(MaterialData::FilePath, baseDir + md5Mesh.shader); + + mesh->SetMaterialData(i, std::move(matData)); // Submesh SkeletalMeshRef subMesh = SkeletalMesh::New(mesh); @@ -285,7 +289,10 @@ namespace Nz mesh->AddSubMesh(subMesh); // Material - mesh->SetMaterial(i, baseDir + md5Mesh.shader); + ParameterList matData; + matData.SetParameter(MaterialData::FilePath, baseDir + md5Mesh.shader); + + mesh->SetMaterialData(i, std::move(matData)); } if (parameters.center) diff --git a/src/Nazara/Graphics/Formats/OBJLoader.cpp b/src/Nazara/Utility/Formats/OBJLoader.cpp similarity index 67% rename from src/Nazara/Graphics/Formats/OBJLoader.cpp rename to src/Nazara/Utility/Formats/OBJLoader.cpp index 09ad743d7..75b5ba22f 100644 --- a/src/Nazara/Graphics/Formats/OBJLoader.cpp +++ b/src/Nazara/Utility/Formats/OBJLoader.cpp @@ -1,14 +1,13 @@ -// Copyright (C) 2015 Jérôme Leclercq -// This file is part of the "Nazara Engine - Graphics module" +// Copyright (C) 2016 Jérôme Leclercq +// This file is part of the "Nazara Engine - Utility 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 @@ -17,7 +16,7 @@ #include #include #include -#include +#include ///TODO: N'avoir qu'un seul VertexBuffer communs à tous les meshes @@ -30,7 +29,7 @@ namespace Nz return (extension == "obj"); } - Ternary Check(Stream& stream, const ModelParameters& parameters) + Ternary Check(Stream& stream, const MeshParams& parameters) { NazaraUnused(stream); @@ -41,7 +40,7 @@ namespace Nz return Ternary_Unknown; } - bool LoadMaterials(Model* model, const String& filePath, const MaterialParams& parameters, const String* materials, const OBJParser::Mesh* meshes, unsigned int meshCount) + bool ParseMTL(Mesh* mesh, const String& filePath, const String* materials, const OBJParser::Mesh* meshes, unsigned int meshCount) { File file(filePath); if (!file.Open(OpenMode_ReadOnly | OpenMode_Text)) @@ -57,7 +56,7 @@ namespace Nz return false; } - std::unordered_map materialCache; + std::unordered_map materialCache; String baseDir = file.GetDirectory(); for (unsigned int i = 0; i < meshCount; ++i) { @@ -72,8 +71,9 @@ namespace Nz auto it = materialCache.find(matName); if (it == materialCache.end()) { - MaterialRef material = Material::New(); - material->SetShader(parameters.shaderName); + ParameterList data; + + data.SetParameter(MaterialData::CustomDefined); UInt8 alphaValue = static_cast(mtlMat->alpha*255.f); @@ -84,54 +84,40 @@ namespace Nz diffuseColor.a = alphaValue; specularColor.a = alphaValue; - material->SetAmbientColor(ambientColor); - material->SetDiffuseColor(diffuseColor); - material->SetSpecularColor(specularColor); - material->SetShininess(mtlMat->shininess); + data.SetParameter(MaterialData::AmbientColor, ambientColor); + data.SetParameter(MaterialData::DiffuseColor, diffuseColor); + data.SetParameter(MaterialData::Shininess, mtlMat->shininess); + data.SetParameter(MaterialData::SpecularColor, specularColor); - bool isTranslucent = (alphaValue != 255); + if (!mtlMat->alphaMap.IsEmpty()) + data.SetParameter(MaterialData::AlphaTexturePath, baseDir + mtlMat->alphaMap); - if (parameters.loadAlphaMap && !mtlMat->alphaMap.IsEmpty()) + if (!mtlMat->diffuseMap.IsEmpty()) + data.SetParameter(MaterialData::DiffuseTexturePath, baseDir + mtlMat->diffuseMap); + + if (!mtlMat->specularMap.IsEmpty()) + data.SetParameter(MaterialData::SpecularTexturePath, baseDir + mtlMat->specularMap); + + // If we either have an alpha value or an alpha map, let's configure the material for transparency + if (alphaValue != 255 || !mtlMat->alphaMap.IsEmpty()) { - if (material->SetAlphaMap(baseDir + mtlMat->alphaMap)) - isTranslucent = true; // Une alpha map indique de la transparence - else - NazaraWarning("Failed to load alpha map (" + mtlMat->alphaMap + ')'); + // Some default settings + data.SetParameter(MaterialData::Blending, true); + data.SetParameter(MaterialData::DepthWrite, true); + data.SetParameter(MaterialData::DstBlend, static_cast(BlendFunc_InvSrcAlpha)); + data.SetParameter(MaterialData::SrcBlend, static_cast(BlendFunc_SrcAlpha)); } - if (parameters.loadDiffuseMap && !mtlMat->diffuseMap.IsEmpty()) - { - if (!material->SetDiffuseMap(baseDir + mtlMat->diffuseMap)) - NazaraWarning("Failed to load diffuse map (" + mtlMat->diffuseMap + ')'); - } - - if (parameters.loadSpecularMap && !mtlMat->specularMap.IsEmpty()) - { - if (!material->SetSpecularMap(baseDir + mtlMat->specularMap)) - NazaraWarning("Failed to load specular map (" + mtlMat->specularMap + ')'); - } - - // Si nous avons une alpha map ou des couleurs transparentes, - // nous devons configurer le matériau pour accepter la transparence au mieux - if (isTranslucent) - { - // On paramètre le matériau pour accepter la transparence au mieux - material->Enable(RendererParameter_Blend, true); - material->Enable(RendererParameter_DepthWrite, false); - material->SetDstBlend(BlendFunc_InvSrcAlpha); - material->SetSrcBlend(BlendFunc_SrcAlpha); - } - - it = materialCache.emplace(matName, std::move(material)).first; + it = materialCache.emplace(matName, std::move(data)).first; } - model->SetMaterial(meshes[i].material, it->second); + mesh->SetMaterialData(meshes[i].material, it->second); } return true; } - bool Load(Model* model, Stream& stream, const ModelParameters& parameters) + bool Load(Mesh* mesh, Stream& stream, const MeshParams& parameters) { int reservedVertexCount; if (!parameters.custom.GetIntegerParameter("NativeOBJLoader_VertexCount", &reservedVertexCount)) @@ -144,12 +130,7 @@ namespace Nz return false; } - MeshRef mesh = Mesh::New(); - if (!mesh->CreateStatic()) // Ne devrait jamais échouer - { - NazaraInternalError("Failed to create mesh"); - return false; - } + mesh->CreateStatic(); const String* materials = parser.GetMaterials(); const Vector4f* positions = parser.GetPositions(); @@ -160,8 +141,8 @@ namespace Nz unsigned int meshCount = parser.GetMeshCount(); NazaraAssert(materials != nullptr && positions != nullptr && normals != nullptr && - texCoords != nullptr && meshes != nullptr && meshCount > 0, - "Invalid OBJParser output"); + texCoords != nullptr && meshes != nullptr && meshCount > 0, + "Invalid OBJParser output"); // Un conteneur temporaire pour contenir les indices de face avant triangulation std::vector faceIndices(3); // Comme il y aura au moins trois sommets @@ -197,8 +178,8 @@ namespace Nz bool operator()(const OBJParser::FaceVertex& lhs, const OBJParser::FaceVertex& rhs) const { return lhs.normal == rhs.normal && - lhs.position == rhs.position && - lhs.texCoord == rhs.texCoord; + lhs.position == rhs.position && + lhs.texCoord == rhs.texCoord; } }; @@ -230,8 +211,8 @@ namespace Nz } // Création des buffers - IndexBufferRef indexBuffer = IndexBuffer::New(vertexCount > std::numeric_limits::max(), indices.size(), parameters.mesh.storage, BufferUsage_Static); - VertexBufferRef vertexBuffer = VertexBuffer::New(VertexDeclaration::Get(VertexLayout_XYZ_Normal_UV_Tangent), vertexCount, parameters.mesh.storage, BufferUsage_Static); + IndexBufferRef indexBuffer = IndexBuffer::New(vertexCount > std::numeric_limits::max(), indices.size(), parameters.storage, BufferUsage_Static); + VertexBufferRef vertexBuffer = VertexBuffer::New(VertexDeclaration::Get(VertexLayout_XYZ_Normal_UV_Tangent), vertexCount, parameters.storage, BufferUsage_Static); // Remplissage des indices IndexMapper indexMapper(indexBuffer, BufferAccess_WriteOnly); @@ -254,7 +235,7 @@ namespace Nz const Vector4f& vec = positions[vertexIndices.position]; vertex.position.Set(vec.x, vec.y, vec.z); - vertex.position *= parameters.mesh.scale/vec.w; + vertex.position *= parameters.scale/vec.w; if (vertexIndices.normal >= 0) vertex.normal = normals[vertexIndices.normal]; @@ -264,7 +245,7 @@ namespace Nz if (vertexIndices.texCoord >= 0) { const Vector3f& uvw = texCoords[vertexIndices.texCoord]; - vertex.uv.Set(uvw.x, (parameters.mesh.flipUVs) ? 1.f - uvw.y : uvw.y); // Inversion des UVs si demandé + vertex.uv.Set(uvw.x, (parameters.flipUVs) ? 1.f - uvw.y : uvw.y); // Inversion des UVs si demandé } else hasTexCoords = false; @@ -279,7 +260,7 @@ namespace Nz continue; } - if (parameters.mesh.optimizeIndexBuffers) + if (parameters.optimizeIndexBuffers) indexBuffer->Optimize(); subMesh->GenerateAABB(); @@ -299,17 +280,15 @@ namespace Nz } mesh->SetMaterialCount(parser.GetMaterialCount()); - if (parameters.mesh.center) + if (parameters.center) mesh->Recenter(); - model->SetMesh(mesh); - // On charge les matériaux si demandé String mtlLib = parser.GetMtlLib(); - if (parameters.loadMaterials && !mtlLib.IsEmpty()) + if (!mtlLib.IsEmpty()) { ErrorFlags flags(ErrorFlag_ThrowExceptionDisabled); - LoadMaterials(model, stream.GetDirectory() + mtlLib, parameters.material, materials, meshes, meshCount); + ParseMTL(mesh, stream.GetDirectory() + mtlLib, materials, meshes, meshCount); } return true; @@ -320,12 +299,12 @@ namespace Nz { void RegisterOBJ() { - ModelLoader::RegisterLoader(IsSupported, Check, Load); + MeshLoader::RegisterLoader(IsSupported, Check, Load); } void UnregisterOBJ() { - ModelLoader::UnregisterLoader(IsSupported, Check, Load); + MeshLoader::UnregisterLoader(IsSupported, Check, Load); } } } diff --git a/src/Nazara/Graphics/Formats/OBJLoader.hpp b/src/Nazara/Utility/Formats/OBJLoader.hpp similarity index 100% rename from src/Nazara/Graphics/Formats/OBJLoader.hpp rename to src/Nazara/Utility/Formats/OBJLoader.hpp diff --git a/src/Nazara/Utility/Mesh.cpp b/src/Nazara/Utility/Mesh.cpp index 82c903cae..fca38e415 100644 --- a/src/Nazara/Utility/Mesh.cpp +++ b/src/Nazara/Utility/Mesh.cpp @@ -52,11 +52,11 @@ namespace Nz { MeshImpl() { - materials.resize(1); // Un matériau par défaut + materialData.resize(1); // Un matériau par défaut } std::unordered_map subMeshMap; - std::vector materials; + std::vector materialData; std::vector subMeshes; AnimationType animationType; Boxf aabb; @@ -75,93 +75,36 @@ namespace Nz void Mesh::AddSubMesh(SubMesh* subMesh) { - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Mesh not created"); - return; - } + NazaraAssert(m_impl, "Mesh should be created first"); + NazaraAssert(subMesh, "Invalid submesh"); + NazaraAssert(subMesh->GetAnimationType() == m_impl->animationType, "Submesh animation type doesn't match mesh animation type"); - if (!subMesh) - { - NazaraError("Invalid submesh"); - return; - } - - if (subMesh->GetAnimationType() != m_impl->animationType) - { - NazaraError("Submesh animation type must match mesh animation type"); - return; - } - #endif - - m_impl->aabbUpdated = false; // On invalide l'AABB m_impl->subMeshes.push_back(subMesh); + + InvalidateAABB(); } void Mesh::AddSubMesh(const String& identifier, SubMesh* subMesh) { - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Mesh not created"); - return; - } - - if (identifier.IsEmpty()) - { - NazaraError("Identifier is empty"); - return; - } - - auto it = m_impl->subMeshMap.find(identifier); - if (it != m_impl->subMeshMap.end()) - { - NazaraError("SubMesh identifier \"" + identifier + "\" is already used"); - return; - } - - if (!subMesh) - { - NazaraError("Invalid submesh"); - return; - } - - if (m_impl->animationType != subMesh->GetAnimationType()) - { - NazaraError("Submesh animation type must match mesh animation type"); - return; - } - #endif + NazaraAssert(m_impl, "Mesh should be created first"); + NazaraAssert(!identifier.IsEmpty(), "Identifier is empty"); + NazaraAssert(m_impl->subMeshMap.find(identifier) == m_impl->subMeshMap.end(), "SubMesh identifier \"" + identifier + "\" is already in use"); + NazaraAssert(subMesh, "Invalid submesh"); + NazaraAssert(subMesh->GetAnimationType() == m_impl->animationType, "Submesh animation type doesn't match mesh animation type"); int index = m_impl->subMeshes.size(); - m_impl->aabbUpdated = false; // On invalide l'AABB m_impl->subMeshes.push_back(subMesh); m_impl->subMeshMap[identifier] = index; + + InvalidateAABB(); } SubMesh* Mesh::BuildSubMesh(const Primitive& primitive, const MeshParams& params) { - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Mesh not created"); - return nullptr; - } - - if (m_impl->animationType != AnimationType_Static) - { - NazaraError("Mesh must be static"); - return nullptr; - } - - if (!params.IsValid()) - { - NazaraError("Parameters must be valid"); - return nullptr; - } - #endif + NazaraAssert(m_impl, "Mesh should be created first"); + NazaraAssert(m_impl->animationType == AnimationType_Static, "Submesh building only works for static meshes"); + NazaraAssert(params.IsValid(), "Invalid parameters"); Boxf aabb; IndexBufferRef indexBuffer; @@ -333,17 +276,7 @@ namespace Nz void Mesh::BuildSubMeshes(const PrimitiveList& list, const MeshParams& params) { - unsigned int primitiveCount = list.GetSize(); - - #if NAZARA_UTILITY_SAFE - if (primitiveCount == 0) - { - NazaraError("PrimitiveList must have at least one primitive"); - return; - } - #endif - - for (unsigned int i = 0; i < primitiveCount; ++i) + for (unsigned int i = 0; i < list.GetSize(); ++i) BuildSubMesh(list.GetPrimitive(i), params); } @@ -351,18 +284,17 @@ namespace Nz { Destroy(); - m_impl = new MeshImpl; - m_impl->animationType = AnimationType_Skeletal; - m_impl->jointCount = jointCount; - if (!m_impl->skeleton.Create(jointCount)) + std::unique_ptr impl(new MeshImpl); + impl->animationType = AnimationType_Skeletal; + impl->jointCount = jointCount; + if (!impl->skeleton.Create(jointCount)) { - delete m_impl; - m_impl = nullptr; - NazaraError("Failed to create skeleton"); return false; } + m_impl = impl.release(); + return true; } @@ -389,13 +321,7 @@ namespace Nz void Mesh::GenerateNormals() { - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Mesh not created"); - return; - } - #endif + NazaraAssert(m_impl, "Mesh should be created first"); for (SubMesh* subMesh : m_impl->subMeshes) subMesh->GenerateNormals(); @@ -403,13 +329,7 @@ namespace Nz void Mesh::GenerateNormalsAndTangents() { - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Mesh not created"); - return; - } - #endif + NazaraAssert(m_impl, "Mesh should be created first"); for (SubMesh* subMesh : m_impl->subMeshes) subMesh->GenerateNormalsAndTangents(); @@ -417,13 +337,7 @@ namespace Nz void Mesh::GenerateTangents() { - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Mesh not created"); - return; - } - #endif + NazaraAssert(m_impl, "Mesh should be created first"); for (SubMesh* subMesh : m_impl->subMeshes) subMesh->GenerateTangents(); @@ -431,15 +345,7 @@ namespace Nz const Boxf& Mesh::GetAABB() const { - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Mesh not created"); - - static Boxf dummy; - return dummy; - } - #endif + NazaraAssert(m_impl, "Mesh should be created first"); if (!m_impl->aabbUpdated) { @@ -461,248 +367,121 @@ namespace Nz String Mesh::GetAnimation() const { - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Mesh not created"); - return String(); - } - #endif + NazaraAssert(m_impl, "Mesh should be created first"); return m_impl->animationPath; } AnimationType Mesh::GetAnimationType() const { - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Mesh not created"); - return AnimationType_Static; - } - #endif + NazaraAssert(m_impl, "Mesh should be created first"); return m_impl->animationType; } unsigned int Mesh::GetJointCount() const { - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Mesh not created"); - return 0; - } - - if (m_impl->animationType != AnimationType_Skeletal) - { - NazaraError("Mesh's animation type is not skeletal"); - return 0; - } - #endif + NazaraAssert(m_impl, "Mesh should be created first"); + NazaraAssert(m_impl->animationType == AnimationType_Skeletal, "Mesh is not skeletal"); return m_impl->jointCount; } - String Mesh::GetMaterial(unsigned int index) const + ParameterList& Mesh::GetMaterialData(unsigned int index) { - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Mesh not created"); - return String(); - } + NazaraAssert(m_impl, "Mesh should be created first"); + NazaraAssert(index < m_impl->materialData.size(), "Material index out of range"); - if (index >= m_impl->materials.size()) - { - NazaraError("Material index out of range (" + String::Number(index) + " >= " + String::Number(m_impl->materials.size()) + ')'); - return String(); - } - #endif + return m_impl->materialData[index]; + } - return m_impl->materials[index]; + const ParameterList& Mesh::GetMaterialData(unsigned int index) const + { + NazaraAssert(m_impl, "Mesh should be created first"); + NazaraAssert(index < m_impl->materialData.size(), "Material index out of range"); + + return m_impl->materialData[index]; } unsigned int Mesh::GetMaterialCount() const { - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Mesh not created"); - return 0; - } - #endif + NazaraAssert(m_impl, "Mesh should be created first"); - return m_impl->materials.size(); + return m_impl->materialData.size(); } Skeleton* Mesh::GetSkeleton() { - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Animation not created"); - return nullptr; - } - - if (m_impl->animationType != AnimationType_Skeletal) - { - NazaraError("Mesh's animation type is not skeletal"); - return nullptr; - } - #endif + NazaraAssert(m_impl, "Mesh should be created first"); + NazaraAssert(m_impl->animationType == AnimationType_Skeletal, "Mesh is not skeletal"); return &m_impl->skeleton; } const Skeleton* Mesh::GetSkeleton() const { - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Animation not created"); - return nullptr; - } - - if (m_impl->animationType != AnimationType_Skeletal) - { - NazaraError("Mesh's animation type is not skeletal"); - return nullptr; - } - #endif + NazaraAssert(m_impl, "Mesh should be created first"); + NazaraAssert(m_impl->animationType == AnimationType_Skeletal, "Mesh is not skeletal"); return &m_impl->skeleton; } SubMesh* Mesh::GetSubMesh(const String& identifier) { - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Mesh not created"); - return nullptr; - } - #endif + NazaraAssert(m_impl, "Mesh should be created first"); auto it = m_impl->subMeshMap.find(identifier); - - #if NAZARA_UTILITY_SAFE - if (it == m_impl->subMeshMap.end()) - { - NazaraError("SubMesh not found"); - return nullptr; - } - #endif + NazaraAssert(it != m_impl->subMeshMap.end(), "SubMesh " + identifier + " not found"); return m_impl->subMeshes[it->second]; } SubMesh* Mesh::GetSubMesh(unsigned int index) { - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Mesh not created"); - return nullptr; - } - - if (index >= m_impl->subMeshes.size()) - { - NazaraError("SubMesh index out of range (" + String::Number(index) + " >= " + String::Number(m_impl->subMeshes.size()) + ')'); - return nullptr; - } - #endif + NazaraAssert(m_impl, "Mesh should be created first"); + NazaraAssert(index < m_impl->subMeshes.size(), "Submesh index out of range"); return m_impl->subMeshes[index]; } const SubMesh* Mesh::GetSubMesh(const String& identifier) const { - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Mesh not created"); - return nullptr; - } - #endif + NazaraAssert(m_impl, "Mesh should be created first"); auto it = m_impl->subMeshMap.find(identifier); - - #if NAZARA_UTILITY_SAFE - if (it == m_impl->subMeshMap.end()) - { - NazaraError("SubMesh not found"); - return nullptr; - } - #endif + NazaraAssert(it != m_impl->subMeshMap.end(), "SubMesh " + identifier + " not found"); return m_impl->subMeshes[it->second]; } const SubMesh* Mesh::GetSubMesh(unsigned int index) const { - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Mesh not created"); - return nullptr; - } - - if (index >= m_impl->subMeshes.size()) - { - NazaraError("SubMesh index out of range (" + String::Number(index) + " >= " + String::Number(m_impl->subMeshes.size()) + ')'); - return nullptr; - } - #endif + NazaraAssert(m_impl, "Mesh should be created first"); + NazaraAssert(index < m_impl->subMeshes.size(), "Submesh index out of range"); return m_impl->subMeshes[index]; } unsigned int Mesh::GetSubMeshCount() const { - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Mesh not created"); - return 0; - } - #endif + NazaraAssert(m_impl, "Mesh should be created first"); return m_impl->subMeshes.size(); } int Mesh::GetSubMeshIndex(const String& identifier) const { - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Mesh not created"); - return -1; - } - #endif + NazaraAssert(m_impl, "Mesh should be created first"); auto it = m_impl->subMeshMap.find(identifier); - - #if NAZARA_UTILITY_SAFE - if (it == m_impl->subMeshMap.end()) - { - NazaraError("SubMesh not found"); - return -1; - } - #endif + NazaraAssert(it != m_impl->subMeshMap.end(), "SubMesh " + identifier + " not found"); return it->second; } unsigned int Mesh::GetTriangleCount() const { - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Mesh not created"); - return 0; - } - #endif + NazaraAssert(m_impl, "Mesh should be created first"); unsigned int triangleCount = 0; for (SubMesh* subMesh : m_impl->subMeshes) @@ -713,13 +492,7 @@ namespace Nz unsigned int Mesh::GetVertexCount() const { - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Mesh not created"); - return 0; - } - #endif + NazaraAssert(m_impl, "Mesh should be created first"); unsigned int vertexCount = 0; for (SubMesh* subMesh : m_impl->subMeshes) @@ -730,52 +503,28 @@ namespace Nz void Mesh::InvalidateAABB() const { - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Mesh not created"); - return; - } - #endif + NazaraAssert(m_impl, "Mesh should be created first"); m_impl->aabbUpdated = false; } bool Mesh::HasSubMesh(const String& identifier) const { - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Mesh not created"); - return false; - } - #endif + NazaraAssert(m_impl, "Mesh should be created first"); return m_impl->subMeshMap.find(identifier) != m_impl->subMeshMap.end(); } bool Mesh::HasSubMesh(unsigned int index) const { - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Mesh not created"); - return false; - } - #endif + NazaraAssert(m_impl, "Mesh should be created first"); return index < m_impl->subMeshes.size(); } bool Mesh::IsAnimable() const { - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Mesh not created"); - return false; - } - #endif + NazaraAssert(m_impl, "Mesh should be created first"); return m_impl->animationType != AnimationType_Static; } @@ -802,21 +551,10 @@ namespace Nz void Mesh::Recenter() { - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Mesh not created"); - return; - } + NazaraAssert(m_impl, "Mesh should be created first"); + NazaraAssert(m_impl->animationType == AnimationType_Static, "Mesh is not static"); - if (m_impl->animationType != AnimationType_Static) - { - NazaraError("Mesh must be static"); - return; - } - #endif - - // Le centre de notre mesh est le centre de l'AABB *globale* + // The center of our mesh is the center of our *global* AABB Vector3f center = GetAABB().GetCenter(); for (SubMesh* subMesh : m_impl->subMeshes) @@ -833,119 +571,62 @@ namespace Nz vertices++; } - // l'AABB ne change pas de dimensions mais seulement de position, appliquons-lui le même procédé + // Our AABB doesn't change shape, only position Boxf aabb = staticMesh->GetAABB(); aabb.Translate(-center); staticMesh->SetAABB(aabb); } - // Il ne faut pas oublier d'invalider notre AABB - m_impl->aabbUpdated = false; + InvalidateAABB(); } void Mesh::RemoveSubMesh(const String& identifier) { - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Mesh not created"); - return; - } - - auto it = m_impl->subMeshMap.find(identifier); - if (it == m_impl->subMeshMap.end()) - { - NazaraError("SubMesh not found"); - return; - } - - unsigned int index = it->second; - #else - unsigned int index = m_impl->subMeshMap[identifier]; - #endif + unsigned int index = GetSubMeshIndex(identifier); // On déplace l'itérateur du début d'une distance de x auto it2 = m_impl->subMeshes.begin(); std::advance(it2, index); m_impl->subMeshes.erase(it2); - m_impl->aabbUpdated = false; // On invalide l'AABB + InvalidateAABB(); } void Mesh::RemoveSubMesh(unsigned int index) { - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Mesh not created"); - return; - } - - if (index >= m_impl->subMeshes.size()) - { - NazaraError("SubMesh index out of range (" + String::Number(index) + " >= " + String::Number(m_impl->subMeshes.size()) + ')'); - return; - } - #endif + NazaraAssert(m_impl, "Mesh should be created first"); + NazaraAssert(index < m_impl->subMeshes.size(), "Submesh index out of range"); // On déplace l'itérateur du début de x auto it = m_impl->subMeshes.begin(); std::advance(it, index); m_impl->subMeshes.erase(it); - m_impl->aabbUpdated = false; // On invalide l'AABB + InvalidateAABB(); } void Mesh::SetAnimation(const String& animationPath) { - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Mesh not created"); - return; - } - #endif + NazaraAssert(m_impl, "Mesh should be created first"); m_impl->animationPath = animationPath; } - void Mesh::SetMaterial(unsigned int matIndex, const String& materialPath) + void Mesh::SetMaterialData(unsigned int matIndex, ParameterList data) { - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Mesh not created"); - return; - } + NazaraAssert(m_impl, "Mesh should be created first"); + NazaraAssert(matIndex < m_impl->materialData.size(), "Material index out of range"); - if (matIndex >= m_impl->materials.size()) - { - NazaraError("Material index out of range (" + String::Number(matIndex) + " >= " + String::Number(m_impl->materials.size()) + ')'); - return; - } - #endif - - m_impl->materials[matIndex] = materialPath; + m_impl->materialData[matIndex] = std::move(data); } void Mesh::SetMaterialCount(unsigned int matCount) { - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Mesh not created"); - return; - } + NazaraAssert(m_impl, "Mesh should be created first"); + NazaraAssert(matCount > 0, "A mesh should have at least a material"); - if (matCount == 0) - { - NazaraError("A mesh should have at least a material"); - return; - } - #endif - - m_impl->materials.resize(matCount); + m_impl->materialData.resize(matCount); #ifdef NAZARA_DEBUG for (SubMesh* subMesh : m_impl->subMeshes) @@ -953,7 +634,7 @@ namespace Nz unsigned int matIndex = subMesh->GetMaterialIndex(); if (matIndex >= matCount) { - subMesh->SetMaterialIndex(0); // Pour empêcher un crash + subMesh->SetMaterialIndex(0); // To prevent a crash NazaraWarning("SubMesh " + String::Pointer(subMesh) + " material index is over mesh new material count (" + String::Number(matIndex) + " >= " + String::Number(matCount) + "), setting it to first material"); } } @@ -962,22 +643,8 @@ namespace Nz void Mesh::Transform(const Matrix4f& matrix) { - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Mesh not created"); - return; - } - - if (m_impl->animationType != AnimationType_Static) - { - NazaraError("Mesh must be static"); - return; - } - #endif - - if (matrix.IsIdentity()) - return; + NazaraAssert(m_impl, "Mesh should be created first"); + NazaraAssert(m_impl->animationType == AnimationType_Static, "Mesh is not static"); for (SubMesh* subMesh : m_impl->subMeshes) { @@ -1000,8 +667,7 @@ namespace Nz staticMesh->SetAABB(aabb); } - // Il ne faut pas oublier d'invalider notre AABB - m_impl->aabbUpdated = false; + InvalidateAABB(); } bool Mesh::Initialize() diff --git a/src/Nazara/Utility/Utility.cpp b/src/Nazara/Utility/Utility.cpp index 75084b8c0..78553ce54 100644 --- a/src/Nazara/Utility/Utility.cpp +++ b/src/Nazara/Utility/Utility.cpp @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -114,7 +115,7 @@ namespace Nz Loaders::RegisterFreeType(); // Image - Loaders::RegisterDDSLoader(); // Generic loader (STB) + Loaders::RegisterDDSLoader(); // DDS Loader (DirectX format) Loaders::RegisterSTBLoader(); // Generic loader (STB) Loaders::RegisterSTBSaver(); // Generic saver (STB) @@ -122,6 +123,9 @@ namespace Nz // Animation Loaders::RegisterMD5Anim(); // Loader de fichiers .md5anim (v10) + // Mesh (text) + Loaders::RegisterOBJ(); + // Mesh Loaders::RegisterMD2(); // Loader de fichiers .md2 (v8) Loaders::RegisterMD5Mesh(); // Loader de fichiers .md5mesh (v10) @@ -158,6 +162,7 @@ namespace Nz Loaders::UnregisterMD2(); Loaders::UnregisterMD5Anim(); Loaders::UnregisterMD5Mesh(); + Loaders::UnregisterOBJ(); Loaders::UnregisterPCX(); Loaders::UnregisterSTBLoader(); Loaders::UnregisterSTBSaver(); From d253e22c8f0362fb45fa4a2ab371531e7affb596 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 1 May 2016 19:23:31 +0200 Subject: [PATCH 40/60] Plugins/Assimp: Add material loading Former-commit-id: 09671bb2ad3520622808575af2faca16300d12c1 --- plugins/Assimp/Plugin.cpp | 82 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) diff --git a/plugins/Assimp/Plugin.cpp b/plugins/Assimp/Plugin.cpp index 0e754ea70..395ca6305 100644 --- a/plugins/Assimp/Plugin.cpp +++ b/plugins/Assimp/Plugin.cpp @@ -27,6 +27,7 @@ SOFTWARE. #include #include #include +#include #include #include #include @@ -165,6 +166,9 @@ bool Load(Mesh* mesh, Stream& stream, const MeshParams& parameters) { mesh->CreateStatic(); + // aiMaterial index in scene => Material index and data in Mesh + std::unordered_map> materials; + for (unsigned int i = 0; i < scene->mNumMeshes; ++i) { aiMesh* iMesh = scene->mMeshes[i]; @@ -222,8 +226,86 @@ bool Load(Mesh* mesh, Stream& stream, const MeshParams& parameters) subMesh->GenerateAABB(); subMesh->SetMaterialIndex(iMesh->mMaterialIndex); + auto matIt = materials.find(iMesh->mMaterialIndex); + if (matIt == materials.end()) + { + ParameterList matData; + aiMaterial* aiMat = scene->mMaterials[iMesh->mMaterialIndex]; + + auto ConvertColor = [&] (const char* aiKey, unsigned int aiType, unsigned int aiIndex, const char* colorKey) + { + aiColor4D color; + if (aiGetMaterialColor(aiMat, aiKey, aiType, aiIndex, &color) == aiReturn_SUCCESS) + { + matData.SetParameter(MaterialData::CustomDefined); + + matData.SetParameter(colorKey, Color(static_cast(color.r * 255), static_cast(color.g * 255), static_cast(color.b * 255), static_cast(color.a * 255))); + } + }; + + auto ConvertTexture = [&] (aiTextureType aiType, const char* textureKey, const char* wrapKey = nullptr) + { + aiString path; + aiTextureMapMode mapMode; + if (aiGetMaterialTexture(aiMat, aiType, 0, &path, nullptr, nullptr, nullptr, nullptr, &mapMode, nullptr) == aiReturn_SUCCESS) + { + matData.SetParameter(MaterialData::CustomDefined); + matData.SetParameter(textureKey, stream.GetDirectory() + String(path.data, path.length)); + + if (wrapKey) + { + SamplerWrap wrap = SamplerWrap_Default; + switch (mapMode) + { + case aiTextureMapMode_Clamp: + case aiTextureMapMode_Decal: + wrap = SamplerWrap_Clamp; + break; + + case aiTextureMapMode_Mirror: + wrap = SamplerWrap_MirroredRepeat; + break; + + case aiTextureMapMode_Wrap: + wrap = SamplerWrap_Repeat; + break; + + default: + NazaraWarning("Assimp texture map mode 0x" + String::Number(mapMode, 16) + " not handled"); + break; + } + + matData.SetParameter(wrapKey, static_cast(wrap)); + } + } + }; + + ConvertColor(AI_MATKEY_COLOR_AMBIENT, MaterialData::AmbientColor); + ConvertColor(AI_MATKEY_COLOR_DIFFUSE, MaterialData::DiffuseColor); + ConvertColor(AI_MATKEY_COLOR_SPECULAR, MaterialData::SpecularColor); + + ConvertTexture(aiTextureType_DIFFUSE, MaterialData::DiffuseTexturePath, MaterialData::DiffuseWrap); + ConvertTexture(aiTextureType_EMISSIVE, MaterialData::EmissiveTexturePath); + ConvertTexture(aiTextureType_HEIGHT, MaterialData::HeightTexturePath); + ConvertTexture(aiTextureType_NORMALS, MaterialData::NormalTexturePath); + ConvertTexture(aiTextureType_OPACITY, MaterialData::AlphaTexturePath); + ConvertTexture(aiTextureType_SPECULAR, MaterialData::SpecularTexturePath, MaterialData::SpecularWrap); + + int iValue; + if (aiGetMaterialInteger(aiMat, AI_MATKEY_TWOSIDED, &iValue)) + matData.SetParameter(MaterialData::FaceCulling, !iValue); + + matIt = materials.insert(std::make_pair(iMesh->mMaterialIndex, std::make_pair(materials.size(), std::move(matData)))).first; + } + + subMesh->SetMaterialIndex(matIt->first); + mesh->AddSubMesh(subMesh); } + + mesh->SetMaterialCount(std::max(materials.size(), 1)); + for (const auto& pair : materials) + mesh->SetMaterialData(pair.second.first, pair.second.second); } if (parameters.center) From 1fa545da736b95da9b29b8523a551fe008bfab67 Mon Sep 17 00:00:00 2001 From: Lynix Date: Tue, 3 May 2016 12:42:52 +0200 Subject: [PATCH 41/60] Utility/Formats: Fix MD5 loading Former-commit-id: 6eb5e2bc69277e0bd87284a66ed73f6fa7e5101c --- src/Nazara/Core/String.cpp | 10 ++++++---- src/Nazara/Utility/Formats/MD5MeshLoader.cpp | 2 +- src/Nazara/Utility/Formats/MD5MeshParser.cpp | 1 + 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/Nazara/Core/String.cpp b/src/Nazara/Core/String.cpp index b94715457..a57d89861 100644 --- a/src/Nazara/Core/String.cpp +++ b/src/Nazara/Core/String.cpp @@ -4240,7 +4240,7 @@ namespace Nz utf8::unchecked::iterator it(m_sharedString->string.get()); do { - if ((Unicode::GetCategory(*it) & Unicode::Category_Separator) == 0) + if (*it != '\t' && (Unicode::GetCategory(*it) & Unicode::Category_Separator) == 0) break; } while (*++it); @@ -4255,7 +4255,7 @@ namespace Nz utf8::unchecked::iterator it(&m_sharedString->string[m_sharedString->size]); while ((it--).base() != m_sharedString->string.get()) { - if ((Unicode::GetCategory(*it) & Unicode::Category_Separator) == 0) + if (*it != '\t' && (Unicode::GetCategory(*it) & Unicode::Category_Separator) == 0) break; } @@ -4271,7 +4271,8 @@ namespace Nz { for (; startPos < m_sharedString->size; ++startPos) { - if ((Unicode::GetCategory(m_sharedString->string[startPos]) & Unicode::Category_Separator) == 0) + char c = m_sharedString->string[startPos]; + if (c != '\t' && (Unicode::GetCategory(c) & Unicode::Category_Separator) == 0) break; } } @@ -4281,7 +4282,8 @@ namespace Nz { for (; endPos > 0; --endPos) { - if ((Unicode::GetCategory(m_sharedString->string[endPos]) & Unicode::Category_Separator) == 0) + char c = m_sharedString->string[endPos]; + if (c != '\t' && (Unicode::GetCategory(c) & Unicode::Category_Separator) == 0) break; } } diff --git a/src/Nazara/Utility/Formats/MD5MeshLoader.cpp b/src/Nazara/Utility/Formats/MD5MeshLoader.cpp index 9f7b6151c..cda183313 100644 --- a/src/Nazara/Utility/Formats/MD5MeshLoader.cpp +++ b/src/Nazara/Utility/Formats/MD5MeshLoader.cpp @@ -42,7 +42,7 @@ namespace Nz // Pour que le squelette soit correctement aligné, il faut appliquer un quaternion "de correction" aux joints à la base du squelette Quaternionf rotationQuat = Quaternionf::RotationBetween(Vector3f::UnitX(), Vector3f::Forward()) * - Quaternionf::RotationBetween(Vector3f::UnitZ(), Vector3f::Up()); + Quaternionf::RotationBetween(Vector3f::UnitZ(), Vector3f::Up()); String baseDir = stream.GetDirectory(); diff --git a/src/Nazara/Utility/Formats/MD5MeshParser.cpp b/src/Nazara/Utility/Formats/MD5MeshParser.cpp index d8dfcb304..56e384bf0 100644 --- a/src/Nazara/Utility/Formats/MD5MeshParser.cpp +++ b/src/Nazara/Utility/Formats/MD5MeshParser.cpp @@ -194,6 +194,7 @@ namespace Nz m_currentLine = m_stream.ReadLine(); m_currentLine = m_currentLine.SubStringTo("//"); // On ignore les commentaires m_currentLine.Simplify(); // Pour un traitement plus simple + m_currentLine.Trim(); } while (m_currentLine.IsEmpty()); } From 839ab8cebe5d8588ee26c80e6d0d026e54b60497 Mon Sep 17 00:00:00 2001 From: Lynix Date: Tue, 3 May 2016 22:44:01 +0200 Subject: [PATCH 42/60] Sdk/Binding: Fix querying argument of type IpAddress Former-commit-id: 2980c126f7d216dd4537cef6f745928148eee45e --- SDK/include/NDK/LuaAPI.inl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SDK/include/NDK/LuaAPI.inl b/SDK/include/NDK/LuaAPI.inl index 903e76c05..cbd4e7c4a 100644 --- a/SDK/include/NDK/LuaAPI.inl +++ b/SDK/include/NDK/LuaAPI.inl @@ -170,7 +170,7 @@ namespace Nz return 1; default: - *address = *(*static_cast(instance.CheckUserdata(index, "IpAddress"))); + *address = *static_cast(instance.CheckUserdata(index, "IpAddress")); return 1; } } From 943dae72afdd53b025268e387acd0d90ebf36960 Mon Sep 17 00:00:00 2001 From: Lynix Date: Tue, 3 May 2016 23:04:56 +0200 Subject: [PATCH 43/60] Build: Rename .bat scripts Former-commit-id: 8dde8153d3a3065fd98f3e094f8b6fa641e9fd62 --- build/{Build CodeBlocks (complete).bat => Build_CodeBlocks.bat} | 0 ...cks (complete, united).bat => Build_CodeBlocks_OneLibrary.bat} | 0 build/{Build CodeLite (complete).bat => Build_CodeLite.bat} | 0 ...eLite (complete, united).bat => Build_CodeLite_OneLibrary.bat} | 0 .../{Build Visual Studio 2015 (complete).bat => Build_VS2015.bat} | 0 ...io 2015 (complete, united).bat => Build_VS2015_OneLibrary.bat} | 0 build/{Encode Resources.bat => EncodeResources.bat} | 0 build/{Generate Headers.bat => Generate_GlobalIncludes.bat} | 0 build/{Parse Unicode.bat => Generate_UnicodeData.bat} | 0 9 files changed, 0 insertions(+), 0 deletions(-) rename build/{Build CodeBlocks (complete).bat => Build_CodeBlocks.bat} (100%) rename build/{Build CodeBlocks (complete, united).bat => Build_CodeBlocks_OneLibrary.bat} (100%) rename build/{Build CodeLite (complete).bat => Build_CodeLite.bat} (100%) rename build/{Build CodeLite (complete, united).bat => Build_CodeLite_OneLibrary.bat} (100%) rename build/{Build Visual Studio 2015 (complete).bat => Build_VS2015.bat} (100%) rename build/{Build Visual Studio 2015 (complete, united).bat => Build_VS2015_OneLibrary.bat} (100%) rename build/{Encode Resources.bat => EncodeResources.bat} (100%) rename build/{Generate Headers.bat => Generate_GlobalIncludes.bat} (100%) rename build/{Parse Unicode.bat => Generate_UnicodeData.bat} (100%) diff --git a/build/Build CodeBlocks (complete).bat b/build/Build_CodeBlocks.bat similarity index 100% rename from build/Build CodeBlocks (complete).bat rename to build/Build_CodeBlocks.bat diff --git a/build/Build CodeBlocks (complete, united).bat b/build/Build_CodeBlocks_OneLibrary.bat similarity index 100% rename from build/Build CodeBlocks (complete, united).bat rename to build/Build_CodeBlocks_OneLibrary.bat diff --git a/build/Build CodeLite (complete).bat b/build/Build_CodeLite.bat similarity index 100% rename from build/Build CodeLite (complete).bat rename to build/Build_CodeLite.bat diff --git a/build/Build CodeLite (complete, united).bat b/build/Build_CodeLite_OneLibrary.bat similarity index 100% rename from build/Build CodeLite (complete, united).bat rename to build/Build_CodeLite_OneLibrary.bat diff --git a/build/Build Visual Studio 2015 (complete).bat b/build/Build_VS2015.bat similarity index 100% rename from build/Build Visual Studio 2015 (complete).bat rename to build/Build_VS2015.bat diff --git a/build/Build Visual Studio 2015 (complete, united).bat b/build/Build_VS2015_OneLibrary.bat similarity index 100% rename from build/Build Visual Studio 2015 (complete, united).bat rename to build/Build_VS2015_OneLibrary.bat diff --git a/build/Encode Resources.bat b/build/EncodeResources.bat similarity index 100% rename from build/Encode Resources.bat rename to build/EncodeResources.bat diff --git a/build/Generate Headers.bat b/build/Generate_GlobalIncludes.bat similarity index 100% rename from build/Generate Headers.bat rename to build/Generate_GlobalIncludes.bat diff --git a/build/Parse Unicode.bat b/build/Generate_UnicodeData.bat similarity index 100% rename from build/Parse Unicode.bat rename to build/Generate_UnicodeData.bat From a6c13f85af2992d393f121560d0485fb16937882 Mon Sep 17 00:00:00 2001 From: Lynix Date: Tue, 3 May 2016 23:15:22 +0200 Subject: [PATCH 44/60] Core/Posix: Add absolutly not tested File::SetSize implementation At least the engine should compile again on posix Former-commit-id: 16819ae6d032d5c1983fd4b22af3e43fc98800b0 --- src/Nazara/Core/Posix/FileImpl.cpp | 5 +++++ src/Nazara/Core/Posix/FileImpl.hpp | 1 + 2 files changed, 6 insertions(+) diff --git a/src/Nazara/Core/Posix/FileImpl.cpp b/src/Nazara/Core/Posix/FileImpl.cpp index 31c1ace73..f6e8b3bcc 100644 --- a/src/Nazara/Core/Posix/FileImpl.cpp +++ b/src/Nazara/Core/Posix/FileImpl.cpp @@ -118,6 +118,11 @@ namespace Nz return lseek64(m_fileDescriptor, offset, moveMethod) != -1; } + bool FileImpl::SetSize(UInt64 size) + { + return ftruncate64(m_fileDescriptor, size) != 0; + } + std::size_t FileImpl::Write(const void* buffer, std::size_t size) { lockf64(m_fileDescriptor, F_LOCK, size); diff --git a/src/Nazara/Core/Posix/FileImpl.hpp b/src/Nazara/Core/Posix/FileImpl.hpp index 844bebd29..4981a832e 100644 --- a/src/Nazara/Core/Posix/FileImpl.hpp +++ b/src/Nazara/Core/Posix/FileImpl.hpp @@ -39,6 +39,7 @@ namespace Nz bool Open(const String& filePath, UInt32 mode); std::size_t Read(void* buffer, std::size_t size); bool SetCursorPos(CursorPosition pos, Int64 offset); + bool SetSize(UInt64 size); std::size_t Write(const void* buffer, std::size_t size); FileImpl& operator=(const FileImpl&) = delete; From d678951c331cb6c99476f1a59109dcc819fbaee0 Mon Sep 17 00:00:00 2001 From: Lynix Date: Tue, 3 May 2016 23:18:08 +0200 Subject: [PATCH 45/60] Utility: Fix some warnings Former-commit-id: 743eae3bfca7871bdd4c180c53a1ee09fa9dcc5a --- src/Nazara/Utility/Formats/DDSLoader.cpp | 4 ++-- src/Nazara/Utility/SubMesh.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Nazara/Utility/Formats/DDSLoader.cpp b/src/Nazara/Utility/Formats/DDSLoader.cpp index 15ed11f95..baa2657b3 100644 --- a/src/Nazara/Utility/Formats/DDSLoader.cpp +++ b/src/Nazara/Utility/Formats/DDSLoader.cpp @@ -65,7 +65,7 @@ namespace Nz headerDX10.resourceDimension = D3D10_RESOURCE_DIMENSION_UNKNOWN; } - if (header.flags & DDSD_WIDTH == 0) + if ((header.flags & DDSD_WIDTH) == 0) NazaraWarning("Ill-formed DDS file, doesn't have a width flag"); unsigned int width = std::max(header.width, 1U); @@ -141,7 +141,7 @@ namespace Nz { if (header.ddsCaps[1] & DDSCAPS2_CUBEMAP) { - if (header.ddsCaps[1] & DDSCAPS2_CUBEMAP_ALLFACES != DDSCAPS2_CUBEMAP_ALLFACES) + if ((header.ddsCaps[1] & DDSCAPS2_CUBEMAP_ALLFACES) != DDSCAPS2_CUBEMAP_ALLFACES) { NazaraError("Partial cubemap are not yet supported, sorry"); return false; diff --git a/src/Nazara/Utility/SubMesh.cpp b/src/Nazara/Utility/SubMesh.cpp index ffe5a05f1..8b0589808 100644 --- a/src/Nazara/Utility/SubMesh.cpp +++ b/src/Nazara/Utility/SubMesh.cpp @@ -209,5 +209,5 @@ namespace Nz void SubMesh::SetMaterialIndex(unsigned int matIndex) { m_matIndex = matIndex; -} + } } From 5e52988d8748095de7fa53bbb5f0ea98025fd15c Mon Sep 17 00:00:00 2001 From: Lynix Date: Thu, 5 May 2016 20:40:25 +0200 Subject: [PATCH 46/60] Sdk/Binding: Add component access by name Former-commit-id: 8b5cffb55c526124cddffc9f13a05bbecc638bb9 --- SDK/include/NDK/LuaBinding.hpp | 15 +++--- SDK/include/NDK/LuaBinding.inl | 1 + SDK/src/NDK/LuaBinding_SDK.cpp | 92 ++++++++++++++++++++-------------- 3 files changed, 63 insertions(+), 45 deletions(-) diff --git a/SDK/include/NDK/LuaBinding.hpp b/SDK/include/NDK/LuaBinding.hpp index 265e9e452..0c1dea15e 100644 --- a/SDK/include/NDK/LuaBinding.hpp +++ b/SDK/include/NDK/LuaBinding.hpp @@ -83,12 +83,6 @@ namespace Ndk Nz::LuaClass nodeClass; // SDK - Nz::LuaClass application; - Nz::LuaClass entityClass; - Nz::LuaClass nodeComponent; - Nz::LuaClass velocityComponent; - Nz::LuaClass worldClass; - using AddComponentFunc = int(*)(Nz::LuaInstance&, EntityHandle&); using GetComponentFunc = int(*)(Nz::LuaInstance&, BaseComponent&); @@ -100,7 +94,16 @@ namespace Ndk Nz::String name; }; + ComponentBinding* QueryComponentIndex(Nz::LuaInstance& lua, int argIndex = 1); + + Nz::LuaClass application; + Nz::LuaClass entityClass; + Nz::LuaClass nodeComponent; + Nz::LuaClass velocityComponent; + Nz::LuaClass worldClass; + std::vector m_componentBinding; + std::unordered_map m_componentBindingByName; #ifndef NDK_SERVER // Audio diff --git a/SDK/include/NDK/LuaBinding.inl b/SDK/include/NDK/LuaBinding.inl index 5ca290398..64e3eb453 100644 --- a/SDK/include/NDK/LuaBinding.inl +++ b/SDK/include/NDK/LuaBinding.inl @@ -21,6 +21,7 @@ namespace Ndk m_componentBinding.resize(T::componentIndex + 1); m_componentBinding[T::componentIndex] = std::move(binding); + m_componentBindingByName[name] = T::componentIndex; } template diff --git a/SDK/src/NDK/LuaBinding_SDK.cpp b/SDK/src/NDK/LuaBinding_SDK.cpp index 289e316a3..b371e76e3 100644 --- a/SDK/src/NDK/LuaBinding_SDK.cpp +++ b/SDK/src/NDK/LuaBinding_SDK.cpp @@ -59,56 +59,29 @@ namespace Ndk entityClass.BindMethod("Kill", &Entity::Kill); entityClass.BindMethod("IsEnabled", &Entity::IsEnabled); entityClass.BindMethod("IsValid", &Entity::IsValid); - entityClass.BindMethod("RemoveComponent", (void(Entity::*)(ComponentIndex)) &Entity::RemoveComponent); entityClass.BindMethod("RemoveAllComponents", &Entity::RemoveAllComponents); entityClass.BindMethod("__tostring", &EntityHandle::ToString); - entityClass.BindMethod("AddComponent", [this] (Nz::LuaInstance& lua, EntityHandle& handle) -> int + entityClass.BindMethod("AddComponent", [this] (Nz::LuaInstance& instance, EntityHandle& handle) -> int { - int index = 1; - ComponentIndex componentIndex = lua.Check(&index); + ComponentBinding* binding = QueryComponentIndex(instance); - if (componentIndex > m_componentBinding.size()) - { - lua.Error("Invalid component index"); - return 0; - } - - ComponentBinding& binding = m_componentBinding[componentIndex]; - if (binding.name.IsEmpty()) - { - lua.Error("This component is not available to the LuaAPI"); - return 0; - } - - return binding.adder(lua, handle); + return binding->adder(instance, handle); }); - entityClass.BindMethod("GetComponent", [this] (Nz::LuaInstance& lua, EntityHandle& handle) -> int + entityClass.BindMethod("GetComponent", [this] (Nz::LuaInstance& instance, EntityHandle& handle) -> int { - int index = 1; - ComponentIndex componentIndex = lua.Check(&index); + ComponentBinding* binding = QueryComponentIndex(instance); - if (!handle->HasComponent(componentIndex)) - { - lua.PushNil(); - return 1; - } + return binding->getter(instance, handle->GetComponent(binding->index)); + }); - if (componentIndex > m_componentBinding.size()) - { - lua.Error("Invalid component index"); - return 0; - } + entityClass.BindMethod("RemoveComponent", [this] (Nz::LuaInstance& instance, EntityHandle& handle) -> int + { + ComponentBinding* binding = QueryComponentIndex(instance); - ComponentBinding& binding = m_componentBinding[componentIndex]; - if (binding.name.IsEmpty()) - { - lua.Error("This component is not available to the LuaAPI"); - return 0; - } - - return binding.getter(lua, handle->GetComponent(componentIndex)); + handle->RemoveComponent(binding->index); + return 0; }); /*********************************** Ndk::NodeComponent **********************************/ @@ -199,4 +172,45 @@ namespace Ndk } instance.SetGlobal("ComponentType"); } + + LuaBinding::ComponentBinding* LuaBinding::QueryComponentIndex(Nz::LuaInstance& instance, int argIndex) + { + switch (instance.GetType(argIndex)) + { + case Nz::LuaType_Number: + { + ComponentIndex componentIndex = instance.Check(&argIndex); + if (componentIndex > m_componentBinding.size()) + { + instance.Error("Invalid component index"); + return nullptr; + } + + ComponentBinding& binding = m_componentBinding[componentIndex]; + if (binding.name.IsEmpty()) + { + instance.Error("Invalid component index"); + return nullptr; + } + + return &binding; + } + + case Nz::LuaType_String: + { + const char* key = instance.CheckString(argIndex); + auto it = m_componentBindingByName.find(key); + if (it == m_componentBindingByName.end()) + { + instance.Error("Invalid component name"); + return nullptr; + } + + return &m_componentBinding[it->second]; + } + } + + instance.Error("Invalid component index at #" + Nz::String::Number(argIndex)); + return nullptr; + } } From 385c5974341a30bd9dae5728fff6bd468a14d57f Mon Sep 17 00:00:00 2001 From: Lynix Date: Thu, 5 May 2016 21:27:36 +0200 Subject: [PATCH 47/60] UnitTests: Fix errors Former-commit-id: fb2340e5c7c264193f1ac363d6387486215aef7e --- include/Nazara/Core.hpp | 2 +- include/Nazara/Core/Algorithm.hpp | 2 +- include/Nazara/Core/Algorithm.inl | 13 ++----- include/Nazara/Core/ByteStream.hpp | 2 +- ...alization.hpp => SerializationContext.hpp} | 8 ++++- include/Nazara/Core/SerializationContext.inl | 24 +++++++++++++ include/Nazara/Core/String.hpp | 2 +- src/Nazara/Core/File.cpp | 32 ++++++++--------- src/Nazara/Core/SerializationContext.cpp | 35 +++++++++++++++++++ src/Nazara/Utility/Formats/DDSConstants.hpp | 2 +- tests/Engine/Core/Bitset.cpp | 2 +- tests/Engine/Core/File.cpp | 6 ++-- tests/Engine/Core/Serialization.cpp | 3 +- 13 files changed, 96 insertions(+), 37 deletions(-) rename include/Nazara/Core/{Serialization.hpp => SerializationContext.hpp} (79%) create mode 100644 include/Nazara/Core/SerializationContext.inl create mode 100644 src/Nazara/Core/SerializationContext.cpp diff --git a/include/Nazara/Core.hpp b/include/Nazara/Core.hpp index a9a93d45c..f2be4f231 100644 --- a/include/Nazara/Core.hpp +++ b/include/Nazara/Core.hpp @@ -73,7 +73,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/include/Nazara/Core/Algorithm.hpp b/include/Nazara/Core/Algorithm.hpp index 5f8b8aa7f..f031854c5 100644 --- a/include/Nazara/Core/Algorithm.hpp +++ b/include/Nazara/Core/Algorithm.hpp @@ -9,7 +9,7 @@ #include #include -#include +#include #include #include #include diff --git a/include/Nazara/Core/Algorithm.inl b/include/Nazara/Core/Algorithm.inl index c45147d79..821a9069f 100644 --- a/include/Nazara/Core/Algorithm.inl +++ b/include/Nazara/Core/Algorithm.inl @@ -209,14 +209,8 @@ namespace Nz template std::enable_if_t::value, bool> Serialize(SerializationContext& context, T value) { - // Flush bits if a writing is in progress - if (context.currentBitPos != 8) - { - context.currentBitPos = 8; - - if (!Serialize(context, context.currentByte)) - NazaraWarning("Failed to flush bits"); - } + // Flush bits in case a writing is in progress + context.FlushBits(); if (context.endianness != Endianness_Unknown && context.endianness != GetPlatformEndianness()) SwapBytes(&value, sizeof(T)); @@ -269,8 +263,7 @@ namespace Nz { NazaraAssert(value, "Invalid data pointer"); - // Reset bit position - context.currentBitPos = 8; + context.ResetBitPosition(); if (context.stream->Read(value, sizeof(T)) == sizeof(T)) { diff --git a/include/Nazara/Core/ByteStream.hpp b/include/Nazara/Core/ByteStream.hpp index e26382cf4..fe1516b06 100644 --- a/include/Nazara/Core/ByteStream.hpp +++ b/include/Nazara/Core/ByteStream.hpp @@ -9,7 +9,7 @@ #include #include -#include +#include #include #include diff --git a/include/Nazara/Core/Serialization.hpp b/include/Nazara/Core/SerializationContext.hpp similarity index 79% rename from include/Nazara/Core/Serialization.hpp rename to include/Nazara/Core/SerializationContext.hpp index 47339b0a2..64c558a7b 100644 --- a/include/Nazara/Core/Serialization.hpp +++ b/include/Nazara/Core/SerializationContext.hpp @@ -8,6 +8,7 @@ #define NAZARA_SERIALIZATION_HPP #include +#include #include #include #include @@ -17,13 +18,18 @@ namespace Nz { class Stream; - struct SerializationContext + struct NAZARA_CORE_API SerializationContext { Stream* stream; Endianness endianness = Endianness_BigEndian; //< Default to Big Endian encoding UInt8 currentBitPos = 8; //< 8 means no bit is currently wrote UInt8 currentByte; //< Undefined value, will be initialized at the first bit write + + void FlushBits(); + inline void ResetBitPosition(); }; } +#include + #endif // NAZARA_SERIALIZATION_HPP diff --git a/include/Nazara/Core/SerializationContext.inl b/include/Nazara/Core/SerializationContext.inl new file mode 100644 index 000000000..47f56e5c2 --- /dev/null +++ b/include/Nazara/Core/SerializationContext.inl @@ -0,0 +1,24 @@ +// Copyright (C) 2015 Jérôme Leclercq +// This file is part of the "Nazara Engine - Core module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include +#include + +namespace Nz +{ + /*! + * \brief Reset the current bit cursor + + * \remark This function only reset the cursor position, it doesn't do any writing + if you wish to write all bits and reset bit position, call FlushBits + + \see FlushBits + */ + inline void SerializationContext::ResetBitPosition() + { + currentBitPos = 8; + } +} + +#include diff --git a/include/Nazara/Core/String.hpp b/include/Nazara/Core/String.hpp index 70673ae8a..765ef8b85 100644 --- a/include/Nazara/Core/String.hpp +++ b/include/Nazara/Core/String.hpp @@ -9,7 +9,7 @@ #include #include -#include +#include #include #include #include diff --git a/src/Nazara/Core/File.cpp b/src/Nazara/Core/File.cpp index 8505e42f9..97504b0ee 100644 --- a/src/Nazara/Core/File.cpp +++ b/src/Nazara/Core/File.cpp @@ -454,24 +454,24 @@ namespace Nz return true; } - /*! - * \brief Sets the size of the file - * \return true if the file size has correctly changed - * - * \param size The size the file should have after this call - * - * \remark The cursor position is not affected by this call - * \remark The file must be open in write mode - */ - bool File::SetSize(UInt64 size) - { - NazaraLock(m_mutex) + /*! + * \brief Sets the size of the file + * \return true if the file size has correctly changed + * + * \param size The size the file should have after this call + * + * \remark The cursor position is not affected by this call + * \remark The file must be open in write mode + */ + bool File::SetSize(UInt64 size) + { + NazaraLock(m_mutex) - NazaraAssert(IsOpen(), "File is not open"); - NazaraAssert(IsWritable(), "File is not writable"); + NazaraAssert(IsOpen(), "File is not open"); + NazaraAssert(IsWritable(), "File is not writable"); - return m_impl->SetSize(size); - } + return m_impl->SetSize(size); + } /*! * \brief Sets the file path diff --git a/src/Nazara/Core/SerializationContext.cpp b/src/Nazara/Core/SerializationContext.cpp new file mode 100644 index 000000000..734b3b23d --- /dev/null +++ b/src/Nazara/Core/SerializationContext.cpp @@ -0,0 +1,35 @@ +// Copyright (C) 2015 Jérôme Leclercq +// This file is part of the "Nazara Engine - Core module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include +#include +#include +#include + +namespace Nz +{ + + /*! + * \ingroup core + * \class Nz::SerializationContext + * \brief Structure containing a serialization/unserialization context states + */ + + /*! + * Write bits to the stream (if any) and reset the current bit cursor + + * \see ResetBitPosition + */ + void SerializationContext::FlushBits() + { + if (currentBitPos != 8) + { + ResetBitPosition(); + + // Serialize will reset the bit position + if (!Serialize(*this, currentByte)) + NazaraWarning("Failed to flush bits"); + } + } +} diff --git a/src/Nazara/Utility/Formats/DDSConstants.hpp b/src/Nazara/Utility/Formats/DDSConstants.hpp index 47a1766a4..4839df800 100644 --- a/src/Nazara/Utility/Formats/DDSConstants.hpp +++ b/src/Nazara/Utility/Formats/DDSConstants.hpp @@ -8,7 +8,7 @@ #define NAZARA_LOADERS_DDS_CONSTANTS_HPP #include -#include +#include #include namespace Nz diff --git a/tests/Engine/Core/Bitset.cpp b/tests/Engine/Core/Bitset.cpp index 76c35c886..cb870f7a4 100644 --- a/tests/Engine/Core/Bitset.cpp +++ b/tests/Engine/Core/Bitset.cpp @@ -7,7 +7,7 @@ SCENARIO("Bitset", "[CORE][BITSET]") { GIVEN("Allocate and constructor") { - Nz::Bitset<> bitset(3); + Nz::Bitset<> bitset(3, false); THEN("Capacity is 3 and size is 3") { diff --git a/tests/Engine/Core/File.cpp b/tests/Engine/Core/File.cpp index 2a87c8495..2ddbfebbf 100644 --- a/tests/Engine/Core/File.cpp +++ b/tests/Engine/Core/File.cpp @@ -78,9 +78,9 @@ SCENARIO("File", "[CORE][FILE]") THEN("The relative positioning should disappear") { - Nz::String containingNoMoreDot = "/resources/Spaceship/spaceship.mtl"; - REQUIRE(Nz::File::AbsolutePath(containingDot) == containingNoMoreDot); - REQUIRE(Nz::File::AbsolutePath(containingDoubleDot) == containingNoMoreDot); + Nz::String containingNoMoreDot = Nz::File::NormalizePath("/resources/Spaceship/spaceship.mtl"); + REQUIRE(Nz::File::AbsolutePath(containingDot).EndsWith(containingNoMoreDot)); + REQUIRE(Nz::File::AbsolutePath(containingDoubleDot).EndsWith(containingNoMoreDot)); } } } diff --git a/tests/Engine/Core/Serialization.cpp b/tests/Engine/Core/Serialization.cpp index a4d8ff75e..cc556dec8 100644 --- a/tests/Engine/Core/Serialization.cpp +++ b/tests/Engine/Core/Serialization.cpp @@ -1,4 +1,4 @@ -#include +#include #include #include @@ -35,6 +35,7 @@ SCENARIO("Serialization", "[CORE][SERIALIZATION]") { context.stream->SetCursorPos(0); REQUIRE(Serialize(context, true)); + context.FlushBits(); //< Don't forget to flush bits (it is NOT done by the stream) context.stream->SetCursorPos(0); bool value = false; REQUIRE(Unserialize(context, &value)); From ed3b9f9a21b718ab39c08ad581e26b36a14f21a3 Mon Sep 17 00:00:00 2001 From: Lynix Date: Thu, 5 May 2016 21:50:44 +0200 Subject: [PATCH 48/60] Examples: Fix MeshInfos since material update Former-commit-id: 1d019a7c6659f2ca0f173711c03e3eb89ed1659b --- examples/MeshInfos/main.cpp | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/examples/MeshInfos/main.cpp b/examples/MeshInfos/main.cpp index ba55d2686..73864abaa 100644 --- a/examples/MeshInfos/main.cpp +++ b/examples/MeshInfos/main.cpp @@ -2,6 +2,7 @@ #include #include #include +#include #include #include #include @@ -22,7 +23,7 @@ int main() for (;;) { - Nz::Directory resourceDirectory("resources/"); + Nz::Directory resourceDirectory("resources"); if (!resourceDirectory.Open()) { std::cerr << "Failed to open resource directory" << std::endl; @@ -68,7 +69,7 @@ int main() break; Nz::Mesh mesh; - if (!mesh.LoadFromFile("resources/" + models[iChoice-1])) + if (!mesh.LoadFromFile(resourceDirectory.GetPath() + '/' + models[iChoice-1])) { std::cout << "Failed to load mesh" << std::endl; std::getchar(); @@ -168,8 +169,18 @@ int main() { for (unsigned int i = 0; i < materialCount; ++i) { - std::cout << "\t" << (i+1) << ": " << mesh.GetMaterial(i) << std::endl; - std::cin.ignore(std::numeric_limits::max(), '\n'); + const Nz::ParameterList& matData = mesh.GetMaterialData(i); + + Nz::String data; + if (!matData.GetStringParameter(Nz::MaterialData::FilePath, &data)) + { + if (matData.HasParameter(Nz::MaterialData::CustomDefined)) + data = ""; + else + data = ""; + } + + std::cout << "\t" << (i+1) << ": " << data << std::endl; } } From 1e3225d1b4ee245876b958da0b92c329a6f7a48a Mon Sep 17 00:00:00 2001 From: Lynix Date: Thu, 5 May 2016 23:36:34 +0200 Subject: [PATCH 49/60] Build: Add an option to copy the built library to the example directory Former-commit-id: 78618a92f864e75c1c46f478a1cfc57726188b89 --- .gitignore | 2 ++ build/scripts/common.lua | 8 ++++++++ 2 files changed, 10 insertions(+) diff --git a/.gitignore b/.gitignore index d671b209b..258594792 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,8 @@ # Nazara build examples/bin/*.exe examples/bin/*.pdb +examples/bin/*.dll +examples/bin/*.so tests/*.exe tests/*.pdb lib/* diff --git a/build/scripts/common.lua b/build/scripts/common.lua index 266b50f85..405b66b60 100644 --- a/build/scripts/common.lua +++ b/build/scripts/common.lua @@ -298,6 +298,14 @@ function NazaraBuild:Execute() targetdir("../plugins/" .. toolTable.Name .. "/lib/" .. makeLibDir .. "/x64") end + -- Copy the module binaries to the example folder + if (toolTable.CopyTargetToExampleDir) then + if (os.is("windows")) then + configuration({}) + postbuildcommands({[[xcopy "%{path.translate(cfg.linktarget.relpath):sub(1, -5) .. ".dll"}" "..\..\..\examples\bin\" /E /Y]]}) + end + end + configuration({"vs*", "x32"}) libdirs("../extlibs/lib/msvc/x86") libdirs("../lib/msvc/x86") From 5d2fa3ce98ab033220a55e2317a32789cca91f0c Mon Sep 17 00:00:00 2001 From: Lynix Date: Thu, 5 May 2016 23:36:53 +0200 Subject: [PATCH 50/60] Build/Tool: Make Assimp plugin copy its library file to the example directory Former-commit-id: c24dd8b79f56353a4b5b43b7e8de1ff0c672eb05 --- build/scripts/tools/assimp.lua | 2 ++ 1 file changed, 2 insertions(+) diff --git a/build/scripts/tools/assimp.lua b/build/scripts/tools/assimp.lua index 0eecbcd54..3a1ca093b 100644 --- a/build/scripts/tools/assimp.lua +++ b/build/scripts/tools/assimp.lua @@ -3,6 +3,8 @@ TOOL.Name = "Assimp" TOOL.Directory = "../SDK/lib" TOOL.Kind = "Plugin" +TOOL.CopyTargetToExampleDir = true + TOOL.Includes = { "../include", "../plugins/Assimp" From 11c435aa7ddec333b373af2ee46bb3bc33323dcc Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 6 May 2016 19:15:15 +0200 Subject: [PATCH 51/60] Core/Bitset: Fix value constructor Former-commit-id: 9ed58dc40a513d32fac946d8876ac702713e279a --- include/Nazara/Core/Bitset.hpp | 2 +- include/Nazara/Core/Bitset.inl | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/include/Nazara/Core/Bitset.hpp b/include/Nazara/Core/Bitset.hpp index a371212ab..3b440278c 100644 --- a/include/Nazara/Core/Bitset.hpp +++ b/include/Nazara/Core/Bitset.hpp @@ -31,7 +31,7 @@ namespace Nz Bitset(const char* bits, unsigned int bitCount); Bitset(const Bitset& bitset) = default; explicit Bitset(const String& bits); - template explicit Bitset(T value); + template Bitset(T value); Bitset(Bitset&& bitset) noexcept = default; ~Bitset() noexcept = default; diff --git a/include/Nazara/Core/Bitset.inl b/include/Nazara/Core/Bitset.inl index d689ff18a..efea1d2db 100644 --- a/include/Nazara/Core/Bitset.inl +++ b/include/Nazara/Core/Bitset.inl @@ -120,14 +120,14 @@ namespace Nz { if (sizeof(T) <= sizeof(Block)) { - m_bitCount = CountBits(value); + m_bitCount = std::numeric_limits::digits; m_blocks.push_back(value); } else { // Note: I was kinda tired when I wrote this, there's probably a much easier method than checking bits to write bits unsigned int bitPos = 0; - for (T bit = 1; bit < std::numeric_limits::digits; bit <<= 1) + for (T bit = 1; bit < std::numeric_limits::max(); bit <<= 1) { if (value & bit) UnboundedSet(bitPos, true); @@ -838,7 +838,7 @@ namespace Nz Block block = m_blocks[i]; - // Compute the position of LSB in the block (and adjustement of the position) + // Compute the position of LSB in the block (and adjustment of the position) return IntegralLog2Pot(block & -block) + i*bitsPerBlock; } From e9608366cdc87b110b1f13af5579b2f974df5b2b Mon Sep 17 00:00:00 2001 From: Lynix Date: Mon, 9 May 2016 09:03:11 +0200 Subject: [PATCH 52/60] Core/ObjectHandle: Add noexcept move constructor/assignment Former-commit-id: d726fab8750fe02fbed0e605bbf9a757c7f035de --- SDK/include/NDK/EntityOwner.hpp | 4 ++-- SDK/include/NDK/EntityOwner.inl | 12 ----------- include/Nazara/Core/HandledObject.hpp | 3 ++- include/Nazara/Core/HandledObject.inl | 16 +++++++++++--- include/Nazara/Core/ObjectHandle.hpp | 3 +++ include/Nazara/Core/ObjectHandle.inl | 30 ++++++++++++++++++++++++++- 6 files changed, 49 insertions(+), 19 deletions(-) diff --git a/SDK/include/NDK/EntityOwner.hpp b/SDK/include/NDK/EntityOwner.hpp index c7cab901f..d0a4a4f59 100644 --- a/SDK/include/NDK/EntityOwner.hpp +++ b/SDK/include/NDK/EntityOwner.hpp @@ -17,7 +17,7 @@ namespace Ndk EntityOwner() = default; explicit EntityOwner(Entity* entity); EntityOwner(const EntityOwner& handle) = delete; - EntityOwner(EntityOwner&& handle); + EntityOwner(EntityOwner&& handle) noexcept = default; ~EntityOwner(); void Reset(Entity* entity = nullptr); @@ -25,7 +25,7 @@ namespace Ndk EntityOwner& operator=(Entity* entity); EntityOwner& operator=(const EntityOwner& handle) = delete; - EntityOwner& operator=(EntityOwner&& handle); + EntityOwner& operator=(EntityOwner&& handle) noexcept = default; }; } diff --git a/SDK/include/NDK/EntityOwner.inl b/SDK/include/NDK/EntityOwner.inl index 607f3229d..6efc2b30e 100644 --- a/SDK/include/NDK/EntityOwner.inl +++ b/SDK/include/NDK/EntityOwner.inl @@ -14,11 +14,6 @@ namespace Ndk Reset(entity); } - inline EntityOwner::EntityOwner(EntityOwner&& handle) : - EntityHandle(std::move(handle)) - { - } - inline EntityOwner::~EntityOwner() { Reset(nullptr); @@ -44,13 +39,6 @@ namespace Ndk return *this; } - - inline EntityOwner& EntityOwner::operator=(EntityOwner&& handle) - { - Reset(std::move(handle)); - - return *this; - } } namespace std diff --git a/include/Nazara/Core/HandledObject.hpp b/include/Nazara/Core/HandledObject.hpp index f1e096748..eeb9c4bfa 100644 --- a/include/Nazara/Core/HandledObject.hpp +++ b/include/Nazara/Core/HandledObject.hpp @@ -36,7 +36,8 @@ namespace Nz private: void RegisterHandle(ObjectHandle* handle); - void UnregisterHandle(ObjectHandle* handle); + void UnregisterHandle(ObjectHandle* handle) noexcept; + void UpdateHandle(ObjectHandle* oldHandle, ObjectHandle* newHandle) noexcept; std::vector*> m_handles; }; diff --git a/include/Nazara/Core/HandledObject.inl b/include/Nazara/Core/HandledObject.inl index 53a5065f4..738a5f7a5 100644 --- a/include/Nazara/Core/HandledObject.inl +++ b/include/Nazara/Core/HandledObject.inl @@ -71,14 +71,24 @@ namespace Nz } template - void HandledObject::UnregisterHandle(ObjectHandle* handle) + void HandledObject::UnregisterHandle(ObjectHandle* handle) noexcept { ///DOC: Un handle ne doit être libéré qu'une fois, et doit faire partie de la liste, sous peine de crash auto it = std::find(m_handles.begin(), m_handles.end(), handle); - NazaraAssert(it != m_handles.end(), "Handle not registred"); + NazaraAssert(it != m_handles.end(), "Handle not registered"); - // On échange cet élément avec le dernier, et on diminue la taille du vector de 1 + // Swap and pop idiom, more efficient than vector::erase std::swap(*it, m_handles.back()); m_handles.pop_back(); } + + template + void HandledObject::UpdateHandle(ObjectHandle* oldHandle, ObjectHandle* newHandle) noexcept + { + auto it = std::find(m_handles.begin(), m_handles.end(), oldHandle); + NazaraAssert(it != m_handles.end(), "Handle not registered"); + + // Simply update the handle + *it = newHandle; + } } diff --git a/include/Nazara/Core/ObjectHandle.hpp b/include/Nazara/Core/ObjectHandle.hpp index d7a53e281..b3cc080dd 100644 --- a/include/Nazara/Core/ObjectHandle.hpp +++ b/include/Nazara/Core/ObjectHandle.hpp @@ -23,6 +23,7 @@ namespace Nz ObjectHandle(); explicit ObjectHandle(T* object); ObjectHandle(const ObjectHandle& handle); + ObjectHandle(ObjectHandle&& handle) noexcept; ~ObjectHandle(); T* GetObject() const; @@ -31,6 +32,7 @@ namespace Nz void Reset(T* object = nullptr); void Reset(const ObjectHandle& handle); + void Reset(ObjectHandle&& handle) noexcept; ObjectHandle& Swap(ObjectHandle& handle); @@ -42,6 +44,7 @@ namespace Nz ObjectHandle& operator=(T* object); ObjectHandle& operator=(const ObjectHandle& handle); + ObjectHandle& operator=(ObjectHandle&& handle) noexcept; static const ObjectHandle InvalidHandle; diff --git a/include/Nazara/Core/ObjectHandle.inl b/include/Nazara/Core/ObjectHandle.inl index 752cb96c0..ef89828e3 100644 --- a/include/Nazara/Core/ObjectHandle.inl +++ b/include/Nazara/Core/ObjectHandle.inl @@ -24,11 +24,18 @@ namespace Nz template ObjectHandle::ObjectHandle(const ObjectHandle& handle) : - ObjectHandle() + ObjectHandle() { Reset(handle); } + template + ObjectHandle::ObjectHandle(ObjectHandle&& handle) noexcept : + ObjectHandle() + { + Reset(std::move(handle)); + } + template ObjectHandle::~ObjectHandle() { @@ -66,6 +73,19 @@ namespace Nz Reset(handle.GetObject()); } + template + void ObjectHandle::Reset(ObjectHandle&& handle) noexcept + { + if (m_object) + m_object->UnregisterHandle(this); + + if (T* object = handle.GetObject()) + { + object->UpdateHandle(&handle, this); + handle.m_object = nullptr; + } + } + template ObjectHandle& ObjectHandle::Swap(ObjectHandle& handle) { @@ -138,6 +158,14 @@ namespace Nz return *this; } + template + ObjectHandle& ObjectHandle::operator=(ObjectHandle&& handle) noexcept + { + Reset(std::move(handle)); + + return *this; + } + template void ObjectHandle::OnObjectDestroyed() { From 8740cf393c6e761fea8879e0db8a886f6b5ff6f3 Mon Sep 17 00:00:00 2001 From: Lynix Date: Mon, 9 May 2016 18:10:46 +0200 Subject: [PATCH 53/60] Core/Bitset: Fix infinite loop Former-commit-id: f1246eedcd7a0b327e7e4a70803eb5cd20b071ef --- include/Nazara/Core/Bitset.inl | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/include/Nazara/Core/Bitset.inl b/include/Nazara/Core/Bitset.inl index efea1d2db..568d4a815 100644 --- a/include/Nazara/Core/Bitset.inl +++ b/include/Nazara/Core/Bitset.inl @@ -126,13 +126,10 @@ namespace Nz else { // Note: I was kinda tired when I wrote this, there's probably a much easier method than checking bits to write bits - unsigned int bitPos = 0; - for (T bit = 1; bit < std::numeric_limits::max(); bit <<= 1) + for (unsigned int bitPos = 0; bitPos < std::numeric_limits::digits; bitPos++) { - if (value & bit) + if (value & (T(1U) << bitPos)) UnboundedSet(bitPos, true); - - bitPos++; } } } From 8328aae0281d6c38177f36be2f758ce0e2ac694d Mon Sep 17 00:00:00 2001 From: Lynix Date: Mon, 9 May 2016 18:10:58 +0200 Subject: [PATCH 54/60] Core/ObjectHandle: Fix movement Former-commit-id: 8b8c9789447f20572400b05349c75e18960b3e3f --- include/Nazara/Core/ObjectHandle.inl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/Nazara/Core/ObjectHandle.inl b/include/Nazara/Core/ObjectHandle.inl index ef89828e3..cfcd6bc0d 100644 --- a/include/Nazara/Core/ObjectHandle.inl +++ b/include/Nazara/Core/ObjectHandle.inl @@ -81,8 +81,9 @@ namespace Nz if (T* object = handle.GetObject()) { - object->UpdateHandle(&handle, this); + m_object = handle.m_object; handle.m_object = nullptr; + object->UpdateHandle(&handle, this); } } From 0c4172f81b53239df930def8cf7186465c265afb Mon Sep 17 00:00:00 2001 From: Lynix Date: Mon, 9 May 2016 18:11:11 +0200 Subject: [PATCH 55/60] Core: Update global include Former-commit-id: 6175fae50487b14ddad34bf4de94d0948f994708 --- include/Nazara/Core.hpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/include/Nazara/Core.hpp b/include/Nazara/Core.hpp index f2be4f231..5f3c85c4c 100644 --- a/include/Nazara/Core.hpp +++ b/include/Nazara/Core.hpp @@ -1,4 +1,4 @@ -// This file was automatically generated on 03 Feb 2016 at 00:06:56 +// This file was automatically generated on 09 May 2016 at 17:07:09 /* Nazara Engine - Core module @@ -51,6 +51,7 @@ #include #include #include +#include #include #include #include @@ -61,6 +62,7 @@ #include #include #include +#include #include #include #include @@ -72,6 +74,8 @@ #include #include #include +#include +#include #include #include #include From b1288c52774e9bf7de0a6e0675bcbf80f37fb9a6 Mon Sep 17 00:00:00 2001 From: Lynix Date: Mon, 9 May 2016 19:38:30 +0200 Subject: [PATCH 56/60] Sdk/LuaBinding: Make LuaClass members public Former-commit-id: 89e8182c833073e12d18ec5a0f0ae0d0f689c4f1 --- SDK/include/NDK/LuaBinding.hpp | 79 +++++++++++++++++----------------- 1 file changed, 40 insertions(+), 39 deletions(-) diff --git a/SDK/include/NDK/LuaBinding.hpp b/SDK/include/NDK/LuaBinding.hpp index 0c1dea15e..cb4fc24e5 100644 --- a/SDK/include/NDK/LuaBinding.hpp +++ b/SDK/include/NDK/LuaBinding.hpp @@ -37,29 +37,6 @@ namespace Ndk void RegisterClasses(Nz::LuaInstance& instance); - private: - void BindCore(); - void BindMath(); - void BindNetwork(); - void BindSDK(); - void BindUtility(); - - void RegisterCore(Nz::LuaInstance& instance); - void RegisterMath(Nz::LuaInstance& instance); - void RegisterNetwork(Nz::LuaInstance& instance); - void RegisterSDK(Nz::LuaInstance& instance); - void RegisterUtility(Nz::LuaInstance& instance); - - #ifndef NDK_SERVER - void BindAudio(); - void BindGraphics(); - void BindRenderer(); - - void RegisterAudio(Nz::LuaInstance& instance); - void RegisterGraphics(Nz::LuaInstance& instance); - void RegisterRenderer(Nz::LuaInstance& instance); - #endif - // Core Nz::LuaClass clockClass; Nz::LuaClass directoryClass; @@ -83,28 +60,12 @@ namespace Ndk Nz::LuaClass nodeClass; // SDK - using AddComponentFunc = int(*)(Nz::LuaInstance&, EntityHandle&); - using GetComponentFunc = int(*)(Nz::LuaInstance&, BaseComponent&); - - struct ComponentBinding - { - AddComponentFunc adder; - ComponentIndex index; - GetComponentFunc getter; - Nz::String name; - }; - - ComponentBinding* QueryComponentIndex(Nz::LuaInstance& lua, int argIndex = 1); - Nz::LuaClass application; Nz::LuaClass entityClass; Nz::LuaClass nodeComponent; Nz::LuaClass velocityComponent; Nz::LuaClass worldClass; - std::vector m_componentBinding; - std::unordered_map m_componentBindingByName; - #ifndef NDK_SERVER // Audio Nz::LuaClass musicClass; @@ -120,6 +81,46 @@ namespace Ndk Nz::LuaClass consoleClass; Nz::LuaClass graphicsComponent; #endif + + private: + void BindCore(); + void BindMath(); + void BindNetwork(); + void BindSDK(); + void BindUtility(); + + void RegisterCore(Nz::LuaInstance& instance); + void RegisterMath(Nz::LuaInstance& instance); + void RegisterNetwork(Nz::LuaInstance& instance); + void RegisterSDK(Nz::LuaInstance& instance); + void RegisterUtility(Nz::LuaInstance& instance); + + #ifndef NDK_SERVER + void BindAudio(); + void BindGraphics(); + void BindRenderer(); + + void RegisterAudio(Nz::LuaInstance& instance); + void RegisterGraphics(Nz::LuaInstance& instance); + void RegisterRenderer(Nz::LuaInstance& instance); + #endif + + + using AddComponentFunc = int(*)(Nz::LuaInstance&, EntityHandle&); + using GetComponentFunc = int(*)(Nz::LuaInstance&, BaseComponent&); + + struct ComponentBinding + { + AddComponentFunc adder; + ComponentIndex index; + GetComponentFunc getter; + Nz::String name; + }; + + ComponentBinding* QueryComponentIndex(Nz::LuaInstance& lua, int argIndex = 1); + + std::vector m_componentBinding; + std::unordered_map m_componentBindingByName; }; template From 2b04a4722fe4dc81bdc9b51c1818ab8c870b3bab Mon Sep 17 00:00:00 2001 From: Lynix Date: Wed, 11 May 2016 12:27:18 +0200 Subject: [PATCH 57/60] Utility/*TextDrawer: Fix bounds starting at a negative position Former-commit-id: 06ac76189b5c36e108b5fc80b3c54d01068deadd --- include/Nazara/Graphics/TextSprite.hpp | 2 +- include/Nazara/Utility/AbstractTextDrawer.hpp | 2 +- include/Nazara/Utility/SimpleTextDrawer.hpp | 4 ++-- src/Nazara/Utility/SimpleTextDrawer.cpp | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/include/Nazara/Graphics/TextSprite.hpp b/include/Nazara/Graphics/TextSprite.hpp index db99077e2..8e0afa93e 100644 --- a/include/Nazara/Graphics/TextSprite.hpp +++ b/include/Nazara/Graphics/TextSprite.hpp @@ -77,7 +77,7 @@ namespace Nz mutable std::vector m_localVertices; Color m_color; MaterialRef m_material; - Rectui m_localBounds; + Recti m_localBounds; mutable bool m_verticesUpdated; float m_scale; diff --git a/include/Nazara/Utility/AbstractTextDrawer.hpp b/include/Nazara/Utility/AbstractTextDrawer.hpp index 20aac4db3..ffd704f6a 100644 --- a/include/Nazara/Utility/AbstractTextDrawer.hpp +++ b/include/Nazara/Utility/AbstractTextDrawer.hpp @@ -26,7 +26,7 @@ namespace Nz AbstractTextDrawer() = default; virtual ~AbstractTextDrawer(); - virtual const Rectui& GetBounds() const = 0; + virtual const Recti& GetBounds() const = 0; virtual Font* GetFont(unsigned int index) const = 0; virtual unsigned int GetFontCount() const = 0; virtual const Glyph& GetGlyph(unsigned int index) const = 0; diff --git a/include/Nazara/Utility/SimpleTextDrawer.hpp b/include/Nazara/Utility/SimpleTextDrawer.hpp index 3f87bf3bb..f5532ca8f 100644 --- a/include/Nazara/Utility/SimpleTextDrawer.hpp +++ b/include/Nazara/Utility/SimpleTextDrawer.hpp @@ -28,7 +28,7 @@ namespace Nz void Clear(); - const Rectui& GetBounds() const override; + const Recti& GetBounds() const override; unsigned int GetCharacterSize() const; const Color& GetColor() const; Font* GetFont() const; @@ -71,7 +71,7 @@ namespace Nz Color m_color; FontRef m_font; mutable Rectf m_workingBounds; - mutable Rectui m_bounds; + mutable Recti m_bounds; String m_text; mutable UInt32 m_previousCharacter; UInt32 m_style; diff --git a/src/Nazara/Utility/SimpleTextDrawer.cpp b/src/Nazara/Utility/SimpleTextDrawer.cpp index cc2130c05..ae2dc8762 100644 --- a/src/Nazara/Utility/SimpleTextDrawer.cpp +++ b/src/Nazara/Utility/SimpleTextDrawer.cpp @@ -49,7 +49,7 @@ namespace Nz ClearGlyphs(); } - const Rectui& SimpleTextDrawer::GetBounds() const + const Recti& SimpleTextDrawer::GetBounds() const { if (!m_glyphUpdated) UpdateGlyphs(); From a15b31c646fc02b2ad040c1d60ea185fa1df5805 Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 13 May 2016 12:47:43 +0200 Subject: [PATCH 58/60] Graphics/Material: Add Basic2D and Translucent2D materials Former-commit-id: fd07cb7c039d0e30b6fe74378efb3208808f9d9b --- src/Nazara/Graphics/Material.cpp | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/src/Nazara/Graphics/Material.cpp b/src/Nazara/Graphics/Material.cpp index c646d940b..9a95c656b 100644 --- a/src/Nazara/Graphics/Material.cpp +++ b/src/Nazara/Graphics/Material.cpp @@ -911,12 +911,29 @@ namespace Nz UberShaderLibrary::Register("PhongLighting", uberShader); } - // Une fois les shaders de base enregistrés, on peut créer le matériau par défaut - s_defaultMaterial = Material::New(); + // Once the base shaders are registered, we can now set some default materials + s_defaultMaterial = New(); s_defaultMaterial->Enable(RendererParameter_FaceCulling, false); s_defaultMaterial->SetFaceFilling(FaceFilling_Line); MaterialLibrary::Register("Default", s_defaultMaterial); + MaterialRef mat; + + mat = New(); + mat->Enable(RendererParameter_DepthWrite, false); + mat->Enable(RendererParameter_FaceCulling, false); + mat->EnableLighting(false); + MaterialLibrary::Register("Basic2D", std::move(mat)); + + mat = New(); + mat->Enable(RendererParameter_Blend, true); + mat->Enable(RendererParameter_DepthWrite, false); + mat->Enable(RendererParameter_FaceCulling, false); + mat->EnableLighting(false); + mat->SetDstBlend(BlendFunc_InvSrcAlpha); + mat->SetSrcBlend(BlendFunc_SrcAlpha); + MaterialLibrary::Register("Translucent2D", std::move(mat)); + return true; } From 206c0a9adc9a4926cd3195b0f475428c9c7442c1 Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 13 May 2016 12:47:53 +0200 Subject: [PATCH 59/60] Core/Color: Add IsOpaque method Former-commit-id: b730460b9d81adbcee983648145cbc7a97301329 --- include/Nazara/Core/Color.hpp | 2 ++ include/Nazara/Core/Color.inl | 9 +++++++++ 2 files changed, 11 insertions(+) diff --git a/include/Nazara/Core/Color.hpp b/include/Nazara/Core/Color.hpp index 91a8cc43d..5fef4f854 100644 --- a/include/Nazara/Core/Color.hpp +++ b/include/Nazara/Core/Color.hpp @@ -25,6 +25,8 @@ namespace Nz inline Color(const Color& color) = default; inline ~Color() = default; + inline bool IsOpaque() const; + inline String ToString() const; inline Color operator+(const Color& angles) const; diff --git a/include/Nazara/Core/Color.inl b/include/Nazara/Core/Color.inl index 4ac3a2246..5d71393df 100644 --- a/include/Nazara/Core/Color.inl +++ b/include/Nazara/Core/Color.inl @@ -72,6 +72,15 @@ namespace Nz { } + /*! + * \brief Return true is the color has no degree of transparency + * \return true if the color has an alpha value of 255 + */ + inline bool Color::IsOpaque() const + { + return a == 255; + } + /*! * \brief Converts this to string * \return String representation of the object "Color(r, g, b[, a])" From 62746921089c2f883e8053a1a5b64dfd54b16673 Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 13 May 2016 13:02:42 +0200 Subject: [PATCH 60/60] Sdk/CameraComponent: Clean include Former-commit-id: 3ff8192a4ae46441c7f3d5554c532f6a0bcc07da --- SDK/include/NDK/Components/CameraComponent.inl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SDK/include/NDK/Components/CameraComponent.inl b/SDK/include/NDK/Components/CameraComponent.inl index 7ff31d623..d3bb9177e 100644 --- a/SDK/include/NDK/Components/CameraComponent.inl +++ b/SDK/include/NDK/Components/CameraComponent.inl @@ -2,9 +2,9 @@ // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp +#include #include #include -#include "CameraComponent.hpp" namespace Ndk {